Skip to content

MarkEdit-app/MarkEdit-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.5.0"
  }
}

Import types declarations with:

import { MarkEdit } from 'markedit-api';

The MarkEdit object provides these interfaces:

interface MarkEdit {
  // CodeMirror EditorView instance of the current editor.
  editorView: EditorView;
  // Convenient text editing interfaces.
  editorAPI: TextEditable;
  // CodeMirror modules used by MarkEdit.
  codemirror: { view, state, language, commands, search };
  // Lezer modules used by MarkEdit.
  lezer: { common, highlight, markdown, lr };
  // Get notified when the editor is initialized.
  onEditorReady: (listener: (editorView: EditorView) => void) => void;
  // Add an extension to MarkEdit.
  addExtension: (extension: Extension) => void;
  // Add a Markdown config to MarkEdit.
  addMarkdownConfig: (config: MarkdownConfig) => void;
  // Add a language to be highlighted (in code blocks) to MarkEdit.
  addCodeLanguage: (language: LanguageDescription) => void;
}

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.

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.

Using JavaScript

If you just want to quickly prototype with 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;

For complete examples, refer to Example: Markdown Table Editor, Example: Text Highlight and Example: Vue Language Package.