Skip to content

Latest commit

 

History

History
138 lines (99 loc) · 4.77 KB

File metadata and controls

138 lines (99 loc) · 4.77 KB

MarkEdit-api

Type definitions for the latest MarkEdit API.

References

Usage

The general workflow for creating a MarkEdit script involves leveraging CodeMirror extensions or Lezer parsers to modify the app's behavior.

Add markedit-api to your (TypeScript) project's devDependencies:

{
  "devDependencies": {
    "markedit-api": "https://github.com/MarkEdit-app/MarkEdit-api#v0.21.0"
  }
}

Import type declarations with:

import { MarkEdit } from 'markedit-api';

Refer to the index.d.ts file for all available interfaces and type definitions.

Also, you can import and use CodeMirror and Lezer dependencies like this:

import { keymap } from '@codemirror/view';
import { Prec } from '@codemirror/state';
import { Tag } from '@lezer/highlight';
import { MarkdownConfig } from '@lezer/markdown';

Build CodeMirror extension with these dependencies, and add it to MarkEdit with:

MarkEdit.addExtension(extension); // Can also add an array of extensions

Build MarkdownConfig with these dependencies, and add it to MarkEdit with:

MarkEdit.addMarkdownConfig(config);

MarkEdit supports syntax highlighting for code blocks, you can also build your own Language Package, and add it to MarkEdit with:

MarkEdit.addCodeLanguage(language);

While extensions and configs can theoretically be added at any time, it is recommended that they be added immediately after loading the script.

Handling User Input

While you can certainly build user interfaces with JavaScript and CSS, leveraging native UI components might be a better option.

To create UI entries for your features, use addMainMenuItem, which adds an item to the "Extensions" submenu of the main menu, with keyboard shortcuts support.

To request user input, try using showContextMenu, showAlert, and showTextBox.

Building

In your build configuration, mark used MarkEdit and CodeMirror dependencies as external.

Here is an example of vite config:

import { defineConfig } from 'vite';

export default defineConfig({
  build: {
    rollupOptions: {
      external: [
        'markedit-api',
        '@codemirror/view',
        '@codemirror/state',
        // ...
      ],
    },
    lib: {
      entry: 'main.ts',
      formats: ['cjs'], // CommonJS
    },
  },
});

Note: If you're using packages that are not supported in MarkEdit, such as leveraging @codemirror/lang-vue to add syntax highlighting for Vue, they should not be marked as external.

It is recommended to build as cjs, building as umd should work too. If you build it as an iife, make sure to replace imports as globals like this:

rollupOptions: {
  external: [
    'markedit-api',
    '@codemirror/view',
    '@codemirror/state',
  ],
  output: {
    globals: {
      'markedit-api': 'MarkEdit',
      '@codemirror/view': 'MarkEdit.codemirror.view',
      '@codemirror/state': 'MarkEdit.codemirror.state',
    },
  },
},

The reason is to ensure that user scripts and MarkEdit use the same modules, rather than being separately bundled from different projects.

The final step is to copy the built script to ~/Library/Containers/app.cyan.markedit/Data/Documents/scripts/, and restart the app.

Ensure the build system produces a single JavaScript file. If the build generates multiple chunks, you can use vite-plugin-singlefile to bundle everything into one file.

Tip

You can also use MarkEdit-vite to simplify the workflow.

Using JavaScript

You can directly access CodeMirror and MarkEdit interfaces through objects assigned to the MarkEdit object. For example:

const keymap = MarkEdit.codemirror.view.keymap;
const editorAPI = MarkEdit.editorAPI;

This is useful when you simply want to prototype something quickly.