ngx-markdown-editor

repository·master·Indexed 41 days ago

https://github.com/instance-oom/ngx-markdown-editor

An Angular markdown editor component based on the Ace editor. It features a live preview panel, toolbar customization, and support for custom file uploads and rendering. Version 5.3.3 implements ControlValueAccessor and Validator for compatibility with Angular Reactive and Template-driven Forms. It provides hooks for pre-rendering raw markdown and post-rendering generated HTML, as well as custom rendering for images, code, tables, and list items.

Tokens
4.9K
Snippets
16
Records
24
Agent score
52%

What's inside ngx-markdown-editor

  1. Install ngx-markdown-editor

    master

    To use ngx-markdown-editor in your Angular project, follow these installation steps:

    1. Install dependencies:

      npm i ace-builds bootstrap font-awesome
      npm i ngx-markdown-editor
    2. Configure angular.json: Add the Ace builds assets, required styles, and scripts to your build options.

    3. Add Ace to index.html: Include the ace.js script in your <head> tag.

    Note: If you are using version <= 2.5.0, you must install brace instead of ace-builds and import brace and its markdown mode in polyfills.ts.

    npm i ace-builds bootstrap font-awesome
    npm i ngx-markdown-editor
  2. Configure angular.json for ngx-markdown-editor

    master

    You must update your angular.json to include the necessary assets, styles, and scripts for the editor and its dependencies (Ace, Bootstrap, Font-Awesome, and Marked/Highlight.js).

    {
      "architect": {
        "build": {
          "options": {
            "assets": [
              {
                "glob": "**/*",
                "input": "node_modules/ace-builds/src-min",
                "output": "./assets/ace-builds/"
              }
            ],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "node_modules/font-awesome/css/font-awesome.min.css",
              "node_modules/ngx-markdown-editor/assets/highlight.js/agate.min.css"
            ],
            "scripts": [
              "node_modules/ngx-markdown-editor/assets/highlight.js/highlight.min.js",
              "node_modules/ngx-markdown-editor/assets/marked.min.js"
            ]
          }
        }
      }
    }
  3. Configure md-editor options

    master

    The [options] input accepts an object to customize the editor's behavior and appearance.

    Key options include:

    • showPreviewPanel: (boolean) Show/hide preview panel. Default: true.
    • showBorder: (boolean) Show editor component's border. Default: true.
    • hideIcons: (Array<string>) List of icon names to hide (e.g., 'Bold', 'Italic', 'TogglePreview').
    • fontAwesomeVersion: '4' | '5' | '6'. Default: '4'.
    • resizable: (boolean) Allow user to resize the editor.
    • placeholder: (string) Placeholder text.
    • customRender: Object containing functions for image, table, code, or listitem to customize how marked.js renders specific elements.
    • customIcons: Object to override default FontAwesome icons.
  4. Install ngx-markdown-editor via Angular CLI (ng add)

    master

    You can automatically set up ngx-markdown-editor in your Angular project using the ng add command. This schematic performs two main tasks:

    1. Dependency Installation: It adds ace-builds, bootstrap, and font-awesome to your package.json dependencies.
    2. Angular Configuration: It updates angular.json to register necessary assets, styles, and scripts required for the editor to function (including Ace builds, Bootstrap, Font Awesome, and the editor's internal highlight/marked assets).

    Options

    When running the command, you can use the following flags to skip certain automation steps:

    • --skip-deps: Skips installing the required dependency packages (ace-builds, bootstrap, and font-awesome).
    • --skip-import: Skips the automatic registration of assets, styles, and scripts in angular.json.
    • --project <name>: Specifies the name of the project within your workspace to apply the configuration to.
    ng add ngx-markdown-editor
    
    # Example with options
    ng add ngx-markdown-editor --skip-deps --skip-import --project my-app
  5. Use MarkdownEditorComponent in Angular templates

    master

    The MarkdownEditorComponent (selector: md-editor) is an Angular component that provides a full-featured Markdown editor with Ace Editor integration and a live preview panel. It implements ControlValueAccessor and Validator, making it compatible with Angular Reactive Forms and Template-driven Forms.

    Key Features

    • Ace Editor Integration: High-performance text editing with syntax highlighting.
    • Live Preview: Real-time HTML rendering of Markdown content.
    • Form Integration: Supports ngModel, formControlName, and built-in validation (required, maxlength).
    • File Uploads: Supports drag-and-drop or paste-to-upload functionality via a custom upload function.
    • Custom Rendering: Allows overriding how specific Markdown elements (images, code, tables, list items) are rendered.
    <md-editor
      [(ngModel)]="myMarkdown"
      [options]="editorOptions"
      [height]="'500px'"
      (onEditorLoaded)="handleEditorLoaded($event)">
    </md-editor>
  6. Implement file uploads in MarkdownEditorComponent

    master

    To enable drag-and-drop or paste-to-upload functionality, provide an upload function via the [upload] input. This function is called with a FileList and must return a Promise that resolves to an array of UploadResult objects.

    Expected Return Format

    Each object in the returned array should follow this structure:

    • name: (string) The filename.
    • url: (string) The URL of the uploaded file.
    • isImg: (boolean) Whether the file is an image (if true, the editor will automatically prepend ! to the markdown link).

    Example Implementation

    // In your component class
    async myUploadFunction(files: FileList): Promise<any[]> {
      // 1. Upload files to your server
      // 2. Return the results
      return [
        { name: 'image.png', url: 'https://cdn.com/image.png', isImg: true },
        { name: 'doc.pdf', url: 'https://cdn.com/doc.pdf', isImg: false }
      ];
    }

    In the template:

    <md-editor [upload]="myUploadFunction"></md-editor>
  7. Use the md-editor component

    master

    To use the editor, import LMarkdownEditorModule and FormsModule in your Angular module. You can then use the <md-editor> component in your templates.

    Important: When passing functions to inputs like [upload], [preRender], or [postRender], you must bind them in your component's constructor to ensure the correct this context.

    import { LMarkdownEditorModule } from 'ngx-markdown-editor';
    import { FormsModule } from '@angular/forms';
    
    @NgModule({
      imports: [
        BrowserModule,
        FormsModule,
        LMarkdownEditorModule
      ],
      // ...
    })
    export class AppModule { }
    <md-editor 
      name="Content" 
      [(ngModel)]="content" 
      [height]="'200px'" 
      [mode]="mode" 
      [options]="options"
      (onEditorLoaded)="onEditorLoaded($event)">
    </md-editor>
  8. Customize rendering with preRender and postRender

    master

    You can intercept the markdown content during the rendering lifecycle:

    • [preRender]: A function that modifies the raw markdown content before it is processed by the parser. This does not affect the ngModel value. It must return a string.
    • [postRender]: A function that modifies the HTML source code generated by marked before it is updated in the DOM. It must return a string.
    // preRender: modifies raw markdown
    preRenderFunc(content: string) {
      return content.replace(/something/g, 'new value');
    }
    
    // postRender: modifies generated HTML
    postRenderFunc(content: string) {
      return content.replace(/<p>something<\/p>/g, '<b>something</b>');
    }
  9. Implement custom file upload with upload()

    master

    The [upload] input allows you to handle file uploads (e.g., images) manually. You must provide a function that returns a Promise<Array<UploadResult>>.

    Note: You must bind the upload function in your constructor.

    interface UploadResult {
      isImg: boolean
      name: string
      url: string
    }
    
    // In your component
    constructor() {
      this.doUpload = this.doUpload.bind(this);
    }
    
    doUpload(files: Array<File>): Promise<Array<UploadResult>> {
      // Implement your upload logic here
      return Promise.resolve([{ name: 'xxx', url: 'xxx.png', isImg: true }]);
    }
  10. Localize the editor with MdEditorLocaleOptions

    master

    To support multiple languages, provide a locales object. This object maps language codes (e.g., 'en', 'fr') to MdEditorLocale configurations.

    Each locale can define:

    • Buttons: Translations for toolbar buttons. Some buttons (like Bold or CodeBlock) use MdButtonInserterLocale which includes an optional initText field (the text inserted when the button is clicked).
    • Upload: Translations for the drag-and-drop upload interface (Drag and Uploading keys).
    const options: MdEditorOption = {
      locales: {
        es: {
          Buttons: {
            Bold: { title: 'Negrita', initText: 'Texto en negrita' },
            Link: { title: 'Enlace' }
          },
          Upload: {
            Drag: 'Arrastra aquí',
            Uploading: 'Subiendo...'
          }
        }
      }
    };