Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use the Markdown editor based on Ace

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the knowledge of "how to use the Markdown editor based on Ace". Many people will encounter this dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

I think editors are divided into two categories, one is to achieve real-time rendering on the left and right sides, and the other is to write syntax first and then render through buttons.

In fact, real-time rendering is not difficult, and the common problem to consider is xss. Because the rendering library can customize the third-party xss filtering (previously implemented through settings, that is, it comes with its own, but was cancelled after a certain version), xss uses the officially recommended dompurify. Real-time rendering can be achieved through the editor's own api to listen for text changes, and another problem to consider is the correspondence between the code and the rendering area. But because this is contrary to my needs, I will not introduce it here. I believe that small bosses can easily achieve it.

Unified convention, let's take a look at the effect picture.

The above toolbar is just to add events and insert the corresponding statements into the cursor. Emoji has not been implemented for the time being and seems to need the support of a third-party library.

On the whole, there is no difficulty, but for these things, either the documents are scattered and unclear, or no documents can be found. If there are really no documents, or official crude documents, you may really want to greet him, ha. At this time, a working code is particularly important, although it may not have any comments, but I am sure you can understand the meaning of it. Don't say much, put on the code ~

Edit Preview Title 1 (Ctrl+Alt+1) title 2 (Ctrl+Alt+2) title 3 (Ctrl+Alt+3) Text (Ctrl+Alt+P) code (Ctrl+Alt+C) Markdown Guide

This site is powered by Markdown. For full documentation, click here

Import ace from 'ace-builds'// must import import' ace-builds/webpack-resolver';import marked from 'marked'import highlight from "highlight.js"; import "highlight.js/styles/foundation.css"; import katex from' katex'import 'katex/dist/katex.css'import DOMPurify from' dompurify';const renderer = new marked.Renderer (); function toHtml (text) {let temp = document.createElement ("div"); temp [XSS _ clean] = text Let output = temp.innerText | | temp.textContent; temp = null; return output;} function maths_Expression (expr) {if (expr.match (/ ^\ $\ $[\ s\ S] *\ $\ $/)) {expr = expr.substr (2, expr.length-4); return katex.renderToString (expr, {displayMode: true});} else if (expr.match (/ ^\ $[\ s\ S] *\ $/)) {expr = toHtml (expr) / / temp solution expr = expr.substr (1, expr.length-2); / / Does that mean your text is getting dynamically added to the page? If so, someone must be calling KaTeX to render / / it, and that call needs to have the strict flag set to false as well. That is, console warning, such as% is escaped or / / link: https://katex.org/docs/options.html return katex.renderToString (expr, {displayMode: false, strict: false});}} const unchanged = new marked.Renderer () renderer.code = function (code, language, escaped) {console.log (language) Const isMarkup = ['caged girls,' cpp', 'golang',' java', 'js',' javascript', 'python']. Language; let hled =''; if (isMarkup) {const math = maths_Expression (code); if (math) {return math;} else {console.log ("highlight"); hled = highlight.highlight (language, code). Value }} else {console.log ("highlightAuto"); hled = highlight.highlightAuto (code) .value;} return `$ {hled} `; / / return unchanged.code (code, language, escaped);}; renderer.codespan = function (text) {const math = maths_Expression (text); if (math) {return math;} return unchanged.codespan (text);} Export default {name: "abc", props: {value: {type: String, required: true}}, data () {return {tableData: [{code:': emoji_name:', or:'-', devices:'-', device:'-', showOff:'?'} {code:'* Italic*', or:'_ Italic_', devices: 'Ctrl+I', device:' Command+I', showOff: 'Italic'}, {code:' * * Bold**', or:'_ _ Bold__', devices: 'Ctrl+B', device:' Command+B', showOff: 'Bold'} {code:'+ + Underscores++', or:'-', devices: 'Shift+U', device:' Option+U', showOff: 'Underscores'}, {code:' ~ Strikethrough~~', or:'-', devices: 'Shift+S', device:' Option+S', showOff: 'Strikethrough'} {code:'# Heading 1, or: 'Heading 1

=', devices: 'Ctrl+Alt+1', device:' Command+Option+1', showOff: 'Heading 1'}, {code:' # # Heading 2, or: 'Heading 2

-', devices: 'Ctrl+Alt+2', device:' Command+Option+2', showOff: 'Heading 1'}, {code:' [Link] (https://a.com)', or:'[Link] [1]

Cymbal

[1]: https://b.org', devices: 'Ctrl+L', device:' Command+L', showOff: 'Link'}, {code:'! [Image] (http://url/a.png)', or:'! [Image] [1]

Cymbal

[1]: http://url/b.jpg', devices: 'Ctrl+Shift+I', device:' Command+Option+I', showOff:

Markdown

'}, {code:' > Blockquote', or:'-', devices: 'Ctrl+Q', device:' Command+Q', showOff:

Blockquote

'}, {code:' a paragraph.

A paragraph after 1 blank line.', or:'-, devices:'-', device:'-', showOff:'

A paragraph.

A paragraph after 1 blank line.

'}, {code:'

* List

* List

* List

, or:'

-List

-List

-List

', devices:' Ctrl+U', device: 'Command+U', showOff:' ListListList'}, {code:'

1. One

2. Two

3. Three

, or:'

1) One

2) Two

3) Three

', devices:' Ctrl+Shift+O', device: 'Command+Option+O', showOff:' OneTwoThree'}, {code: 'Horizontal Rule

-', or: 'Horizontal Rule

*', devices: 'Ctrl+H', device:' Command+H', showOff: 'Horizontal Rule'}, {code:' `Inline code` with backticks', or:'-', devices: 'Ctrl+Alt+C', device:' Command+Option+C', showOff: 'Inline codewith backticks'}, {code:' ```

Def whatever (foo):

Return foo

````, or: 'with tab / 4 spaces

.. def whatever (foo):

.. return foo', devices: 'Ctrl+Alt+P', device:' Command+Option+P', showOff: 'def' +' whatever (foo):\ n'+ 'return foo'}], dialogHelpVisible: false, isTextActive:', isCodeActive:', isHeader1Active:', isHeader2Active:', isHeader3Active:'' IsShowPreview: false, isEditActive: "active", isPreviewActive: "", aceEditor: null, themePath: 'ace/theme/crimson_editor', / / do not import webpack-resolver The module path will report an error modePath: 'ace/mode/markdown', / / ditto codeValue: this.value | |',} }, methods: {insertBoldCode () {this.aceEditor.insert ("*"); let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column-2);}, insertItalicCode () {this.aceEditor.insert ("_"); let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column-1) }, insertMinusCode () {let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.insert ("\ n\ n"); this.aceEditor.insert ("-"); this.aceEditor.insert ("\ n\ n"); this.aceEditor.gotoLine (cursorPosition.row + 5, cursorPosition.column,true);}, insertHeader1Code () {this.isHeader2Active = this.isHeader3Active ='' This.isHeader1Active = 'active'; this.aceEditor.insert ("\ n\ n"); this.aceEditor.insert ("#");}, insertHeader2Code () {this.isHeader1Active = this.isHeader3Active =''; this.isHeader2Active = 'active'; this.aceEditor.insert ("\ n\ n"); this.aceEditor.insert ("# #") }, insertHeader3Code () {this.isHeader1Active = this.isHeader2Active =''; this.isHeader3Active = 'active'; this.aceEditor.insert ("\ n\ n"); this.aceEditor.insert ("#");}, insertText () {let cursorPosition = this.aceEditor.getCursorPosition (); this.isCodeActive =''; this.isTextActive = 'active' This.aceEditor.insert ("```\ n\ n```"); this.aceEditor.gotoLine (cursorPosition.row + 2, cursorPosition.column,true);}, insertCode () {let cursorPosition = this.aceEditor.getCursorPosition (); this.isTextActive =''; this.isCodeActive = 'active'; this.aceEditor.insert ("``"); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column + 1) }, insertQuoteCode () {this.aceEditor.insert ("\ n >"); let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column + 1);}, insertUlCode () {this.aceEditor.insert ("\ n *"); let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column + 1) }, insertOlCode () {this.aceEditor.insert ("\ N1."); let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column + 1);}, insertLinkCode () {this.aceEditor.insert ("[] ()"); let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column-3) }, insertImgCode () {this.aceEditor.insert ("! [] ()); let cursorPosition = this.aceEditor.getCursorPosition (); this.aceEditor.moveCursorTo (cursorPosition.row, cursorPosition.column-3);}, uploadImg () {this.aceEditor.insert ("! [] () ");}, selectEmoji () {this.aceEditor.insert (" * ") }, toggleMaximize () {this.aceEditor.insert ("*");}, toggleHelp () {this.dialogHelpVisible =! this.dialogHelpVisible;}, showEdit () {this.$ refs.previews [XSS _ clean] =''; this.isEditActive = 'active'; this.isPreviewActive ='; this.isShowPreview = false;}, showPreview () {this.show () This.isEditActive =''; this.isPreviewActive = 'active'; this.isShowPreview = true;}, show (data) {let value = this.aceEditor.session.getValue (); this.$ refs.Preview [XSS _ clean] = DOMPurify.sanitize (marked (value)); console.log (DOMPurify.sanitize (marked (value) },}, mounted () {this.aceEditor = ace.edit (this.$refs.markdown, {selectionStyle: 'line', / / selected style maxLines: 1000, / / maximum number of rows, scroll bar minLines: 22, / / minimum number of rows will automatically appear when the maximum number of lines is not reached The editor will automatically scale the font size within the editor fontSize: 14, / / theme: this.themePath, / / default theme mode: this.modePath, / / default language mode tabSize: 4, / / Tab set to four space sizes readOnly: false, / / read-only wrap: true, highlightActiveLine: true Value: this.codeValue}) Marked.setOptions ({renderer: renderer, / / highlight: function (code) {/ / return highlight.highlightAuto (code) .value; / /}, gfm: true,// defaults to true. Allow Git Hub standard markdown. Tables: true,// defaults to true. Table syntax is allowed. This option requires gfm to be true. Breaks: false,// defaults to false. Enter is allowed to change lines. This option requires gfm to be true. Pedantic: false,// defaults to false. Be compatible with the obscure parts of markdown.pl as much as possible. Do not correct any bad behavior and errors in the original model. / / sanitize: false,// does not support filtering (cleaning) the output. Filter xhtml with sanitizer or direct rendering: true, / / If true, emit self-closing HTML tags for void elements (

, etc.) With a "/" as required by XHTML. Silent: true, / / If true, the parser does not throw any exception. SmartLists: true, smartypants: false// uses more stylish punctuation, such as adding dashes to the reference syntax. }); / / this.aceEditor.session.on ('change', this.show); / / let that = this; / / this.aceEditor.commands.addCommand ({/ / name:' copy', / / bindKey: {win: 'Ctrl-C', mac:' Command-M'}, / / exec: function (editor) {/ / that.$message.success ("copy successfully") / / this.aceEditor.commands.addCommand ({/ / name: 'paste', / / bindKey: {win: 'Ctrl-V', mac:' Command-M'}, / / exec: function (editor) {/ / that.$message.success (paste successfully); / /} / /}) }, watch: {value (newVal) {console.log (newVal); this.aceEditor.setValue (newVal);}. Toolbar {cursor: pointer;// mouse hand}. Show-panel {padding: 5px; border: 1px solid lightgray; .ace {position: relative! important; border-top: 1px solid lightgray; display: block; margin: auto; height: auto; width: 100% Panel-preview {padding: 1remt; margin: 0000; width: auto; background-color: white;}} .editor-tab-content, .header1-tab-content, .header1-btn, .header2-btn, .header3-btn, .text-btn, .code-btn {border-bottom-color: transparent; border-bottom-style: solid; border-radius: 0; padding: .85714286em 1.14285714em 1.29999714em 1.14285714em Border-bottom-width: 2px; transition: color .1s ease; cursor: pointer;// mouse hand}. Header1-btn, .header2-btn, .header3-btn, .code-btn, .text-btn {font-size: 5px; padding: .78571429em 1.14285714 emissary importance;} .active {background-color: transparent; box-shadow: none; border-color: # 1B1C1D; font-weight: 700; color: rgba }. Header1-btn:hover, .header2-btn:hover, .header3-btn:hover, .text-btn:hover, .code-btn:hover {cursor: pointer;// mouse hand background: rgba! important; color: rgba! important;}. HelpHeader {font-size: 1.228571remm; line-height: 1.2857emm; font-weight: 700; border-top-left-radius: .28571429rem Border-top-right-radius: .28571429rem; display: block; font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; background: # FFF; box-shadow: none; color: rgba

This time the code also needs to bind value when referencing, that is, the contents of the edit box.

Oh, by the way, I forgot to say something. Issues with code block highlighting and latex rendering.

Highlight is that highlight.js,marked supports this library, just use it directly, it can automatically recognize the language, if you do not want to call that function, you can also determine the language that the user will use. To use a topic, you need to refer to the css corresponding to the style under the package. And the most important thing is that the rendering tag must have the property that class is hljs, otherwise you can only see that the code is highlighted. As for how to add the class attribute, if you don't have a letax requirement, you just need to set a layer of tags at render time, and its class attribute is this.

The rest is latex, because marked itself does not support latex, but it supports rewriting the render function, through this method to achieve latex support, here I use katex, interested small bosses can try mathjax. However, one bad thing is that the mathematical formula needs to be wrapped in a code block, that is, $a * b $. However, this is not a big problem, can be a good rendering is the king.

That's all for "how to use the Ace-based Markdown Editor". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report