Ich denke, Editoren lassen sich in zwei Kategorien unterteilen: Eine ist in eine linke und eine rechte Seite unterteilt, um ein sofortiges Rendering zu erreichen; bei der anderen wird zuerst die Syntax geschrieben und dann das Rendering über Schaltflächen erreicht. Tatsächlich ist Echtzeit-Rendering nicht schwierig. Das häufige Problem, das berücksichtigt werden muss, ist XSS. Da die Rendering-Bibliothek die XSS-Filterung von Drittanbietern anpassen kann (früher wurde dies über Einstellungen erreicht, d. h. es war damit ausgestattet, wurde jedoch nach einer bestimmten Version abgebrochen), verwendet XSS das offiziell empfohlene Dompurify. Echtzeit-Rendering kann erreicht werden, indem die eigene API des Editors verwendet wird, um Textänderungen zu überwachen. Ein weiteres zu berücksichtigendes Problem ist die Übereinstimmung zwischen dem Code und dem Rendering-Bereich. Da dies jedoch meinen Anforderungen widerspricht, werde ich es hier nicht vorstellen. Ich glaube, dass kleine Chefs dies problemlos erreichen können. Einheitliche Konvention, schauen wir uns das Effektdiagramm an Die Symbolleiste oben fügt tatsächlich Ereignisse hinzu und fügt entsprechende Anweisungen in den Cursor ein. Emoji ist noch nicht implementiert und scheint Unterstützung durch eine Drittanbieterbibliothek zu benötigen. Insgesamt gibt es keine Schwierigkeiten, aber für diese Dinge ist die Dokumentation entweder verstreut und unklar, oder es ist keine Dokumentation zu finden. Wenn wirklich keine Dokumentation vorhanden ist oder die offizielle Dokumentation sehr einfach ist, möchten Sie ihm vielleicht wirklich Hallo sagen, hahahaha. Zu diesem Zeitpunkt ist ein verwendbarer Code besonders wichtig. Obwohl er möglicherweise nicht viele Kommentare enthält, bin ich davon überzeugt, dass Sie klug genug sind, um seine Bedeutung zu verstehen. Kommen wir ohne weitere Umschweife zum Code~ <Vorlage> <div> <div Klasse="Abschnitt-Ace"> <el-Zeile> <el-col :span="6"> <el-Zeile> <el-col :span="12"> <a class="editor-tab-content" :class="isEditActive" @click="showEdit"> <i class="fa fa-pencil-square-o" aria-hidden="true"></i> Bearbeiten </el-col> <el-col :span="12"> <a class="Vorschau-Tab-Inhalt" :class="isPreviewActive" @click="showPreview"> <i class="fa fa-eye" aria-hidden="true"></i> Vorschau </el-col> </el-row> </el-col> <el-col :push="8" :span="18"> <el-Zeile> <div Klasse="Werkzeugleiste"> <el-col :span="1"> <div> <i @click="insertBoldCode" class="fa fa-bold" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <i @click="insertItalicCode" class="fa fa-italic" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <i @click="insertMinusCode" class="fa fa-minus" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <el-popover Platzierung="unten" Breite="125" Übergang = "lineares Einblenden" Auslöser="Klick" Inhalt=""> <i slot="Referenz" class="fa fa-header" aria-hidden="true"></i> <div> <div Klasse="header1-btn" :Klasse="isHeader1Active" @click="insertHeader1Code"> Überschrift 1 (Strg+Alt+1) </div> <div Klasse="header2-btn" :Klasse="isHeader2Active" @click="insertHeader2Code"> Überschrift 2 (Strg+Alt+2) </div> <div Klasse="header3-btn" :Klasse="isHeader3Active" @click="insertHeader3Code"> Überschrift 3 (Strg+Alt+3) </div> </div> </el-popover> </el-col> <el-col :span="1"> <el-popover Platzierung="unten" Breite="125" Übergang = "lineares Einblenden" Auslöser="Klick" Inhalt=""> <i slot="Referenz" class="fa fa-code" aria-hidden="true"></i> <div> <div Klasse="text-btn" :Klasse="isTextActive" @click="insertText"> Text (Strg+Alt+P) </div> <div Klasse = "code-btn" :Klasse = "isCodeActive" @click = "insertCode"> Code (Strg+Alt+C) </div> </div> </el-popover> </el-col> <el-col :span="1"> <div> <i @click="insertQuoteCode" class="fa fa-quote-left" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <i @click="insertUlCode" class="fa fa-list-ul" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <i @click="insertOlCode" class="fa fa-list-ol" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <i @click="insertLinkCode" class="fa fa-link" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <i @click="insertImgCode" class="fa fa-picture-o" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <el-hochladen Klasse="Upload-Demo" Aktion="https://jsonplaceholder.typicode.com/posts/" :Grenze="1"> <i class="fa fa-cloud-upload" aria-hidden="true"></i> </el-upload> </div> </el-col> <el-col :span="1"> <div> <i @click="selectEmoji" class="fa fa-smile-o" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <div> <i @click="toggleMaximize" class="fa fa-arrows-alt" aria-hidden="true"></i> </div> </el-col> <el-col :span="1"> <i @click="toggleHelp" class="fa fa-question-circle" aria-hidden="true"></i> <el-dialog :visible.sync="dialogHilfeSichtbar" :anzeigen-schließen="false" oben="5vh" Breite="60%" :an den Hauptteil anhängen="true" :schließen-beim-Pressen-Escape="true"> <el-card Klasse="Box-Card" Stil="Rand: -60px -20px -30px -20px"> <div slot="header" class="helpHeader"> <i class="fa fa-question-circle" aria-hidden="true"><span>Markdown-Leitfaden</span></i> </div> <p>Diese Website wird von Markdown betrieben. Die vollständige Dokumentation finden Sie unter <a href="http://commonmark.org/help/" rel="external nofollow" target="_blank">hier klicken</a> </p> <el-Tabelle :data="Tabellendaten" Streifen Grenze :aktuelle Zeile hervorheben="true" Stil="Breite: 100%"> <el-table-column prop="Code" Bezeichnung="Code" Breite="150"> <template slot-scope="Umfang"> <p v-html='Umfang.Zeilencode'></p> </Vorlage> </el-Tabellenspalte> <el-table-column prop="oder" label="Oder" Breite="180"> <template slot-scope="Umfang"> <p v-html='scope.row.oder'></p> </Vorlage> </el-Tabellenspalte> <el-table-column prop="Geräte" label="Linux/Windows"> </el-Tabellenspalte> <el-table-column prop="Gerät" Bezeichnung="Mac OS" Breite="180"> </el-Tabellenspalte> <el-table-column prop="angeben" label="... zum Abrufen" Breite="200"> <template slot-scope="Umfang"> <p v-html='scope.row.showOff'></p> </Vorlage> </el-Tabellenspalte> </el-Tabelle> </el-Karte> </el-dialog> </el-col> </div> </el-row> </el-col> </el-row> </div> <br> <div id="Behälter"> <div Klasse="Anzeigenpanel"> <div ref="markdown" class="ace" v-show="!isShowPreview"></div> <div class="panel-preview" ref="Vorschau" v-show="isShowPreview"></div> </div> </div> </div> </Vorlage> <Skript> importiere Ace aus „Ace-Builds“ // Um es in einer Webpack-Umgebung zu verwenden, müssen Sie import 'ace-builds/webpack-resolver'; importieren. Markierte importieren von 'markiert' Hervorhebung aus „highlight.js“ importieren; importiere "highlight.js/styles/foundation.css"; Katex von „Katex“ importieren importiere 'katex/dist/katex.css' importiere DOMPurify von „dompurify“; const renderer = neuer markierter.Renderer(); Funktion toHtml(Text){ let temp = document.createElement("div"); temp.innerHTML = Text; let Ausgabe = temp.innerText || temp.textContent; temp = null; Ausgabe zurückgeben; } Funktion mathematischerAusdruck(Ausdruck) { wenn (Ausdruck.Übereinstimmung(/^\$\$[\s\S]*\$\$$/)) { Ausdruck = Ausdruck.substr(2, Ausdruck.Länge - 4); return katex.renderToString(expr, { displayMode: true }); } sonst wenn (Ausdruck.Match(/^\$[\s\S]*\$$/)) { expr = toHtml(expr); // temporäre Lösung Ausdruck = Ausdruck.substr(1, Ausdruck.Länge - 2); //Heißt das, dass Ihr Text dynamisch zur Seite hinzugefügt wird? Wenn ja, muss jemand KaTeX aufrufen, um // es, und dieser Aufruf muss auch das Flag „strict“ auf „false“ gesetzt haben. Das heißt, Konsolenwarnungen wie „% wird maskiert“ oder „Chinesisch“ // Link: https://katex.org/docs/options.html return katex.renderToString(expr, { displayMode: false , strict: false}); } } const unverändert = neu markiert.Renderer() renderer.code = Funktion(Code, Sprache, maskiert) { console.log(Sprache); const isMarkup = ['c++', 'cpp', 'golang', 'java', 'js', 'javascript', 'python'].includes(Sprache); lass hled = ''; wenn (istMarkup) { const math = mathsExpression(code); wenn (Mathe) { Mathematik zurückgeben; } anders { console.log("hervorheben"); hled = Highlight.Highlight(Sprache, Code).Wert; } } anders { console.log("highlightAuto"); hled = Hervorhebung.HighlightAuto(Code).Wert; } return `<pre class="hljs ${language}"><code class="${language}">${hled}</code></pre>`; // unverändert zurückgeben. Code (Code, Sprache, entkommen); }; renderer.codespan = Funktion(Text) { const math = mathsExpression(text); wenn (Mathe) { Mathematik zurückgeben; } returniere unverändert.codespan(text); }; Standard exportieren { Name: "abc", Requisiten: { Wert: { Typ: Zeichenfolge, erforderlich: true } }, Daten() { zurückkehren { Tabellendaten: [{ Code: ':emoji_name:', oder: '-', Geräte: '-', Gerät: '-', showOff: '🧡' },{ Code: '*Kursiv*', oder: '_Kursiv_', Geräte: 'Strg+I', Gerät: 'Befehl+I', showOff: '<em>Kursiv</em>' },{ Code: '**Fett**', oder: '__Fett__', Geräte: 'Strg+B', Gerät: 'Befehl+B', showOff: '<em>Fett</em>' },{ Code: '++Unterstriche++', oder: '-', Geräte: 'Umschalt+U', Gerät: 'Option+U', showOff: '<ins>Unterstriche</ins>' },{ Code: '~~Durchgestrichen~~', oder: '-', Geräte: 'Umschalt+S', Gerät: 'Option+S', showOff: '<del>Durchgestrichen</del>' },{ Code: '#Überschrift 1', oder: 'Überschrift 1<br>=========', Geräte: 'Strg+Alt+1', Gerät: „Befehl+Wahl+1“, showOff: '<h1>Überschrift 1</h1>' },{ Code: '## Überschrift 2', oder: 'Überschrift 2<br>--------------', Geräte: 'Strg+Alt+2', Gerät: „Befehl+Wahl+2“, showOff: '<h2>Überschrift 1</h2>' },{ Code: '[Link](https://a.com)', oder: '[Link][1]<br>⁝<br>[1]: https://b.org', Geräte: 'Strg+L', Gerät: „Befehl+L“, showOff: '<a href="https://commonmark.org/" rel="external nofollow" >Link</a>' },{ Code: '', oder: '![Bild][1]<br>⁝<br>[1]: http://url/b.jpg', Geräte: 'Strg+Umschalt+I', Gerät: „Befehl+Wahl+I“, showOff: '<img src="https://cdn.acwing.com/static/plugins/images/commonmark.png" width="36" height="36" alt="Markdown">' },{ Code: '> Blockzitat', oder: '-', Geräte: 'Strg+Q', Gerät: „Befehl+Q“, showOff: '<blockquote><p>Blockzitat</p></blockquote>' },{ Code: „Ein Absatz.<br><br>Ein Absatz nach 1 Leerzeile.“ oder: '-', Geräte: '-', Gerät: '-', showOff: '<p>Ein Absatz.</p><p>Ein Absatz nach 1 Leerzeile.</p>' },{ Code: '<p>* Liste<br> * Liste<br> * Liste</p>', oder: '<p> – Liste<br> – Liste<br> – Liste<br></p>', Geräte: 'Strg+U', Gerät: „Befehl+U“, showOff: '<ul><li>Liste</li><li>Liste</li><li>Liste</li></ul>' },{ Code: '<p> 1. Eins<br> 2. Zwei<br> 3. Drei</p>', oder: '<p> 1) Eins<br> 2) Zwei<br> 3) Drei</p>', Geräte: 'Strg+Umschalt+O', Gerät: „Befehl+Wahl+O“, showOff: '<ol><li>Eins</li><li>Zwei</li><li>Drei</li></ol>' },{ Code: 'Horizontale Linie<br><br>-----------', oder: 'Horizontale Regel<br><br>***********', Geräte: 'Strg+H', Gerät: „Befehl+H“, showOff: 'Horizontale Linie<hr>' },{ Code: „Inline-Code“ mit Backticks, oder: '-', Geräte: 'Strg+Alt+C', Gerät: „Befehl+Wahl+C“, showOff: '<code>Inline-Code</code> mit Backticks' },{ Code: '```<br> def was auch immer(foo):<br> return foo<br>```', oder: '<b>mit Tab / 4 Leerzeichen</b><br>....def whatever(foo):<br>.... return foo', Geräte: 'Strg+Alt+P', Gerät: „Befehl+Wahl+P“, showOff: '<pre class="hljs"><code class=""><span class="hljs-function"><span class="hljs-keyword">def</span>' + '<span class="hljs-title">was auch immer</span><span class="hljs-params">(foo)</span></span>:\n' + ' <span class="hljs-keyword">return</span> foo</code></pre>' }], dialogHelpVisible: false, istTextActive: '', istCodeActive: '', isHeader1Active: '', isHeader2Active: '', isHeader3Active: '', isShowPreview: false, isEditActive: "aktiv", isPreviewActive: "", aceEditor: null, themePath: 'ace/theme/crimson_editor', // Wenn webpack-resolver nicht importiert wird, meldet der Modulpfad einen Fehler modePath: 'ace/mode/markdown', // Wie oben codeValue: this.value || '', }; }, Methoden: { einfügenBoldCode() { this.aceEditor.insert("****"); let cursorPosition = this.aceEditor.getCursorPosition(); this.aceEditor.moveCursorTo(cursorPosition.Zeile, cursorPosition.Spalte - 2); }, Kursivcode einfügen() { this.aceEditor.insert("__"); let cursorPosition = this.aceEditor.getCursorPosition(); this.aceEditor.moveCursorTo(cursorPosition.row, cursorPosition.column - 1); }, insertMinusCode() { let cursorPosition = this.aceEditor.getCursorPosition(); dies.aceEditor.insert("\n\n"); this.aceEditor.insert("----------"); dies.aceEditor.insert("\n\n"); this.aceEditor.gotoLine(cursorPosition.row + 5, cursorPosition.column,true); }, insertHeader1Code() { dies.isHeader2Active = dies.isHeader3Active = ''; this.isHeader1Active = "aktiv"; dies.aceEditor.insert("\n\n"); dies.aceEditor.insert("#"); }, insertHeader2Code() { dies.isHeader1Active = dies.isHeader3Active = ''; this.isHeader2Active = "aktiv"; dies.aceEditor.insert("\n\n"); dies.aceEditor.insert("##"); }, insertHeader3Code() { dies.isHeader1Active = dies.isHeader2Active = ''; this.isHeader3Active = "aktiv"; dies.aceEditor.insert("\n\n"); dies.aceEditor.insert("###"); }, Text einfügen() { let cursorPosition = this.aceEditor.getCursorPosition(); dies.isCodeActive = ''; this.isTextActive = "aktiv"; this.aceEditor.insert("```\n\n```"); this.aceEditor.gotoLine(cursorPosition.row + 2, cursorPosition.column,true); }, Code einfügen() { let cursorPosition = this.aceEditor.getCursorPosition(); dies.isTextActive = ''; this.isCodeActive = "aktiv"; dies.aceEditor.insert("``"); this.aceEditor.moveCursorTo(cursorPosition.row, cursorPosition.column + 1); }, füge QuoteCode() ein { dies.aceEditor.insert("\n>"); let cursorPosition = this.aceEditor.getCursorPosition(); this.aceEditor.moveCursorTo(cursorPosition.row, cursorPosition.column + 1); }, insertUlCode() { dies.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); }, LinkCode einfügen() { this.aceEditor.insert("[]()"); let cursorPosition = this.aceEditor.getCursorPosition(); this.aceEditor.moveCursorTo(cursorPosition.Zeile, cursorPosition.Spalte - 3); }, Bildcode einfügen() { this.aceEditor.insert("![]()"); let cursorPosition = this.aceEditor.getCursorPosition(); this.aceEditor.moveCursorTo(cursorPosition.Zeile, cursorPosition.Spalte - 3); }, uploadImg() { this.aceEditor.insert("![]()"); }, wähleEmoji() { this.aceEditor.insert("****"); }, umschaltenMaximieren() { this.aceEditor.insert("****"); }, toggleHelp() { this.dialogHelpVisible = !this.dialogHelpVisible; }, zeigeEdit() { dies.$refs.preview.innerHTML = ''; this.isEditActive = "aktiv"; this.isPreviewActive = ''; dies.isShowPreview = falsch; }, Vorschau anzeigen() { dies.zeigen(); dies.isEditActive = ''; this.isPreviewActive = "aktiv"; dies.isShowPreview = true; }, anzeigen(Daten) { lass Wert = this.aceEditor.session.getValue(); dies.$refs.preview.innerHTML = DOMPurify.sanitize(markiert(Wert)); Konsole.log(DOMPurify.sanitize(markiert(Wert))); }, }, montiert() { dies.aceEditor = ace.edit(dies.$refs.markdown,{ selectionStyle: 'line', //Ausgewählter StilmaxLines: 1000, //Maximale Zeilenanzahl, bei Überschreitung erscheint automatisch die BildlaufleisteminLines: 22, //Mindestzeilenanzahl, der Editor wird automatisch erweitert und verkleinert, wenn die maximale Zeilenanzahl nicht erreicht istfontSize: 14, //Schriftgröße im Editortheme: this.themePath, //Standarddesignmode: this.modePath, //StandardsprachmodustabSize: 4, //Tabulator ist auf 4 Leerzeichen eingestelltreadOnly: false, //Nur lesenwrap: true, highlightActiveLine: wahr, Wert: dieser.Codewert }); markiert.setOptions({ Renderer: Renderer, // Hervorhebung: Funktion (Code) { // Highlight zurückgeben.HighlightAuto(Code).Wert; // }, gfm: true, //Der Standardwert ist true. Ermöglicht Git Hub-Standard-Markdown. Tabellen: true, //Der Standardwert ist true. Aktiviert die Unterstützung für Tabellensyntax. Diese Option erfordert, dass gfm wahr ist. breaks: false, //Der Standardwert ist false. Wagenrücklauf und Zeilenvorschub zulassen. Diese Option erfordert, dass gfm wahr ist. pedantic: false, //Der Standardwert ist „false“. Versuchen Sie, so kompatibel wie möglich mit unbekannten Teilen von markdown.pl zu sein. Korrigiert keine Fehlverhalten oder Fehler des Originalmodells. // sanitize: false, // Filtern (bereinigen) Sie die Ausgabe. Wird nicht unterstützt. Verwenden Sie Sanitizer oder Filter direkt beim Rendern. xhtml: true, // Wenn wahr, geben Sie selbstschließende HTML-Tags für leere Elemente (<br/>, <img/> usw.) mit einem "/" aus, wie von XHTML gefordert. silent: true, //Wenn wahr, wirft der Parser keine Ausnahme. smartLists: wahr, smartypants: false // Verwenden Sie intelligentere Zeichensetzung, z. B. Bindestriche in Anführungszeichen. }); // this.aceEditor.session.on('ändern', this.show); // lass das = dies; // dies.aceEditor.commands.addCommand({ // Name: 'Kopie', // bindKey: {win: 'Strg-C', mac: 'Befehl-M'}, // exec: Funktion(Editor) { // that.$message.success("Kopieren erfolgreich"); // } // }); // dies.aceEditor.commands.addCommand({ // Name: 'Einfügen', // bindKey: {win: 'Strg-V', mac: 'Befehl-M'}, // exec: Funktion(Editor) { // that.$message.success("Einfügen erfolgreich"); // } // }); }, betrachten: Wert(neuerWert) { console.log(neuerWert); this.aceEditor.setValue(neuerWert); } } } </Skript> <style scoped lang="scss"> .Werkzeugleiste { Cursor: Zeiger; //Maushandform} .Anzeigenfeld { Polsterung: 5px; Rand: 1px durchgehend hellgrau; .ace { Position: relativ !wichtig; Rahmen oben: 1px durchgehend hellgrau; Anzeige: Block; Rand: automatisch; Höhe: automatisch; Breite: 100 %; } .panel-vorschau { Polsterung: 1rem; Rand: 0 0 0 0; Breite: automatisch; Hintergrundfarbe: weiß; } } .editor-tab-content, .preview-tab-content, .header1-btn, .header2-btn, .header3-btn, .text-btn, .code-btn{ Farbe des unteren Rahmens: transparent; Rahmen-unten-Stil: durchgezogen; Randradius: 0; Polsterung: .85714286em 1.14285714em 1.29999714em 1.14285714em; Breite des unteren Rahmens: 2px; Übergang: Farbe 0,1 s Leichtigkeit; Cursor: Zeiger; //Maushandform} .header1-btn, .header2-btn, .header3-btn, .code-btn, .text-btn { Schriftgröße: 5px; Polsterung: .78571429em 1.14285714em!wichtig; } .aktiv { Hintergrundfarbe: transparent; Kastenschatten: keiner; Rahmenfarbe: #1B1C1D; Schriftstärke: 700; Farbe: rgba(0,0,0,.95); } .header1-btn:hover, .header2-btn:hover, .header3-btn:hover, .text-btn:hover, .code-btn:hover { Cursor: Zeiger; //Maushandformhintergrund: rgba(0,0,0,.05)!wichtig; Farbe: rgba(0,0,0,.95)!wichtig; } .helpHeader { Schriftgröße: 1,228571rem; Zeilenhöhe: 1,2857em; Schriftstärke: 700; Rahmen oben links-Radius: .28571429rem; Rahmen oben rechts – Radius: .28571429rem; Anzeige: Block; Schriftfamilie: Lato, „Helvetica Neue“, Arial, Helvetica, serifenlos; Hintergrund: #FFF; Kastenschatten: keiner; Farbe: rgba(0,0,0,.85); } </Stil> Dieses Mal muss der Code auch den Wert beim Verweisen binden, d. h. den Inhalt im Bearbeitungsfeld <MarkdownEditor v-bind:value="''"></MarkdownEditor> Oh, übrigens, ich habe vergessen, etwas zu erwähnen. Bezüglich Codeblockhervorhebung und Latex-Rendering. Highlight verwendet highlight.js. Marked unterstützt diese Bibliothek und kann direkt verwendet werden. Es kann die Sprache automatisch erkennen. Wenn Sie diese Funktion nicht aufrufen möchten, können Sie auch die Sprache beurteilen, die der Benutzer verwenden wird. Um das Design zu verwenden, müssen Sie auf das CSS verweisen, das dem Stil im Paket entspricht. Eine weitere wichtige Sache ist, dass das gerenderte Tag das Attribut der Klasse hljs haben muss, sonst können Sie nur sehen, dass der Code hervorgehoben ist. Was das Hinzufügen des Klassenattributs betrifft: Wenn Sie keine Letax-Anforderung haben, müssen Sie beim Rendern nur eine Tag-Ebene hinzufügen, und das Klassenattribut lautet wie folgt. Das einzige, was übrig bleibt, ist Latex, da Marked selbst kein Latex unterstützt, aber das Umschreiben der Renderfunktion unterstützt, um Unterstützung für Latex zu erreichen. Hier verwende ich Katex, und wer interessiert ist, kann Mathjax ausprobieren. Ein Nachteil besteht jedoch darin, dass die mathematische Formel von einem Codeblock umgeben sein muss, d. h. Nun, dieser Austausch endet hier, wir sehen uns wieder~ Dies ist das Ende dieses Artikels über den Ace-basierten Markdown-Editor. Weitere Informationen zum Ace Markdown-Editor finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erläuterung des Beispielcodes für das elastische CSS3 Flex-Layout
>>: Sammlung einer Zusammenfassung der HTML-Iframe-Nutzung
Die Elemente in einem HTML-Dokument werden hinter...
Inhaltsverzeichnis 1. Übersicht 1.1 Verwendung vo...
MySQL-Anweisungen zum Hinzufügen, Löschen, Ändern...
Inhaltsverzeichnis Hintergrund Wirkung Ideen Hint...
Problemhintergrund: Wenn Sie Docker zum Bereitste...
<br />Dies ist eine Reihe von Tutorials, die...
Vorwort Workbench ist auf einem Computer installi...
Wie unten dargestellt: wähle a1,a2,a1+a2 a,a1*a2 ...
Inhaltsverzeichnis 1. Anwendung und Konfiguration...
In diesem Artikel wird die Installations- und Kon...
Verstehen Sie zunächst eine Methode: Aufrufen ein...
In diesem Artikel wird der spezifische Code von V...
So geben Sie das übergeordnete Verzeichnis an ../ ...
Dieser Artikel fasst hauptsächlich einige häufig ...
Wenn Sie Tomcat in Docker installieren, kann es b...