Improve links and checkboxes
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Use the markdown parser to handle links and checkboxes instead of internal javascript. Also add catch clauses to the promises in the editor.
This commit is contained in:
parent
a2c83d87b6
commit
70f1b62646
|
@ -59,7 +59,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node_modules/.bin/mocha -r esm",
|
"test": "node_modules/.bin/mocha -r esm",
|
||||||
"watch": "webpack --watch",
|
"watch": "webpack --watch --mode=development",
|
||||||
"start": "webpack-dev-server --open --hot",
|
"start": "webpack-dev-server --open --hot",
|
||||||
"build": "webpack --progress --mode=production",
|
"build": "webpack --progress --mode=production",
|
||||||
"docker": "webpack --no-color --mode=production"
|
"docker": "webpack --no-color --mode=production"
|
||||||
|
|
|
@ -152,7 +152,7 @@ function showSearchResultsExtended(element, template, searchTool, query, input,
|
||||||
}
|
}
|
||||||
|
|
||||||
return results
|
return results
|
||||||
})
|
}).catch(e => console.log('searchtool', e))
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatLineResult(hits, key) {
|
function formatLineResult(hits, key) {
|
||||||
|
@ -284,7 +284,7 @@ function Editor(holder, input) {
|
||||||
return td
|
return td
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
})
|
}).catch(e => console.log('while fetching metakv', e))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then(mflatten)
|
.then(mflatten)
|
||||||
|
@ -313,8 +313,9 @@ function Editor(holder, input) {
|
||||||
div.classList.add('table-wrapper')
|
div.classList.add('table-wrapper')
|
||||||
|
|
||||||
return element.html(div);
|
return element.html(div);
|
||||||
})
|
}).catch(e => console.log('while creating table', e))
|
||||||
})
|
})
|
||||||
|
.catch(e => console.log('transformTable', e))
|
||||||
}
|
}
|
||||||
|
|
||||||
async function transformMathExpression(converted, scope) {
|
async function transformMathExpression(converted, scope) {
|
||||||
|
@ -350,7 +351,6 @@ function Editor(holder, input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let converted = text
|
let converted = text
|
||||||
let todo;
|
|
||||||
|
|
||||||
if (converted === '{{table}}') {
|
if (converted === '{{table}}') {
|
||||||
transformTable.call(this, editor, id, element);
|
transformTable.call(this, editor, id, element);
|
||||||
|
@ -368,30 +368,37 @@ function Editor(holder, input) {
|
||||||
})
|
})
|
||||||
.catch(e => console.warn(e))
|
.catch(e => console.warn(e))
|
||||||
} else {
|
} else {
|
||||||
let re = /^([A-Z0-9 ]+)::\s*(.*)$/i;
|
// let re = /^([A-Z0-9 ]+)::\s*(.*)$/i;
|
||||||
let res = text.match(re)
|
// let res = text.match(re)
|
||||||
if (res) {
|
// if (res) {
|
||||||
converted = '<span class="metadata-key">[[' + res[1] + ']]</span>'
|
// converted = '<span class="metadata-key">[[' + res[1] + ']]</span>'
|
||||||
if (res[2]) {
|
// if (res[2]) {
|
||||||
converted += ': ' + res[2]
|
// converted += ': ' + res[2]
|
||||||
}
|
// }
|
||||||
} else if (text.match(/#\[\[TODO]]/)) {
|
// } else if (text.match(/#\[\[TODO]]/)) {
|
||||||
converted = converted.replace('#[[TODO]]', '<input class="checkbox" type="checkbox" />')
|
// converted = converted.replace('#[[TODO]]', '<input class="checkbox" type="checkbox" />')
|
||||||
todo = true;
|
// todo = true;
|
||||||
} else if (text.match(/#\[\[DONE]]/)) {
|
// } else if (text.match(/#\[\[DONE]]/)) {
|
||||||
converted = converted.replace('#[[DONE]]', '<input class="checkbox" type="checkbox" checked />')
|
// converted = converted.replace('#[[DONE]]', '<input class="checkbox" type="checkbox" checked />')
|
||||||
todo = false;
|
// todo = false;
|
||||||
}
|
// }
|
||||||
MD.options.html = true
|
MD.options.html = true
|
||||||
converted = MD.renderInline(converted)
|
converted = MD.renderInline(converted)
|
||||||
MD.options.html = false
|
MD.options.html = false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (todo !== undefined) {
|
try {
|
||||||
element.toggleClass('todo--done', todo === false)
|
const todoItem = $(converted).find(':checkbox')
|
||||||
element.toggleClass('todo--todo', todo === true)
|
if (todoItem.length) {
|
||||||
} else {
|
const todo = !todoItem.is(':checked')
|
||||||
element.removeClass(['todo--todo', 'todo--done'])
|
element.toggleClass('todo--done', todo === false)
|
||||||
|
element.toggleClass('todo--todo', todo === true)
|
||||||
|
} else {
|
||||||
|
element.removeClass(['todo--todo', 'todo--done'])
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// problem with $(converted) is that it could be treated as a jQuery selector expression instead of normal text
|
||||||
|
// the wiki text is not quite like selectors
|
||||||
}
|
}
|
||||||
|
|
||||||
element.html(converted)
|
element.html(converted)
|
||||||
|
@ -436,7 +443,9 @@ function Editor(holder, input) {
|
||||||
addIndicator(
|
addIndicator(
|
||||||
addSaver(editor, saveUrl, page, beforeSave),
|
addSaver(editor, saveUrl, page, beforeSave),
|
||||||
indicator
|
indicator
|
||||||
).save().then(() => indicator.done())
|
).save()
|
||||||
|
.then(() => indicator.done())
|
||||||
|
.catch(e => console.log('editor.change', e))
|
||||||
})
|
})
|
||||||
|
|
||||||
// editor.on('rendered', function () {
|
// editor.on('rendered', function () {
|
||||||
|
@ -612,11 +621,12 @@ function Editor(holder, input) {
|
||||||
|
|
||||||
if (insideSearch) {
|
if (insideSearch) {
|
||||||
let query = value.substring(start + 1, end);
|
let query = value.substring(start + 1, end);
|
||||||
showSearchResults(commandSearch, query, input, value, 'command').then(results => {
|
showSearchResults(commandSearch, query, input, value, 'command')
|
||||||
if (query.length > 0 && (!results || results.length === 0)) {
|
.then(results => {
|
||||||
searchEnabled = false
|
if (query.length > 0 && (!results || results.length === 0)) {
|
||||||
}
|
searchEnabled = false
|
||||||
})
|
}
|
||||||
|
}).catch(e => console.log('showSearchResults', e))
|
||||||
return true
|
return true
|
||||||
} else if (insideLink) {
|
} else if (insideLink) {
|
||||||
let query = value.substring(start, end);
|
let query = value.substring(start, end);
|
||||||
|
@ -645,15 +655,17 @@ function Editor(holder, input) {
|
||||||
return search.startQuery(res[2])
|
return search.startQuery(res[2])
|
||||||
.then(hits => _.uniqBy(_.flatMap(hits, formatTitleResult), _.property('text')))
|
.then(hits => _.uniqBy(_.flatMap(hits, formatTitleResult), _.property('text')))
|
||||||
.then(results => editor.replaceChildren(id, results))
|
.then(results => editor.replaceChildren(id, results))
|
||||||
|
.catch(e => console.log('search query', e))
|
||||||
.finally(() => editor.render())
|
.finally(() => editor.render())
|
||||||
} else {
|
} else {
|
||||||
return search.startQuery(res[2])
|
return search.startQuery(res[2])
|
||||||
.then(hits => _.groupBy(hits, (it) => it.title))
|
.then(hits => _.groupBy(hits, (it) => it.title))
|
||||||
.then(hits => _.flatMap(hits, formatLineResult))
|
.then(hits => _.flatMap(hits, formatLineResult))
|
||||||
.then(results => editor.replaceChildren(id, results))
|
.then(results => editor.replaceChildren(id, results))
|
||||||
|
.catch(e => console.log('search query', e))
|
||||||
.finally(() => editor.render())
|
.finally(() => editor.render())
|
||||||
}
|
}
|
||||||
})
|
}).catch(e => {})
|
||||||
});
|
});
|
||||||
return editor
|
return editor
|
||||||
})
|
})
|
||||||
|
@ -663,7 +675,7 @@ function match(s, re) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let res = s.match(re)
|
let res = s.match(re)
|
||||||
if (res) resolve(res)
|
if (res) resolve(res)
|
||||||
else reject()
|
else reject(s + ' did not match ' + re)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import MarkdownIt from "markdown-it";
|
import MarkdownIt from "markdown-it";
|
||||||
import MarkdownItWikilinks from "./wikilinks";
|
//import MarkdownItWikilinks from "./wikilinks";
|
||||||
|
import MarkdownItWikilinks2 from "./wikilinks2";
|
||||||
import MarkdownItMark from "markdown-it-mark";
|
import MarkdownItMark from "markdown-it-mark";
|
||||||
import MarkdownItKatex from "markdown-it-katex";
|
import MarkdownItKatex from "markdown-it-katex";
|
||||||
|
|
||||||
const MD = new MarkdownIt({
|
const MD = new MarkdownIt({
|
||||||
linkify: true,
|
linkify: false,
|
||||||
highlight: function (str, lang) {
|
highlight: function (str, lang) {
|
||||||
if (lang === 'mermaid') {
|
if (lang === 'mermaid') {
|
||||||
return '<div class="mermaid">' + str + '</div>';
|
return '<div class="mermaid">' + str + '</div>';
|
||||||
|
@ -12,14 +13,22 @@ const MD = new MarkdownIt({
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
MD.use(MarkdownItWikilinks2({
|
||||||
MD.use(MarkdownItWikilinks({
|
|
||||||
baseURL: document.querySelector('body').dataset.baseUrl,
|
baseURL: document.querySelector('body').dataset.baseUrl,
|
||||||
uriSuffix: '',
|
uriSuffix: '',
|
||||||
relativeBaseURL: '/edit/',
|
relativeBaseURL: '/edit/',
|
||||||
htmlAttributes: {
|
htmlAttributes: {
|
||||||
class: 'wiki-link'
|
class: 'wiki-link'
|
||||||
},
|
},
|
||||||
})).use(MarkdownItMark).use(MarkdownItKatex)
|
}))
|
||||||
|
// MD.use(MarkdownItWikilinks({
|
||||||
|
// baseURL: document.querySelector('body').dataset.baseUrl,
|
||||||
|
// uriSuffix: '',
|
||||||
|
// relativeBaseURL: '/edit/',
|
||||||
|
// htmlAttributes: {
|
||||||
|
// class: 'wiki-link'
|
||||||
|
// },
|
||||||
|
// }))
|
||||||
|
// MD.use(MarkdownItMark).use(MarkdownItKatex)
|
||||||
|
|
||||||
export default MD;
|
export default MD;
|
||||||
|
|
|
@ -2,7 +2,26 @@
|
||||||
|
|
||||||
import Plugin from "markdown-it-regexp";
|
import Plugin from "markdown-it-regexp";
|
||||||
import extend from "extend";
|
import extend from "extend";
|
||||||
import sanitize from "sanitize-filename";
|
|
||||||
|
var illegalRe = /[\/\?<>\\\*\|"]/g;
|
||||||
|
var controlRe = /[\x00-\x1f\x80-\x9f]/g;
|
||||||
|
var reservedRe = /^\.+$/;
|
||||||
|
var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i;
|
||||||
|
var windowsTrailingRe = /[\. ]+$/;
|
||||||
|
|
||||||
|
function sanitize(input) {
|
||||||
|
const replacement = '';
|
||||||
|
if (typeof input !== 'string') {
|
||||||
|
throw new Error('Input must be string');
|
||||||
|
}
|
||||||
|
var sanitized = input
|
||||||
|
.replace(illegalRe, replacement)
|
||||||
|
.replace(controlRe, replacement)
|
||||||
|
.replace(reservedRe, replacement)
|
||||||
|
.replace(windowsReservedRe, replacement)
|
||||||
|
.replace(windowsTrailingRe, replacement);
|
||||||
|
return sanitized;
|
||||||
|
}
|
||||||
|
|
||||||
export default (options) => {
|
export default (options) => {
|
||||||
const defaults = {
|
const defaults = {
|
||||||
|
@ -17,7 +36,7 @@ export default (options) => {
|
||||||
},
|
},
|
||||||
postProcessPageName: (pageName) => {
|
postProcessPageName: (pageName) => {
|
||||||
pageName = pageName.trim()
|
pageName = pageName.trim()
|
||||||
pageName = pageName.split('/').map(sanitize).join('/')
|
pageName = pageName.split('/').map(sanitize).map(sanitize).join('/')
|
||||||
pageName = pageName.replace(/\s+/g, '_')
|
pageName = pageName.replace(/\s+/g, '_')
|
||||||
return pageName
|
return pageName
|
||||||
},
|
},
|
||||||
|
|
75
editor/src/wikilinks2.js
Normal file
75
editor/src/wikilinks2.js
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
var util = require('util')
|
||||||
|
|
||||||
|
function Plugin(options) {
|
||||||
|
var self = function (md) {
|
||||||
|
self.options = options
|
||||||
|
self.init(md)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.__proto__ = Plugin.prototype
|
||||||
|
self.id = 'wikilinks'
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
util.inherits(Plugin, Function)
|
||||||
|
|
||||||
|
Plugin.prototype.init = function (md) {
|
||||||
|
md.inline.ruler.push(this.id, this.parse.bind(this))
|
||||||
|
md.renderer.rules[this.id] = this.render.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function linkParser(id, state) {
|
||||||
|
let input = state.src.slice(state.pos);
|
||||||
|
const match = /^#?\[\[/.exec(input)
|
||||||
|
if (!match) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let prefixLength = match[0].length
|
||||||
|
let p = state.pos + prefixLength
|
||||||
|
let open = 2
|
||||||
|
while (p < state.src.length - 1 && open > 0) {
|
||||||
|
if (state.src[p] === '[' && state.src[p + 1] === '[') {
|
||||||
|
open += 2
|
||||||
|
p += 2
|
||||||
|
} else if (state.src[p] === ']' && state.src[p + 1] === ']') {
|
||||||
|
open -= 2
|
||||||
|
p += 2
|
||||||
|
} else {
|
||||||
|
p++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (open === 0) {
|
||||||
|
let link = state.src.slice(state.pos + prefixLength, p - 2)
|
||||||
|
let token = state.push(id, '', 0)
|
||||||
|
token.meta = {match: link, tag: prefixLength === 3}
|
||||||
|
state.pos = p
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
Plugin.prototype.parse = function (state, silent) {
|
||||||
|
return linkParser(this.id, state)
|
||||||
|
}
|
||||||
|
|
||||||
|
Plugin.prototype.render = function (tokens, id, options, env) {
|
||||||
|
let {match: link, tag} = tokens[id].meta
|
||||||
|
if (tag) {
|
||||||
|
if (link === 'TODO') {
|
||||||
|
return '<input type="checkbox" class="checkbox">';
|
||||||
|
} else if (link === 'DONE') {
|
||||||
|
return '<input type="checkbox" class="checkbox" checked>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '<a href="/' + link.replace(' ', '_') + '" class="wiki-link">' + link + '</a>';
|
||||||
|
}
|
||||||
|
|
||||||
|
export default (options) => {
|
||||||
|
return Plugin(options);
|
||||||
|
}
|
62
editor/test/markdown.test.js
Normal file
62
editor/test/markdown.test.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* Wiki - A wiki with editor
|
||||||
|
* Copyright (c) 2021 Peter Stuifzand
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
import MarkdownIt from "markdown-it";
|
||||||
|
import MarkdownItWikilinks2 from "../src/wikilinks2";
|
||||||
|
|
||||||
|
const MD = new MarkdownIt({
|
||||||
|
linkify: false,
|
||||||
|
highlight: function (str, lang) {
|
||||||
|
if (lang === 'mermaid') {
|
||||||
|
return '<div class="mermaid">' + str + '</div>';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
MD.use(MarkdownItWikilinks2({
|
||||||
|
baseURL: 'http://localhost/',
|
||||||
|
uriSuffix: '',
|
||||||
|
relativeBaseURL: '/edit/',
|
||||||
|
htmlAttributes: {
|
||||||
|
class: 'wiki-link'
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('MD', function () {
|
||||||
|
it('parseLinks', function () {
|
||||||
|
assert.deepStrictEqual(MD.renderInline("#[[TODO]]"), '<input type="checkbox" class="checkbox">')
|
||||||
|
assert.deepStrictEqual(MD.renderInline("#[[TODO]] #[[DONE]]"), '<input type="checkbox" class="checkbox"> <input type="checkbox" class="checkbox" checked>')
|
||||||
|
})
|
||||||
|
it('parseLinks 2', function () {
|
||||||
|
assert.deepStrictEqual(MD.renderInline("#[[TODO]] #[[DONE]]"), '<input type="checkbox" class="checkbox"> <input type="checkbox" class="checkbox" checked>')
|
||||||
|
})
|
||||||
|
it('parseLinks 3', function () {
|
||||||
|
assert.deepStrictEqual(MD.renderInline("test #[[TODO]] test2"), 'test <input type="checkbox" class="checkbox"> test2')
|
||||||
|
})
|
||||||
|
it('parseLinks 4', function () {
|
||||||
|
assert.deepStrictEqual(MD.renderInline("test [[test]] [[test2]] [[test3]]"), 'test <a href="/test" class="wiki-link">test</a> <a href="/test2" class="wiki-link">test2</a> <a href="/test3" class="wiki-link">test3</a>')
|
||||||
|
})
|
||||||
|
it('parseLinks 5', function () {
|
||||||
|
assert.deepStrictEqual(MD.renderInline("test [[test]]"), 'test <a href="/test" class="wiki-link">test</a>')
|
||||||
|
})
|
||||||
|
it('parseLinks 6', function () {
|
||||||
|
assert.deepStrictEqual(MD.renderInline("test [[test]] [[test2]]"), 'test <a href="/test" class="wiki-link">test</a> <a href="/test2" class="wiki-link">test2</a>')
|
||||||
|
})
|
||||||
|
})
|
117
editor/test/wikilinks2.test.js
Normal file
117
editor/test/wikilinks2.test.js
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* Wiki - A wiki with editor
|
||||||
|
* Copyright (c) 2021 Peter Stuifzand
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import assert from 'assert'
|
||||||
|
import {linkParser} from '../src/wikilinks2'
|
||||||
|
|
||||||
|
describe('linkParser', function () {
|
||||||
|
it('parse', function () {
|
||||||
|
let state = {src: '', pos: 0, tokens: []};
|
||||||
|
state.__proto__.push = function (id, s, x) {
|
||||||
|
let token = {id, s, x};
|
||||||
|
this.tokens.push(token)
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
assert.deepStrictEqual(linkParser('test', state), false);
|
||||||
|
assert.deepStrictEqual(state, {
|
||||||
|
src: '',
|
||||||
|
pos: 0,
|
||||||
|
tokens: []
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parse 2', function () {
|
||||||
|
let state = {src: '[[Link]]', pos: 0, tokens: []};
|
||||||
|
state.__proto__.push = function (id, s, x) {
|
||||||
|
let token = {id, s, x};
|
||||||
|
this.tokens.push(token)
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
assert.deepStrictEqual(linkParser('test', state), true);
|
||||||
|
assert.deepStrictEqual(state, {
|
||||||
|
src: '[[Link]]',
|
||||||
|
pos: 8,
|
||||||
|
tokens: [{
|
||||||
|
id: 'test',
|
||||||
|
s: '',
|
||||||
|
x: 0,
|
||||||
|
meta: {match:'Link', tag: false}
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parse 3', function () {
|
||||||
|
let state = {src: '1234[[Link]]', pos: 4, tokens: []};
|
||||||
|
state.__proto__.push = function (id, s, x) {
|
||||||
|
let token = {id, s, x};
|
||||||
|
this.tokens.push(token)
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
assert.deepStrictEqual(linkParser('test', state), true);
|
||||||
|
assert.deepStrictEqual(state, {
|
||||||
|
src: '1234[[Link]]',
|
||||||
|
pos: 12,
|
||||||
|
tokens: [{
|
||||||
|
id: 'test',
|
||||||
|
s: '',
|
||||||
|
x: 0,
|
||||||
|
meta: {match:'Link', tag: false}
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parse 4', function () {
|
||||||
|
let state = {src: '1234#[[TODO]]', pos: 4, tokens: []};
|
||||||
|
state.__proto__.push = function (id, s, x) {
|
||||||
|
let token = {id, s, x};
|
||||||
|
this.tokens.push(token)
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
assert.deepStrictEqual(linkParser('test', state), true);
|
||||||
|
assert.deepStrictEqual(state, {
|
||||||
|
src: '1234#[[TODO]]',
|
||||||
|
pos: 13,
|
||||||
|
tokens: [{
|
||||||
|
id: 'test',
|
||||||
|
s: '',
|
||||||
|
x: 0,
|
||||||
|
meta: {match:'TODO', tag: true}
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parse text and two links', function () {
|
||||||
|
let state = {src: '1234 [[Link]] [[Link2]]', pos: 5, tokens: []};
|
||||||
|
state.__proto__.push = function (id, s, x) {
|
||||||
|
let token = {id, s, x};
|
||||||
|
this.tokens.push(token)
|
||||||
|
return token
|
||||||
|
}
|
||||||
|
assert.deepStrictEqual(linkParser('test', state), true);
|
||||||
|
assert.deepStrictEqual(state, {
|
||||||
|
src: '1234 [[Link]] [[Link2]]',
|
||||||
|
pos: 13,
|
||||||
|
tokens: [{
|
||||||
|
id: 'test',
|
||||||
|
s: '',
|
||||||
|
x: 0,
|
||||||
|
meta: {match:'Link', tag: false}
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user