diff --git a/server/modules/rendering/markdown-abbr/definition.yml b/server/modules/rendering/markdown-abbr/definition.yml deleted file mode 100644 index f64ab46c..00000000 --- a/server/modules/rendering/markdown-abbr/definition.yml +++ /dev/null @@ -1,8 +0,0 @@ -key: markdownAbbr -title: Abbreviations -description: Parse abbreviations into abbr tags -author: requarks.io -icon: mdi-contain-start -enabledDefault: true -dependsOn: markdown-core -props: {} diff --git a/server/modules/rendering/markdown-abbr/renderer.js b/server/modules/rendering/markdown-abbr/renderer.js deleted file mode 100644 index 3438f947..00000000 --- a/server/modules/rendering/markdown-abbr/renderer.js +++ /dev/null @@ -1,11 +0,0 @@ -const mdAbbr = require('markdown-it-abbr') - -// ------------------------------------ -// Markdown - Abbreviations -// ------------------------------------ - -module.exports = { - init (md, conf) { - md.use(mdAbbr) - } -} diff --git a/server/modules/rendering/markdown-core/definition.yml b/server/modules/rendering/markdown-core/definition.yml deleted file mode 100644 index 17a35702..00000000 --- a/server/modules/rendering/markdown-core/definition.yml +++ /dev/null @@ -1,63 +0,0 @@ -key: markdown-core -title: Core -description: Basic Markdown Parser -author: requarks.io -input: markdown -output: html -icon: mdi-language-markdown -props: - allowHTML: - type: Boolean - default: true - title: Allow HTML - hint: Enable HTML tags in content. - order: 1 - public: true - linkify: - type: Boolean - default: true - title: Automatically convert links - hint: Links will automatically be converted to clickable links. - order: 2 - public: true - linebreaks: - type: Boolean - default: true - title: Automatically convert line breaks - hint: Add linebreaks within paragraphs. - order: 3 - public: true - underline: - type: Boolean - default: false - title: Underline Emphasis - hint: Enable text underlining by using _underline_ syntax. - order: 4 - public: true - typographer: - type: Boolean - default: false - title: Typographer - hint: Enable some language-neutral replacement + quotes beautification. - order: 5 - public: true - quotes: - type: String - default: English - title: Quotes style - hint: When typographer is enabled. Double + single quotes replacement pairs. e.g. «»„“ for Russian, „“‚‘ for German, etc. - order: 6 - enum: - - Chinese - - English - - French - - German - - Greek - - Japanese - - Hungarian - - Polish - - Portuguese - - Russian - - Spanish - - Swedish - public: true diff --git a/server/modules/rendering/markdown-core/renderer.js b/server/modules/rendering/markdown-core/renderer.js deleted file mode 100644 index 8e686c6c..00000000 --- a/server/modules/rendering/markdown-core/renderer.js +++ /dev/null @@ -1,53 +0,0 @@ -const md = require('markdown-it') -const mdAttrs = require('markdown-it-attrs') -const _ = require('lodash') -const underline = require('./underline') - -const quoteStyles = { - Chinese: '””‘’', - English: '“”‘’', - French: ['«\xA0', '\xA0»', '‹\xA0', '\xA0›'], - German: '„“‚‘', - Greek: '«»‘’', - Japanese: '「」「」', - Hungarian: '„”’’', - Polish: '„”‚‘', - Portuguese: '«»‘’', - Russian: '«»„“', - Spanish: '«»‘’', - Swedish: '””’’' -} - -module.exports = { - async render() { - const mkdown = md({ - html: this.config.allowHTML, - breaks: this.config.linebreaks, - linkify: this.config.linkify, - typographer: this.config.typographer, - quotes: _.get(quoteStyles, this.config.quotes, quoteStyles.English), - highlight(str, lang) { - if (lang === 'diagram') { - return `
` + Buffer.from(str, 'base64').toString() + `` - } else { - return `
${_.escape(str)}
`
- }
- }
- })
-
- if (this.config.underline) {
- mkdown.use(underline)
- }
-
- mkdown.use(mdAttrs, {
- allowedAttributes: ['id', 'class', 'target']
- })
-
- for (let child of this.children) {
- const renderer = require(`../${child.key}/renderer.js`)
- await renderer.init(mkdown, child.config)
- }
-
- return mkdown.render(this.input)
- }
-}
diff --git a/server/modules/rendering/markdown-core/underline.js b/server/modules/rendering/markdown-core/underline.js
deleted file mode 100644
index a7bc47f8..00000000
--- a/server/modules/rendering/markdown-core/underline.js
+++ /dev/null
@@ -1,12 +0,0 @@
-const renderEm = (tokens, idx, opts, env, slf) => {
- const token = tokens[idx]
- if (token.markup === '_') {
- token.tag = 'u'
- }
- return slf.renderToken(tokens, idx, opts)
-}
-
-module.exports = (md) => {
- md.renderer.rules.em_open = renderEm
- md.renderer.rules.em_close = renderEm
-}
diff --git a/server/modules/rendering/markdown-emoji/definition.yml b/server/modules/rendering/markdown-emoji/definition.yml
deleted file mode 100644
index 716cddee..00000000
--- a/server/modules/rendering/markdown-emoji/definition.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-key: markdownEmoji
-title: Emoji
-description: Convert tags to emojis
-author: requarks.io
-icon: mdi-sticker-emoji
-enabledDefault: true
-dependsOn: markdown-core
-props: {}
diff --git a/server/modules/rendering/markdown-emoji/renderer.js b/server/modules/rendering/markdown-emoji/renderer.js
deleted file mode 100644
index 331b97ef..00000000
--- a/server/modules/rendering/markdown-emoji/renderer.js
+++ /dev/null
@@ -1,20 +0,0 @@
-const mdEmoji = require('markdown-it-emoji')
-const twemoji = require('twemoji')
-
-// ------------------------------------
-// Markdown - Emoji
-// ------------------------------------
-
-module.exports = {
- init (md, conf) {
- md.use(mdEmoji)
-
- md.renderer.rules.emoji = (token, idx) => {
- return twemoji.parse(token[idx].content, {
- callback (icon, opts) {
- return `/_assets/svg/twemoji/${icon}.svg`
- }
- })
- }
- }
-}
diff --git a/server/modules/rendering/markdown-expandtabs/definition.yml b/server/modules/rendering/markdown-expandtabs/definition.yml
deleted file mode 100644
index 6531d2a8..00000000
--- a/server/modules/rendering/markdown-expandtabs/definition.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-key: markdownExpandtabs
-title: Expand Tabs
-description: Replace tabs with spaces in code blocks
-author: requarks.io
-icon: mdi-arrow-expand-horizontal
-enabledDefault: true
-dependsOn: markdown-core
-props:
- tabWidth:
- type: Number
- title: Tab Width
- hint: Amount of spaces for each tab
- default: 4
diff --git a/server/modules/rendering/markdown-expandtabs/renderer.js b/server/modules/rendering/markdown-expandtabs/renderer.js
deleted file mode 100644
index 39c0825f..00000000
--- a/server/modules/rendering/markdown-expandtabs/renderer.js
+++ /dev/null
@@ -1,14 +0,0 @@
-const mdExpandTabs = require('markdown-it-expand-tabs')
-const _ = require('lodash')
-
-// ------------------------------------
-// Markdown - Expand Tabs
-// ------------------------------------
-
-module.exports = {
- init (md, conf) {
- md.use(mdExpandTabs, {
- tabWidth: _.toInteger(conf.tabWidth || 4)
- })
- }
-}
diff --git a/server/modules/rendering/markdown-footnotes/definition.yml b/server/modules/rendering/markdown-footnotes/definition.yml
deleted file mode 100644
index 00876294..00000000
--- a/server/modules/rendering/markdown-footnotes/definition.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-key: markdownFootnotes
-title: Footnotes
-description: Parse footnotes references
-author: requarks.io
-icon: mdi-page-layout-footer
-enabledDefault: true
-dependsOn: markdown-core
-props: {}
diff --git a/server/modules/rendering/markdown-footnotes/renderer.js b/server/modules/rendering/markdown-footnotes/renderer.js
deleted file mode 100644
index 553b04b3..00000000
--- a/server/modules/rendering/markdown-footnotes/renderer.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const mdFootnote = require('markdown-it-footnote')
-
-// ------------------------------------
-// Markdown - Footnotes
-// ------------------------------------
-
-module.exports = {
- init (md, conf) {
- md.use(mdFootnote)
- }
-}
diff --git a/server/modules/rendering/markdown-imsize/definition.yml b/server/modules/rendering/markdown-imsize/definition.yml
deleted file mode 100644
index 603a3069..00000000
--- a/server/modules/rendering/markdown-imsize/definition.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-key: markdownImsize
-title: Image Size
-description: Adds dimensions attributes to images
-author: requarks.io
-icon: mdi-image-size-select-large
-enabledDefault: true
-dependsOn: markdown-core
-props: {}
diff --git a/server/modules/rendering/markdown-imsize/renderer.js b/server/modules/rendering/markdown-imsize/renderer.js
deleted file mode 100644
index 33bd80ac..00000000
--- a/server/modules/rendering/markdown-imsize/renderer.js
+++ /dev/null
@@ -1,11 +0,0 @@
-const mdImsize = require('markdown-it-imsize')
-
-// ------------------------------------
-// Markdown - Image Size
-// ------------------------------------
-
-module.exports = {
- init (md, conf) {
- md.use(mdImsize)
- }
-}
diff --git a/server/modules/rendering/markdown-katex/definition.yml b/server/modules/rendering/markdown-katex/definition.yml
deleted file mode 100644
index 0532ea75..00000000
--- a/server/modules/rendering/markdown-katex/definition.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-key: markdownKatex
-title: Katex
-description: LaTeX Math + Chemical Expression Typesetting Renderer
-author: requarks.io
-icon: mdi-math-integral
-enabledDefault: true
-dependsOn: markdown-core
-props:
- useInline:
- type: Boolean
- default: true
- title: Inline TeX
- hint: Process inline TeX expressions surrounded by $ symbols.
- order: 1
- useBlocks:
- type: Boolean
- default: true
- title: TeX Blocks
- hint: Process TeX blocks enclosed by $$ symbols.
- order: 2
diff --git a/server/modules/rendering/markdown-katex/mhchem.js b/server/modules/rendering/markdown-katex/mhchem.js
deleted file mode 100644
index 4a9860f7..00000000
--- a/server/modules/rendering/markdown-katex/mhchem.js
+++ /dev/null
@@ -1,1677 +0,0 @@
-/* eslint-disable */
-/* -*- Mode: Javascript; indent-tabs-mode:nil; js-indent-level: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-
-/*************************************************************
- *
- * KaTeX mhchem.js
- *
- * This file implements a KaTeX version of mhchem version 3.3.0.
- * It is adapted from MathJax/extensions/TeX/mhchem.js
- * It differs from the MathJax version as follows:
- * 1. The interface is changed so that it can be called from KaTeX, not MathJax.
- * 2. \rlap and \llap are replaced with \mathrlap and \mathllap.
- * 3. Four lines of code are edited in order to use \raisebox instead of \raise.
- * 4. The reaction arrow code is simplified. All reaction arrows are rendered
- * using KaTeX extensible arrows instead of building non-extensible arrows.
- * 5. \tripledash vertical alignment is slightly adjusted.
- *
- * This code, as other KaTeX code, is released under the MIT license.
- *
- * /*************************************************************
- *
- * MathJax/extensions/TeX/mhchem.js
- *
- * Implements the \ce command for handling chemical formulas
- * from the mhchem LaTeX package.
- *
- * ---------------------------------------------------------------------
- *
- * Copyright (c) 2011-2015 The MathJax Consortium
- * Copyright (c) 2015-2018 Martin Hensel
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Coding Style
-// - use '' for identifiers that can by minified/uglified
-// - use "" for strings that need to stay untouched
-
-// version: "3.3.0" for MathJax and KaTeX
-
-
- //
- // This is the main function for handing the \ce and \pu commands.
- // It takes the argument to \ce or \pu and returns the corresponding TeX string.
- //
-
- module.exports = function (tokens, stateMachine) {
- // Recreate the argument string from KaTeX's array of tokens.
- var str = "";
- var expectedLoc = tokens[tokens.length - 1].loc.start
- for (var i = tokens.length - 1; i >= 0; i--) {
- if(tokens[i].loc.start > expectedLoc) {
- // context.consumeArgs has eaten a space.
- str += " ";
- expectedLoc = tokens[i].loc.start;
- }
- str += tokens[i].text;
- expectedLoc += tokens[i].text.length;
- }
- var tex = texify.go(mhchemParser.go(str, stateMachine));
- return tex;
- };
-
- //
- // Core parser for mhchem syntax (recursive)
- //
- /** @type {MhchemParser} */
- var mhchemParser = {
- //
- // Parses mchem \ce syntax
- //
- // Call like
- // go("H2O");
- //
- go: function (input, stateMachine) {
- if (!input) { return []; }
- if (stateMachine === undefined) { stateMachine = 'ce'; }
- var state = '0';
-
- //
- // String buffers for parsing:
- //
- // buffer.a == amount
- // buffer.o == element
- // buffer.b == left-side superscript
- // buffer.p == left-side subscript
- // buffer.q == right-side subscript
- // buffer.d == right-side superscript
- //
- // buffer.r == arrow
- // buffer.rdt == arrow, script above, type
- // buffer.rd == arrow, script above, content
- // buffer.rqt == arrow, script below, type
- // buffer.rq == arrow, script below, content
- //
- // buffer.text_
- // buffer.rm
- // etc.
- //
- // buffer.parenthesisLevel == int, starting at 0
- // buffer.sb == bool, space before
- // buffer.beginsWithBond == bool
- //
- // These letters are also used as state names.
- //
- // Other states:
- // 0 == begin of main part (arrow/operator unlikely)
- // 1 == next entity
- // 2 == next entity (arrow/operator unlikely)
- // 3 == next atom
- // c == macro
- //
- /** @type {Buffer} */
- var buffer = {};
- buffer['parenthesisLevel'] = 0;
-
- input = input.replace(/\n/g, " ");
- input = input.replace(/[\u2212\u2013\u2014\u2010]/g, "-");
- input = input.replace(/[\u2026]/g, "...");
-
- //
- // Looks through mhchemParser.transitions, to execute a matching action
- // (recursive)
- //
- var lastInput;
- var watchdog = 10;
- /** @type {ParserOutput[]} */
- var output = [];
- while (true) {
- if (lastInput !== input) {
- watchdog = 10;
- lastInput = input;
- } else {
- watchdog--;
- }
- //
- // Find actions in transition table
- //
- var machine = mhchemParser.stateMachines[stateMachine];
- var t = machine.transitions[state] || machine.transitions['*'];
- iterateTransitions:
- for (var i=0; i` + katex.renderToString(tokens[idx].content, { - displayMode: true - }) + `
` - } catch (err) { - WIKI.logger.warn(err) - return tokens[idx].content - } - } - } - } -} - -// Test if potential opening or closing delimieter -// Assumes that there is a "$" at state.src[pos] -function isValidDelim (state, pos) { - let prevChar - let nextChar - let max = state.posMax - let canOpen = true - let canClose = true - - prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1 - nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1 - - // Check non-whitespace conditions for opening and closing, and - // check that closing delimeter isn't followed by a number - if (prevChar === 0x20/* " " */ || prevChar === 0x09/* \t */ || - (nextChar >= 0x30/* "0" */ && nextChar <= 0x39/* "9" */)) { - canClose = false - } - if (nextChar === 0x20/* " " */ || nextChar === 0x09/* \t */) { - canOpen = false - } - - return { - canOpen: canOpen, - canClose: canClose - } -} - -function katexInline (state, silent) { - let start, match, token, res, pos - - if (state.src[state.pos] !== '$') { return false } - - res = isValidDelim(state, state.pos) - if (!res.canOpen) { - if (!silent) { state.pending += '$' } - state.pos += 1 - return true - } - - // First check for and bypass all properly escaped delimieters - // This loop will assume that the first leading backtick can not - // be the first character in state.src, which is known since - // we have found an opening delimieter already. - start = state.pos + 1 - match = start - while ((match = state.src.indexOf('$', match)) !== -1) { - // Found potential $, look for escapes, pos will point to - // first non escape when complete - pos = match - 1 - while (state.src[pos] === '\\') { pos -= 1 } - - // Even number of escapes, potential closing delimiter found - if (((match - pos) % 2) === 1) { break } - match += 1 - } - - // No closing delimter found. Consume $ and continue. - if (match === -1) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - // Check if we have empty content, ie: $$. Do not parse. - if (match - start === 0) { - if (!silent) { state.pending += '$$' } - state.pos = start + 1 - return true - } - - // Check for valid closing delimiter - res = isValidDelim(state, match) - if (!res.canClose) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - if (!silent) { - token = state.push('katex_inline', 'math', 0) - token.markup = '$' - token.content = state.src.slice(start, match) - } - - state.pos = match + 1 - return true -} - -function katexBlock (state, start, end, silent) { - let firstLine; let lastLine; let next; let lastPos; let found = false; let token - let pos = state.bMarks[start] + state.tShift[start] - let max = state.eMarks[start] - - if (pos + 2 > max) { return false } - if (state.src.slice(pos, pos + 2) !== '$$') { return false } - - pos += 2 - firstLine = state.src.slice(pos, max) - - if (silent) { return true } - if (firstLine.trim().slice(-2) === '$$') { - // Single line expression - firstLine = firstLine.trim().slice(0, -2) - found = true - } - - for (next = start; !found;) { - next++ - - if (next >= end) { break } - - pos = state.bMarks[next] + state.tShift[next] - max = state.eMarks[next] - - if (pos < max && state.tShift[next] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - break - } - - if (state.src.slice(pos, max).trim().slice(-2) === '$$') { - lastPos = state.src.slice(0, max).lastIndexOf('$$') - lastLine = state.src.slice(pos, lastPos) - found = true - } - } - - state.line = next + 1 - - token = state.push('katex_block', 'math', 0) - token.block = true - token.content = (firstLine && firstLine.trim() ? firstLine + '\n' : '') + - state.getLines(start + 1, next, state.tShift[start], true) + - (lastLine && lastLine.trim() ? lastLine : '') - token.map = [ start, state.line ] - token.markup = '$$' - return true -} diff --git a/server/modules/rendering/markdown-kroki/definition.yml b/server/modules/rendering/markdown-kroki/definition.yml deleted file mode 100644 index b56d3785..00000000 --- a/server/modules/rendering/markdown-kroki/definition.yml +++ /dev/null @@ -1,29 +0,0 @@ -key: markdownKroki -title: Kroki -description: Kroki Diagrams Parser -author: rlanyi (based on PlantUML renderer) -icon: mdi-sitemap -enabledDefault: false -dependsOn: markdown-core -props: - server: - type: String - default: https://kroki.io - title: Kroki Server - hint: Kroki server used for image generation - order: 1 - public: true - openMarker: - type: String - default: "```kroki" - title: Open Marker - hint: String to use as opening delimiter. Diagram type must be put in the next line in lowercase. - order: 2 - public: true - closeMarker: - type: String - default: "```" - title: Close Marker - hint: String to use as closing delimiter - order: 3 - public: true diff --git a/server/modules/rendering/markdown-kroki/renderer.js b/server/modules/rendering/markdown-kroki/renderer.js deleted file mode 100644 index 801bab6d..00000000 --- a/server/modules/rendering/markdown-kroki/renderer.js +++ /dev/null @@ -1,143 +0,0 @@ -const zlib = require('zlib') - -// ------------------------------------ -// Markdown - Kroki Preprocessor -// ------------------------------------ - -module.exports = { - init (mdinst, conf) { - mdinst.use((md, opts) => { - const openMarker = opts.openMarker || '```kroki' - const openChar = openMarker.charCodeAt(0) - const closeMarker = opts.closeMarker || '```' - const closeChar = closeMarker.charCodeAt(0) - const server = opts.server || 'https://kroki.io' - - md.block.ruler.before('fence', 'kroki', (state, startLine, endLine, silent) => { - let nextLine - let markup - let params - let token - let i - let autoClosed = false - let start = state.bMarks[startLine] + state.tShift[startLine] - let max = state.eMarks[startLine] - - // Check out the first character quickly, - // this should filter out most of non-uml blocks - // - if (openChar !== state.src.charCodeAt(start)) { return false } - - // Check out the rest of the marker string - // - for (i = 0; i < openMarker.length; ++i) { - if (openMarker[i] !== state.src[start + i]) { return false } - } - - markup = state.src.slice(start, start + i) - params = state.src.slice(start + i, max) - - // Since start is found, we can report success here in validation mode - // - if (silent) { return true } - - // Search for the end of the block - // - nextLine = startLine - - for (;;) { - nextLine++ - if (nextLine >= endLine) { - // unclosed block should be autoclosed by end of document. - // also block seems to be autoclosed by end of parent - break - } - - start = state.bMarks[nextLine] + state.tShift[nextLine] - max = state.eMarks[nextLine] - - if (start < max && state.sCount[nextLine] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - // - ``` - // test - break - } - - if (closeChar !== state.src.charCodeAt(start)) { - // didn't find the closing fence - continue - } - - if (state.sCount[nextLine] > state.sCount[startLine]) { - // closing fence should not be indented with respect of opening fence - continue - } - - let closeMarkerMatched = true - for (i = 0; i < closeMarker.length; ++i) { - if (closeMarker[i] !== state.src[start + i]) { - closeMarkerMatched = false - break - } - } - - if (!closeMarkerMatched) { - continue - } - - // make sure tail has spaces only - if (state.skipSpaces(start + i) < max) { - continue - } - - // found! - autoClosed = true - break - } - - let contents = state.src - .split('\n') - .slice(startLine + 1, nextLine) - .join('\n') - - // We generate a token list for the alt property, to mimic what the image parser does. - let altToken = [] - // Remove leading space if any. - let alt = params ? params.slice(1) : 'uml diagram' - state.md.inline.parse( - alt, - state.md, - state.env, - altToken - ) - - let firstlf = contents.indexOf('\n') - if (firstlf === -1) firstlf = undefined - let diagramType = contents.substring(0, firstlf) - contents = contents.substring(firstlf + 1) - - let result = zlib.deflateSync(contents).toString('base64').replace(/\+/g, '-').replace(/\//g, '_') - - token = state.push('kroki', 'img', 0) - // alt is constructed from children. No point in populating it here. - token.attrs = [ [ 'src', `${server}/${diagramType}/svg/${result}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ] - token.block = true - token.children = altToken - token.info = params - token.map = [ startLine, nextLine ] - token.markup = markup - - state.line = nextLine + (autoClosed ? 1 : 0) - - return true - }, { - alt: [ 'paragraph', 'reference', 'blockquote', 'list' ] - }) - md.renderer.rules.kroki = md.renderer.rules.image - }, { - openMarker: conf.openMarker, - closeMarker: conf.closeMarker, - server: conf.server - }) - } -} diff --git a/server/modules/rendering/markdown-mathjax/definition.yml b/server/modules/rendering/markdown-mathjax/definition.yml deleted file mode 100644 index c0e95120..00000000 --- a/server/modules/rendering/markdown-mathjax/definition.yml +++ /dev/null @@ -1,20 +0,0 @@ -key: markdownMathjax -title: Mathjax -description: LaTeX Math + Chemical Expression Typesetting Renderer -author: requarks.io -icon: mdi-math-integral -enabledDefault: false -dependsOn: markdown-core -props: - useInline: - type: Boolean - default: true - title: Inline TeX - hint: Process inline TeX expressions surrounded by $ symbols. - order: 1 - useBlocks: - type: Boolean - default: true - title: TeX Blocks - hint: Process TeX blocks enclosed by $$ symbols. - order: 2 diff --git a/server/modules/rendering/markdown-mathjax/renderer.js b/server/modules/rendering/markdown-mathjax/renderer.js deleted file mode 100644 index b7596521..00000000 --- a/server/modules/rendering/markdown-mathjax/renderer.js +++ /dev/null @@ -1,205 +0,0 @@ -const mjax = require('mathjax') - -// ------------------------------------ -// Markdown - MathJax Renderer -// ------------------------------------ - -const extensions = [ - 'bbox', - 'boldsymbol', - 'braket', - 'color', - 'extpfeil', - 'mhchem', - 'newcommand', - 'unicode', - 'verb' -] - -module.exports = { - async init (mdinst, conf) { - const MathJax = await mjax.init({ - loader: { - require: require, - paths: { mathjax: 'mathjax/es5' }, - load: [ - 'input/tex', - 'output/svg', - ...extensions.map(e => `[tex]/${e}`) - ] - }, - tex: { - packages: {'[+]': extensions} - } - }) - if (conf.useInline) { - mdinst.inline.ruler.after('escape', 'mathjax_inline', mathjaxInline) - mdinst.renderer.rules.mathjax_inline = (tokens, idx) => { - try { - const result = MathJax.tex2svg(tokens[idx].content, { - display: false - }) - return MathJax.startup.adaptor.innerHTML(result) - } catch (err) { - WIKI.logger.warn(err) - return tokens[idx].content - } - } - } - if (conf.useBlocks) { - mdinst.block.ruler.after('blockquote', 'mathjax_block', mathjaxBlock, { - alt: [ 'paragraph', 'reference', 'blockquote', 'list' ] - }) - mdinst.renderer.rules.mathjax_block = (tokens, idx) => { - try { - const result = MathJax.tex2svg(tokens[idx].content, { - display: true - }) - return `` + MathJax.startup.adaptor.innerHTML(result) + `
` - } catch (err) { - WIKI.logger.warn(err) - return tokens[idx].content - } - } - } - } -} - -// Test if potential opening or closing delimieter -// Assumes that there is a "$" at state.src[pos] -function isValidDelim (state, pos) { - let prevChar - let nextChar - let max = state.posMax - let canOpen = true - let canClose = true - - prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1 - nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1 - - // Check non-whitespace conditions for opening and closing, and - // check that closing delimeter isn't followed by a number - if (prevChar === 0x20/* " " */ || prevChar === 0x09/* \t */ || - (nextChar >= 0x30/* "0" */ && nextChar <= 0x39/* "9" */)) { - canClose = false - } - if (nextChar === 0x20/* " " */ || nextChar === 0x09/* \t */) { - canOpen = false - } - - return { - canOpen: canOpen, - canClose: canClose - } -} - -function mathjaxInline (state, silent) { - let start, match, token, res, pos - - if (state.src[state.pos] !== '$') { return false } - - res = isValidDelim(state, state.pos) - if (!res.canOpen) { - if (!silent) { state.pending += '$' } - state.pos += 1 - return true - } - - // First check for and bypass all properly escaped delimieters - // This loop will assume that the first leading backtick can not - // be the first character in state.src, which is known since - // we have found an opening delimieter already. - start = state.pos + 1 - match = start - while ((match = state.src.indexOf('$', match)) !== -1) { - // Found potential $, look for escapes, pos will point to - // first non escape when complete - pos = match - 1 - while (state.src[pos] === '\\') { pos -= 1 } - - // Even number of escapes, potential closing delimiter found - if (((match - pos) % 2) === 1) { break } - match += 1 - } - - // No closing delimter found. Consume $ and continue. - if (match === -1) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - // Check if we have empty content, ie: $$. Do not parse. - if (match - start === 0) { - if (!silent) { state.pending += '$$' } - state.pos = start + 1 - return true - } - - // Check for valid closing delimiter - res = isValidDelim(state, match) - if (!res.canClose) { - if (!silent) { state.pending += '$' } - state.pos = start - return true - } - - if (!silent) { - token = state.push('mathjax_inline', 'math', 0) - token.markup = '$' - token.content = state.src.slice(start, match) - } - - state.pos = match + 1 - return true -} - -function mathjaxBlock (state, start, end, silent) { - let firstLine; let lastLine; let next; let lastPos; let found = false; let token - let pos = state.bMarks[start] + state.tShift[start] - let max = state.eMarks[start] - - if (pos + 2 > max) { return false } - if (state.src.slice(pos, pos + 2) !== '$$') { return false } - - pos += 2 - firstLine = state.src.slice(pos, max) - - if (silent) { return true } - if (firstLine.trim().slice(-2) === '$$') { - // Single line expression - firstLine = firstLine.trim().slice(0, -2) - found = true - } - - for (next = start; !found;) { - next++ - - if (next >= end) { break } - - pos = state.bMarks[next] + state.tShift[next] - max = state.eMarks[next] - - if (pos < max && state.tShift[next] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - break - } - - if (state.src.slice(pos, max).trim().slice(-2) === '$$') { - lastPos = state.src.slice(0, max).lastIndexOf('$$') - lastLine = state.src.slice(pos, lastPos) - found = true - } - } - - state.line = next + 1 - - token = state.push('mathjax_block', 'math', 0) - token.block = true - token.content = (firstLine && firstLine.trim() ? firstLine + '\n' : '') + - state.getLines(start + 1, next, state.tShift[start], true) + - (lastLine && lastLine.trim() ? lastLine : '') - token.map = [ start, state.line ] - token.markup = '$$' - return true -} diff --git a/server/modules/rendering/markdown-multi-table/definition.yml b/server/modules/rendering/markdown-multi-table/definition.yml deleted file mode 100644 index 57885052..00000000 --- a/server/modules/rendering/markdown-multi-table/definition.yml +++ /dev/null @@ -1,23 +0,0 @@ -key: markdownMultiTable -title: MultiMarkdown Table -description: Add MultiMarkdown table support -author: requarks.io -icon: mdi-table -enabledDefault: false -dependsOn: markdown-core -props: - multilineEnabled: - type: Boolean - title: Multiline - hint: Enable multiple lines rows - default: true - headerlessEnabled: - type: Boolean - title: Headerless - hint: Enable ommited table headers - default: true - rowspanEnabled: - type: Boolean - title: Rowspan - hint: Enable table row spans - default: true diff --git a/server/modules/rendering/markdown-multi-table/renderer.js b/server/modules/rendering/markdown-multi-table/renderer.js deleted file mode 100644 index 79be64c1..00000000 --- a/server/modules/rendering/markdown-multi-table/renderer.js +++ /dev/null @@ -1,11 +0,0 @@ -const multiTable = require('markdown-it-multimd-table') - -module.exports = { - init (md, conf) { - md.use(multiTable, { - multiline: conf.multilineEnabled, - rowspan: conf.rowspanEnabled, - headerless: conf.headerlessEnabled - }) - } -} diff --git a/server/modules/rendering/markdown-plantuml/definition.yml b/server/modules/rendering/markdown-plantuml/definition.yml deleted file mode 100644 index eb81d834..00000000 --- a/server/modules/rendering/markdown-plantuml/definition.yml +++ /dev/null @@ -1,41 +0,0 @@ -key: markdownPlantuml -title: PlantUML -description: PlantUML Markdown Parser -author: ethanmdavidson -icon: mdi-sitemap -enabledDefault: true -dependsOn: markdown-core -props: - server: - type: String - default: https://plantuml.requarks.io - title: PlantUML Server - hint: PlantUML server used for image generation - order: 1 - public: true - openMarker: - type: String - default: "```plantuml" - title: Open Marker - hint: String to use as opening delimiter - order: 2 - public: true - closeMarker: - type: String - default: "```" - title: Close Marker - hint: String to use as closing delimiter - order: 3 - public: true - imageFormat: - type: String - default: svg - title: Image Format - hint: Format to use for rendered PlantUML images - enum: - - svg - - png - - latex - - ascii - order: 4 - public: true diff --git a/server/modules/rendering/markdown-plantuml/renderer.js b/server/modules/rendering/markdown-plantuml/renderer.js deleted file mode 100644 index 40eedc04..00000000 --- a/server/modules/rendering/markdown-plantuml/renderer.js +++ /dev/null @@ -1,190 +0,0 @@ -const zlib = require('zlib') - -// ------------------------------------ -// Markdown - PlantUML Preprocessor -// ------------------------------------ - -module.exports = { - init (mdinst, conf) { - mdinst.use((md, opts) => { - const openMarker = opts.openMarker || '```plantuml' - const openChar = openMarker.charCodeAt(0) - const closeMarker = opts.closeMarker || '```' - const closeChar = closeMarker.charCodeAt(0) - const imageFormat = opts.imageFormat || 'svg' - const server = opts.server || 'https://plantuml.requarks.io' - - md.block.ruler.before('fence', 'uml_diagram', (state, startLine, endLine, silent) => { - let nextLine - let markup - let params - let token - let i - let autoClosed = false - let start = state.bMarks[startLine] + state.tShift[startLine] - let max = state.eMarks[startLine] - - // Check out the first character quickly, - // this should filter out most of non-uml blocks - // - if (openChar !== state.src.charCodeAt(start)) { return false } - - // Check out the rest of the marker string - // - for (i = 0; i < openMarker.length; ++i) { - if (openMarker[i] !== state.src[start + i]) { return false } - } - - markup = state.src.slice(start, start + i) - params = state.src.slice(start + i, max) - - // Since start is found, we can report success here in validation mode - // - if (silent) { return true } - - // Search for the end of the block - // - nextLine = startLine - - for (;;) { - nextLine++ - if (nextLine >= endLine) { - // unclosed block should be autoclosed by end of document. - // also block seems to be autoclosed by end of parent - break - } - - start = state.bMarks[nextLine] + state.tShift[nextLine] - max = state.eMarks[nextLine] - - if (start < max && state.sCount[nextLine] < state.blkIndent) { - // non-empty line with negative indent should stop the list: - // - ``` - // test - break - } - - if (closeChar !== state.src.charCodeAt(start)) { - // didn't find the closing fence - continue - } - - if (state.sCount[nextLine] > state.sCount[startLine]) { - // closing fence should not be indented with respect of opening fence - continue - } - - let closeMarkerMatched = true - for (i = 0; i < closeMarker.length; ++i) { - if (closeMarker[i] !== state.src[start + i]) { - closeMarkerMatched = false - break - } - } - - if (!closeMarkerMatched) { - continue - } - - // make sure tail has spaces only - if (state.skipSpaces(start + i) < max) { - continue - } - - // found! - autoClosed = true - break - } - - const contents = state.src - .split('\n') - .slice(startLine + 1, nextLine) - .join('\n') - - // We generate a token list for the alt property, to mimic what the image parser does. - let altToken = [] - // Remove leading space if any. - let alt = params ? params.slice(1) : 'uml diagram' - state.md.inline.parse( - alt, - state.md, - state.env, - altToken - ) - - const zippedCode = encode64(zlib.deflateRawSync('@startuml\n' + contents + '\n@enduml').toString('binary')) - - token = state.push('uml_diagram', 'img', 0) - // alt is constructed from children. No point in populating it here. - token.attrs = [ [ 'src', `${server}/${imageFormat}/${zippedCode}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ] - token.block = true - token.children = altToken - token.info = params - token.map = [ startLine, nextLine ] - token.markup = markup - - state.line = nextLine + (autoClosed ? 1 : 0) - - return true - }, { - alt: [ 'paragraph', 'reference', 'blockquote', 'list' ] - }) - md.renderer.rules.uml_diagram = md.renderer.rules.image - }, { - openMarker: conf.openMarker, - closeMarker: conf.closeMarker, - imageFormat: conf.imageFormat, - server: conf.server - }) - } -} - -function encode64 (data) { - let r = '' - for (let i = 0; i < data.length; i += 3) { - if (i + 2 === data.length) { - r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), 0) - } else if (i + 1 === data.length) { - r += append3bytes(data.charCodeAt(i), 0, 0) - } else { - r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), data.charCodeAt(i + 2)) - } - } - return r -} - -function append3bytes (b1, b2, b3) { - let c1 = b1 >> 2 - let c2 = ((b1 & 0x3) << 4) | (b2 >> 4) - let c3 = ((b2 & 0xF) << 2) | (b3 >> 6) - let c4 = b3 & 0x3F - let r = '' - r += encode6bit(c1 & 0x3F) - r += encode6bit(c2 & 0x3F) - r += encode6bit(c3 & 0x3F) - r += encode6bit(c4 & 0x3F) - return r -} - -function encode6bit(raw) { - let b = raw - if (b < 10) { - return String.fromCharCode(48 + b) - } - b -= 10 - if (b < 26) { - return String.fromCharCode(65 + b) - } - b -= 26 - if (b < 26) { - return String.fromCharCode(97 + b) - } - b -= 26 - if (b === 0) { - return '-' - } - if (b === 1) { - return '_' - } - return '?' -} diff --git a/server/modules/rendering/markdown-supsub/definition.yml b/server/modules/rendering/markdown-supsub/definition.yml deleted file mode 100644 index ffb63b21..00000000 --- a/server/modules/rendering/markdown-supsub/definition.yml +++ /dev/null @@ -1,18 +0,0 @@ -key: markdownSupsub -title: Subscript/Superscript -description: Parse subscript and superscript tags -author: requarks.io -icon: mdi-format-superscript -enabledDefault: true -dependsOn: markdown-core -props: - subEnabled: - type: Boolean - title: Subscript - hint: Enable subscript tags - default: true - supEnabled: - type: Boolean - title: Superscript - hint: Enable superscript tags - default: true diff --git a/server/modules/rendering/markdown-supsub/renderer.js b/server/modules/rendering/markdown-supsub/renderer.js deleted file mode 100644 index be57ac1f..00000000 --- a/server/modules/rendering/markdown-supsub/renderer.js +++ /dev/null @@ -1,17 +0,0 @@ -const mdSub = require('markdown-it-sub') -const mdSup = require('markdown-it-sup') - -// ------------------------------------ -// Markdown - Subscript / Superscript -// ------------------------------------ - -module.exports = { - init (md, conf) { - if (conf.subEnabled) { - md.use(mdSub) - } - if (conf.supEnabled) { - md.use(mdSup) - } - } -} diff --git a/server/modules/rendering/markdown-tasklists/definition.yml b/server/modules/rendering/markdown-tasklists/definition.yml deleted file mode 100644 index 866ef99b..00000000 --- a/server/modules/rendering/markdown-tasklists/definition.yml +++ /dev/null @@ -1,8 +0,0 @@ -key: markdownTasklists -title: Task Lists -description: Parse task lists to checkboxes -author: requarks.io -icon: mdi-format-list-checks -enabledDefault: true -dependsOn: markdown-core -props: {} diff --git a/server/modules/rendering/markdown-tasklists/renderer.js b/server/modules/rendering/markdown-tasklists/renderer.js deleted file mode 100644 index 6950acdd..00000000 --- a/server/modules/rendering/markdown-tasklists/renderer.js +++ /dev/null @@ -1,11 +0,0 @@ -const mdTaskLists = require('markdown-it-task-lists') - -// ------------------------------------ -// Markdown - Task Lists -// ------------------------------------ - -module.exports = { - init (md, conf) { - md.use(mdTaskLists, { label: false, labelAfter: false }) - } -} diff --git a/server/modules/rendering/openapi-core/definition.yml b/server/modules/rendering/openapi-core/definition.yml deleted file mode 100644 index 557ad792..00000000 --- a/server/modules/rendering/openapi-core/definition.yml +++ /dev/null @@ -1,8 +0,0 @@ -key: openapiCore -title: Core -description: Basic OpenAPI Parser -author: requarks.io -input: openapi -output: html -icon: mdi-api -props: {} diff --git a/server/modules/rendering/openapi-core/renderer.js b/server/modules/rendering/openapi-core/renderer.js deleted file mode 100644 index 25df7eca..00000000 --- a/server/modules/rendering/openapi-core/renderer.js +++ /dev/null @@ -1,14 +0,0 @@ -const _ = require('lodash') - -module.exports = { - async render() { - let output = this.input - - for (let child of this.children) { - const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`) - output = await renderer.init(output, child.config) - } - - return output - } -} diff --git a/ux/public/_assets/icons/ultraviolet-brick.svg b/ux/public/_assets/icons/ultraviolet-brick.svg new file mode 100644 index 00000000..521e18c3 --- /dev/null +++ b/ux/public/_assets/icons/ultraviolet-brick.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ux/src/i18n/locales/en.json b/ux/src/i18n/locales/en.json index d2ae6246..472c71b9 100644 --- a/ux/src/i18n/locales/en.json +++ b/ux/src/i18n/locales/en.json @@ -449,7 +449,7 @@ "admin.navigation.visibilityMode.all": "Visible to everyone", "admin.navigation.visibilityMode.restricted": "Visible to select groups...", "admin.pages.title": "Pages", - "admin.rendering.subtitle": "Configure the page rendering pipeline", + "admin.rendering.subtitle": "Configure the content rendering pipeline", "admin.rendering.title": "Rendering", "admin.scheduler.active": "Active", "admin.scheduler.activeNone": "There are no active jobs at the moment.", diff --git a/ux/src/layouts/AdminLayout.vue b/ux/src/layouts/AdminLayout.vue index e285d608..5b43bb75 100644 --- a/ux/src/layouts/AdminLayout.vue +++ b/ux/src/layouts/AdminLayout.vue @@ -157,7 +157,7 @@ q-layout.admin(view='hHh Lpr lff') q-item-section {{ t('admin.mail.title') }} q-item-section(side) status-light(:color='adminStore.info.isMailConfigured ? `positive` : `warning`') - q-item(to='/_admin/rendering', v-ripple, active-class='bg-primary text-white', disabled, v-if='flagsStore.experimental') + q-item(to='/_admin/rendering', v-ripple, active-class='bg-primary text-white') q-item-section(avatar) q-icon(name='img:/_assets/icons/fluent-rich-text-converter.svg') q-item-section {{ t('admin.rendering.title') }} diff --git a/ux/src/pages/AdminRendering.vue b/ux/src/pages/AdminRendering.vue index b20f031b..d4e658f4 100644 --- a/ux/src/pages/AdminRendering.vue +++ b/ux/src/pages/AdminRendering.vue @@ -11,7 +11,7 @@ q-page.admin-mail icon='las la-question-circle' flat color='grey' - href='https://docs.js.wiki/admin/rendering' + :href='siteStore.docsBase + `/system/rendering`' target='_blank' type='a' ) @@ -19,7 +19,7 @@ q-page.admin-mail icon='las la-redo-alt' flat color='secondary' - :loading='loading > 0' + :loading='state.loading > 0' @click='load' ) q-btn( @@ -28,284 +28,88 @@ q-page.admin-mail :label='$t(`common.actions.apply`)' color='secondary' @click='save' - :disabled='loading > 0' + :disabled='state.loading > 0' ) q-separator(inset) - //- v-container(fluid, grid-list-lg) - //- v-layout(row, wrap) - //- v-flex(xs12) - //- .admin-header - //- img.animated.fadeInUp(src='/_assets/svg/icon-process.svg', alt='Rendering', style='width: 80px;') - //- .admin-header-title - //- .headline.primary--text.animated.fadeInLeft {{ $t('admin.rendering.title') }} - //- .subtitle-1.grey--text.animated.fadeInLeft.wait-p4s {{ $t('admin.rendering.subtitle') }} - //- v-spacer - //- v-btn.animated.fadeInDown.wait-p3s(icon, outlined, color='grey', href='https://docs.requarks.io/rendering', target='_blank') - //- v-icon mdi-help-circle - //- v-btn.mx-3.animated.fadeInDown.wait-p2s(icon, outlined, color='grey', @click='refresh') - //- v-icon mdi-refresh - //- v-btn.animated.fadeInDown(color='success', @click='save', depressed, large) - //- v-icon(left) mdi-check - //- span {{$t('common.actions.apply')}} - //- v-flex.animated.fadeInUp(lg3, xs12) - //- v-toolbar( - //- color='blue darken-2' - //- dense - //- flat - //- dark - //- ) - //- .subtitle-1 Pipeline - //- v-expansion-panels.adm-rendering-pipeline( - //- v-model='selectedCore' - //- accordion - //- mandatory - //- ) - //- v-expansion-panel( - //- v-for='core in renderers' - //- :key='core.key' - //- ) - //- v-expansion-panel-header( - //- hide-actions - //- ripple - //- ) - //- v-toolbar( - //- color='blue' - //- dense - //- dark - //- flat - //- ) - //- v-spacer - //- .body-2 {{core.input}} - //- v-icon.mx-2 mdi-arrow-right-circle - //- .caption {{core.output}} - //- v-spacer - //- v-expansion-panel-content - //- v-list.py-0(two-line, dense) - //- template(v-for='(rdr, n) in core.children') - //- v-list-item( - //- :key='rdr.key' - //- @click='selectRenderer(rdr.key)' - //- :class='currentRenderer.key === rdr.key ? ($vuetify.theme.dark ? `grey darken-4-l4` : `blue lighten-5`) : ``' - //- ) - //- v-list-item-avatar(size='24', tile) - //- v-icon(:color='currentRenderer.key === rdr.key ? "primary" : "grey"') {{rdr.icon}} - //- v-list-item-content - //- v-list-item-title {{rdr.title}} - //- v-list-item-subtitle: .caption {{rdr.description}} - //- v-list-item-avatar(size='24') - //- status-indicator(v-if='rdr.isEnabled', positive, pulse) - //- status-indicator(v-else, negative, pulse) - //- v-divider.my-0(v-if='n < core.children.length - 1') + .row.q-pa-md.q-col-gutter-md + .col-auto + q-card.rounded-borders.bg-dark + q-list( + style='min-width: 300px;' + padding + dark + ) + q-item( + v-for='rdr of state.renderers' + :key='rdr.key' + active-class='bg-primary text-white' + :active='state.selectedRenderer === rdr.id' + @click='state.selectedRenderer = rdr.id' + clickable + ) + q-item-section(side) + q-icon(:name='`img:` + rdr.icon') + q-item-section + q-item-label {{rdr.title}} + q-item-label(caption) {{rdr.description}} + q-item-section(side) + status-light(:color='rdr.isEnabled ? `positive` : `negative`', :pulse='rdr.isEnabled') + .col + .row.q-col-gutter-md + .col-12.col-lg - //- v-flex(lg9, xs12) - //- v-card.wiki-form.animated.fadeInUp - //- v-toolbar( - //- color='indigo' - //- dark - //- flat - //- dense - //- ) - //- v-icon.mr-2 {{currentRenderer.icon}} - //- .subtitle-1 {{currentRenderer.title}} - //- v-spacer - //- v-switch( - //- dark - //- color='white' - //- label='Enabled' - //- v-model='currentRenderer.isEnabled' - //- hide-details - //- inset - //- ) - //- v-card-info(color='blue') - //- div - //- div {{currentRenderer.description}} - //- span.caption: a(href='https://docs.requarks.io/en/rendering', target='_blank') Documentation - //- v-card-text.pb-4.pl-4 - //- .overline.mb-5 Rendering Module Configuration - //- .body-2.ml-3(v-if='!currentRenderer.config || currentRenderer.config.length < 1'): em This rendering module has no configuration options you can modify. - //- template(v-else, v-for='(cfg, idx) in currentRenderer.config') - //- v-select( - //- v-if='cfg.value.type === "string" && cfg.value.enum' - //- outlined - //- :items='cfg.value.enum' - //- :key='cfg.key' - //- :label='cfg.value.title' - //- v-model='cfg.value.value' - //- :hint='cfg.value.hint ? cfg.value.hint : ""' - //- persistent-hint - //- :class='cfg.value.hint ? "mb-2" : ""' - //- color='indigo' - //- ) - //- v-switch( - //- v-else-if='cfg.value.type === "boolean"' - //- :key='cfg.key' - //- :label='cfg.value.title' - //- v-model='cfg.value.value' - //- color='indigo' - //- :hint='cfg.value.hint ? cfg.value.hint : ""' - //- persistent-hint - //- inset - //- ) - //- v-text-field( - //- v-else - //- outlined - //- :key='cfg.key' - //- :label='cfg.value.title' - //- v-model='cfg.value.value' - //- :hint='cfg.value.hint ? cfg.value.hint : ""' - //- persistent-hint - //- :class='cfg.value.hint ? "mb-2" : ""' - //- color='indigo' - //- ) - //- v-divider.my-5(v-if='idx < currentRenderer.config.length - 1') - //- v-card-chin - //- v-spacer - //- .caption.pr-3.grey--text Module: {{ currentRenderer.key }} - +import { useI18n } from 'vue-i18n' +import { useMeta, useQuasar } from 'quasar' +import { computed, onMounted, reactive, watch } from 'vue' + +import { useAdminStore } from 'src/stores/admin' +import { useSiteStore } from 'src/stores/site' + +// QUASAR + +const $q = useQuasar() + +// STORES + +const adminStore = useAdminStore() +const siteStore = useSiteStore() + +// I18N + +const { t } = useI18n() - + +async function save () { + +} + + diff --git a/ux/src/router/routes.js b/ux/src/router/routes.js index 74a60f91..2048434b 100644 --- a/ux/src/router/routes.js +++ b/ux/src/router/routes.js @@ -51,7 +51,7 @@ const routes = [ { path: 'icons', component: () => import('pages/AdminIcons.vue') }, { path: 'instances', component: () => import('pages/AdminInstances.vue') }, { path: 'mail', component: () => import('pages/AdminMail.vue') }, - // { path: 'rendering', component: () => import('pages/AdminRendering.vue') }, + { path: 'rendering', component: () => import('pages/AdminRendering.vue') }, { path: 'scheduler', component: () => import('pages/AdminScheduler.vue') }, { path: 'security', component: () => import('pages/AdminSecurity.vue') }, { path: 'system', component: () => import('pages/AdminSystem.vue') },