Эффективное редактирование вики-текстов — плагин CodeEditor
(Created page with "Вики-статьи, с их возможностью включений, шаблонов, макросов отлично подходят для формирования...") |
|||
Line 4: | Line 4: | ||
* LaTeX — неплохо, но наследие ужасной разметки и слабая генерация html-контента — не то. | * LaTeX — неплохо, но наследие ужасной разметки и слабая генерация html-контента — не то. | ||
* Pandoc-стек с Markdown — очень перспективно, но до сих пор нет стандарта на включение документов (куча фильтров, у каждого свои проблемы). | * Pandoc-стек с Markdown — очень перспективно, но до сих пор нет стандарта на включение документов (куча фильтров, у каждого свои проблемы). | ||
+ | |||
+ | Основные проблемы написания технических документов с вики-системами и вообще любыми веб-CMS — не очень удобно использовать стандартную textare для разметки, хочется заюзать все пространство вкладки браузера, и возможности нормального редактора, типа VS Code. | ||
+ | Есть [https://github.com/Frederisk/Wikitext-Extension-Gadget всякие такие] интеграторы с VS Code, но все-таки не особо удобно, отдельно VS Code с его мешаниной вкладок, отдельно броузер с его вкладками, особенно когда редактируешь кучу документов — надо бы чтобы это было встроено в броузер, чтобы как-то рулить ими («Tree Style Tab» — почему еще не все с этим живут?). | ||
+ | |||
+ | Для последний версий MediaWiki уже есть https://www.mediawiki.org/wiki/Extension:CodeEditor — очень похоже на то что надо, но наша сборка пока еще (все сил нет обновлять) на замороженных старых версиях MediaWiki, наверно не сработает. | ||
+ | |||
+ | С другой стороны, а почему бы не поставить экстенш прямо в броузер? Собственно более умные редакторы textarea всегда были тем, что хотелось опытным пользователям (сам в нулевых писал на первом механизме FF extensionнов интеграцию с notepad++…), и вот, есть расширение | ||
+ | https://addons.mozilla.org/en-US/firefox/addon/code-editor/ , которое затаскивает «почти VS Code» (ну вернее «Monaco Editor», на котором он основан), прямо в Firefox. | ||
+ | |||
+ | Осталось чуть настроить его, чтобы было удобней русскоязычным пользователям MediaWiki (да, без этого будет не оч) | ||
+ | |||
+ | <source code="javascript"> | ||
+ | /** | ||
+ | * @type {Context} | ||
+ | */ | ||
+ | ({ | ||
+ | /** | ||
+ | * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneEditorConstructionOptions.html} | ||
+ | * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneDiffEditorConstructionOptions.html} | ||
+ | */ | ||
+ | options: { | ||
+ | minimap: { | ||
+ | enabled: false, | ||
+ | }, | ||
+ | unicodeHighlight: { | ||
+ | ambiguousCharacters: false, | ||
+ | }, | ||
+ | theme: "vs", | ||
+ | language: "plaintext", | ||
+ | wordWrap: "off", | ||
+ | accessibilitySupport: "on", | ||
+ | accessibilityPageSize: 20, | ||
+ | scrollBeyondLastLine: true, | ||
+ | ignoreTrimWhitespace: true, | ||
+ | useInlineViewWhenSpaceIsLimited: true, | ||
+ | }, | ||
+ | /** | ||
+ | * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IActionDescriptor.html} | ||
+ | */ | ||
+ | actions: { | ||
+ | "user.toggleWordWarp": { | ||
+ | label: "Toggle Word Wrap", | ||
+ | keybindings: [ | ||
+ | "Alt+KeyZ", | ||
+ | ], | ||
+ | contextMenuGroupId: "view", | ||
+ | contextMenuOrder: 4.5, | ||
+ | run(editor) { | ||
+ | let wrappingInfo = editor.getOption(monaco.editor.EditorOption.wrappingInfo); | ||
+ | editor.updateOptions({ | ||
+ | wordWrapOverride2: wrappingInfo.wrappingColumn == -1 ? 'on' : 'off', | ||
+ | }); | ||
+ | }, | ||
+ | }, | ||
+ | "user.toggleIgnoreTrimWhitespace": { | ||
+ | label: "Toggle Show Trim Whitespace Diff", | ||
+ | precondition: "isInDiffEditor", | ||
+ | contextMenuGroupId: "view", | ||
+ | contextMenuOrder: 4.6, | ||
+ | run() { | ||
+ | let editor = editorUtil.editor; | ||
+ | let value = editor._options?.ignoreTrimWhitespace?.value; | ||
+ | editor.updateOptions({ | ||
+ | ignoreTrimWhitespace: !value, | ||
+ | }); | ||
+ | }, | ||
+ | }, | ||
+ | }, | ||
+ | init: [ | ||
+ | { | ||
+ | func() { | ||
+ | // console.log("ext-code-editor.init"); | ||
+ | }, | ||
+ | args: [], | ||
+ | injectImmediately: false, | ||
+ | }, | ||
+ | { | ||
+ | injectImmediately: true, | ||
+ | func() { | ||
+ | let addTouchTools = () => { | ||
+ | self.removeEventListener('touchstart', addTouchTools, true); | ||
+ | console.debug('addTouchTools'); | ||
+ | editorUtil.addActions({ | ||
+ | "user.undo": { | ||
+ | label: "Undo", | ||
+ | precondition: "textInputFocus && !editorReadonly", | ||
+ | contextMenuGroupId: " 1_modification", | ||
+ | contextMenuOrder: 11, | ||
+ | run(editor) { | ||
+ | editor.trigger("", "undo"); | ||
+ | }, | ||
+ | }, | ||
+ | "user.redo": { | ||
+ | label: "Redo", | ||
+ | precondition: "textInputFocus && !editorReadonly", | ||
+ | contextMenuGroupId: " 1_modification", | ||
+ | contextMenuOrder: 12, | ||
+ | run(editor) { | ||
+ | editor.trigger("", "redo"); | ||
+ | }, | ||
+ | }, | ||
+ | "user.paste": { | ||
+ | label: "Paste Clipboard Text", | ||
+ | precondition: "textInputFocus && !editorReadonly", | ||
+ | contextMenuGroupId: "9_cutcopypaste", | ||
+ | contextMenuOrder: 4, | ||
+ | async run(editor) { | ||
+ | // Requires ACCESS_LEVEL >=30 | ||
+ | if (self.browser) { | ||
+ | try { | ||
+ | await browser.permissions.request({ permissions: ['clipboardRead'] }); | ||
+ | } catch (e) { | ||
+ | console.warn(e); | ||
+ | } | ||
+ | } | ||
+ | try { | ||
+ | let text = await navigator.clipboard.readText(); | ||
+ | if (!text) return; | ||
+ | editor.executeEdits("", [{ | ||
+ | forceMoveMarkers: true, | ||
+ | range: editor.getSelection(), | ||
+ | text, | ||
+ | }]); | ||
+ | } catch (e) { | ||
+ | console.warn(e); | ||
+ | } finally { | ||
+ | // await browser.permissions.remove({ permissions: ['clipboardRead'] }); | ||
+ | } | ||
+ | }, | ||
+ | }, | ||
+ | "user.delete": { | ||
+ | label: "Delete", | ||
+ | precondition: "!editorReadonly && editorHasSelection", | ||
+ | contextMenuGroupId: "9_cutcopypaste", | ||
+ | contextMenuOrder: 5, | ||
+ | run(editor) { | ||
+ | editor.executeEdits("", [{ | ||
+ | forceMoveMarkers: true, | ||
+ | range: editor.getSelection(), | ||
+ | text: "", | ||
+ | }]); | ||
+ | }, | ||
+ | }, | ||
+ | "user.selectAll": { | ||
+ | label: "Select All", | ||
+ | precondition: "textInputFocus", | ||
+ | contextMenuGroupId: "9_cutcopypaste", | ||
+ | contextMenuOrder: 6, | ||
+ | run(editor) { | ||
+ | editor.setSelection(editor.getModel().getFullModelRange()); | ||
+ | }, | ||
+ | }, | ||
+ | "user.find": { | ||
+ | label: "Find...", | ||
+ | precondition: "textInputFocus && !findWidgetVisible", | ||
+ | contextMenuGroupId: "view", | ||
+ | contextMenuOrder: 4.9, | ||
+ | run() { | ||
+ | editor.trigger("", "actions.find"); | ||
+ | }, | ||
+ | }, | ||
+ | }); | ||
+ | }; | ||
+ | self.addEventListener('touchstart', addTouchTools, true); | ||
+ | }, | ||
+ | }, | ||
+ | ], | ||
+ | }) | ||
+ | </source> |
Revision as of 10:00, 10 April 2024
Вики-статьи, с их возможностью включений, шаблонов, макросов отлично подходят для формирования целостной, самособираемой технической документации по различным проектам. Ведь альтернативы:
- Офисные форматы с слабыми возможностями включения документов (OpenOffice, Word) — не дотягивают по гибкости.
- SGML Docbook — было неплохо для 90ых, но протухло и сдохло.
- LaTeX — неплохо, но наследие ужасной разметки и слабая генерация html-контента — не то.
- Pandoc-стек с Markdown — очень перспективно, но до сих пор нет стандарта на включение документов (куча фильтров, у каждого свои проблемы).
Основные проблемы написания технических документов с вики-системами и вообще любыми веб-CMS — не очень удобно использовать стандартную textare для разметки, хочется заюзать все пространство вкладки браузера, и возможности нормального редактора, типа VS Code. Есть всякие такие интеграторы с VS Code, но все-таки не особо удобно, отдельно VS Code с его мешаниной вкладок, отдельно броузер с его вкладками, особенно когда редактируешь кучу документов — надо бы чтобы это было встроено в броузер, чтобы как-то рулить ими («Tree Style Tab» — почему еще не все с этим живут?).
Для последний версий MediaWiki уже есть https://www.mediawiki.org/wiki/Extension:CodeEditor — очень похоже на то что надо, но наша сборка пока еще (все сил нет обновлять) на замороженных старых версиях MediaWiki, наверно не сработает.
С другой стороны, а почему бы не поставить экстенш прямо в броузер? Собственно более умные редакторы textarea всегда были тем, что хотелось опытным пользователям (сам в нулевых писал на первом механизме FF extensionнов интеграцию с notepad++…), и вот, есть расширение https://addons.mozilla.org/en-US/firefox/addon/code-editor/ , которое затаскивает «почти VS Code» (ну вернее «Monaco Editor», на котором он основан), прямо в Firefox.
Осталось чуть настроить его, чтобы было удобней русскоязычным пользователям MediaWiki (да, без этого будет не оч)
Invalid language.
You need to specify a language like this: <source lang="html4strict">...</source>
Supported languages for syntax highlighting:
4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript, actionscript3, ada, aimms, algol68, apache, applescript, arm, asm, asp, asymptote, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, caddcl, cadlisp, cfdg, cfm, chaiscript, chapel, cil, clojure, cmake, cobol, coffeescript, cpp, csharp, css, cuesheet, d, dart, dcl, dcpu16, dcs, delphi, diff, div, dos, dot, e, ecmascript, eiffel, email, epc, erlang, euphoria, ezt, f1, falcon, fo, fortran, freebasic, freeswitch, fsharp, gambas, gdb, genero, genie, gettext, glsl, gml, gnuplot, go, groovy, gwbasic, haskell, haxe, hicest, hq9plus, html4strict, html5, icon, idl, ini, inno, intercal, io, ispfpanel, j, java, java5, javascript, jcl, jquery, kixtart, klonec, klonecpp, latex, lb, ldif, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, mmix, modula2, modula3, mpasm, mxml, mysql, nagios, netrexx, newlisp, nginx, nimrod, nsis, oberon2, objc, objeck, ocaml, octave, oobas, oorexx, oracle11, oracle8, oxygene, oz, parasail, parigp, pascal, pcre, per, perl, perl6, pf, php, pic16, pike, pixelbender, pli, plsql, postgresql, postscript, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, pys60, python, q, qbasic, qml, racket, rails, rbs, rebol, reg, rexx, robots, rpmspec, rsplus, ruby, rust, sas, scala, scheme, scilab, scl, sdlbasic, smalltalk, smarty, spark, sparql, sql, standardml, stonescript, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, upc, urbi, uscript, vala, vb, vbnet, vbscript, vedit, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, whois, winbatch, xbasic, xml, xpp, yaml, z80, zxbasic
/** * @type {Context} */ ({ /** * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneEditorConstructionOptions.html} * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IStandaloneDiffEditorConstructionOptions.html} */ options: { minimap: { enabled: false, }, unicodeHighlight: { ambiguousCharacters: false, }, theme: "vs", language: "plaintext", wordWrap: "off", accessibilitySupport: "on", accessibilityPageSize: 20, scrollBeyondLastLine: true, ignoreTrimWhitespace: true, useInlineViewWhenSpaceIsLimited: true, }, /** * {@link https://microsoft.github.io/monaco-editor/docs.html#interfaces/editor.IActionDescriptor.html} */ actions: { "user.toggleWordWarp": { label: "Toggle Word Wrap", keybindings: [ "Alt+KeyZ", ], contextMenuGroupId: "view", contextMenuOrder: 4.5, run(editor) { let wrappingInfo = editor.getOption(monaco.editor.EditorOption.wrappingInfo); editor.updateOptions({ wordWrapOverride2: wrappingInfo.wrappingColumn == -1 ? 'on' : 'off', }); }, }, "user.toggleIgnoreTrimWhitespace": { label: "Toggle Show Trim Whitespace Diff", precondition: "isInDiffEditor", contextMenuGroupId: "view", contextMenuOrder: 4.6, run() { let editor = editorUtil.editor; let value = editor._options?.ignoreTrimWhitespace?.value; editor.updateOptions({ ignoreTrimWhitespace: !value, }); }, }, }, init: [ { func() { // console.log("ext-code-editor.init"); }, args: [], injectImmediately: false, }, { injectImmediately: true, func() { let addTouchTools = () => { self.removeEventListener('touchstart', addTouchTools, true); console.debug('addTouchTools'); editorUtil.addActions({ "user.undo": { label: "Undo", precondition: "textInputFocus && !editorReadonly", contextMenuGroupId: " 1_modification", contextMenuOrder: 11, run(editor) { editor.trigger("", "undo"); }, }, "user.redo": { label: "Redo", precondition: "textInputFocus && !editorReadonly", contextMenuGroupId: " 1_modification", contextMenuOrder: 12, run(editor) { editor.trigger("", "redo"); }, }, "user.paste": { label: "Paste Clipboard Text", precondition: "textInputFocus && !editorReadonly", contextMenuGroupId: "9_cutcopypaste", contextMenuOrder: 4, async run(editor) { // Requires ACCESS_LEVEL >=30 if (self.browser) { try { await browser.permissions.request({ permissions: ['clipboardRead'] }); } catch (e) { console.warn(e); } } try { let text = await navigator.clipboard.readText(); if (!text) return; editor.executeEdits("", [{ forceMoveMarkers: true, range: editor.getSelection(), text, }]); } catch (e) { console.warn(e); } finally { // await browser.permissions.remove({ permissions: ['clipboardRead'] }); } }, }, "user.delete": { label: "Delete", precondition: "!editorReadonly && editorHasSelection", contextMenuGroupId: "9_cutcopypaste", contextMenuOrder: 5, run(editor) { editor.executeEdits("", [{ forceMoveMarkers: true, range: editor.getSelection(), text: "", }]); }, }, "user.selectAll": { label: "Select All", precondition: "textInputFocus", contextMenuGroupId: "9_cutcopypaste", contextMenuOrder: 6, run(editor) { editor.setSelection(editor.getModel().getFullModelRange()); }, }, "user.find": { label: "Find...", precondition: "textInputFocus && !findWidgetVisible", contextMenuGroupId: "view", contextMenuOrder: 4.9, run() { editor.trigger("", "actions.find"); }, }, }); }; self.addEventListener('touchstart', addTouchTools, true); }, }, ], })