--- /dev/null
+function parseWikiLink(source) {
+ const matched = source.matchAll(/\[\[(.*)\]\]/g);
+ if (matched) {
+ return Array.from(matched).map(match => {
+ const text = match[1];
+ return {
+ text,
+ url: encodeURI(`/note/${text}`),
+ range: [match.index, match.index + match[0].length - 1]
+ }
+ });
+ }
+
+ return null;
+}
+
+export function extendedAutolinks(source) {
+ return [...parseUrlLink(source), ...parseEmailLink(source), ...parseWikiLink(source)].sort(
+ (a, b) => a.range[0] - b.range[0]
+ );
+}
+
+/*
+ * Sourced from toast-ui. There autolink options are
+ * either override their built in functionality or
+ * use their built in functionality. We'd like to have
+ * both so this is the source of their parsers.
+*/
+const DOMAIN = '(?:[w-]+.)*[A-Za-z0-9-]+.[A-Za-z0-9-]+';
+const PATH = '[^<\\s]*[^<?!.,:*_?~\\s]';
+const EMAIL = '[\\w.+-]+@(?:[\\w-]+\\.)+[\\w-]+';
+function trimUnmatchedTrailingParens(source) {
+ const trailingParen = /\)+$/.exec(source);
+ if (trailingParen) {
+ let count = 0;
+ for (const ch of source) {
+ if (ch === '(') {
+ if (count < 0) {
+ count = 1;
+ } else {
+ count += 1;
+ }
+ } else if (ch === ')') {
+ count -= 1;
+ }
+ }
+
+ if (count < 0) {
+ const trimCount = Math.min(-count, trailingParen[0].length);
+ return source.substring(0, source.length - trimCount);
+ }
+ }
+ return source;
+}
+
+function trimTrailingEntity(source) {
+ return source.replace(/&[A-Za-z0-9]+;$/, '');
+}
+export function parseEmailLink(source) {
+ const reEmailLink = new RegExp(EMAIL, 'g');
+ const result = [];
+ let m;
+ while ((m = reEmailLink.exec(source))) {
+ const text = m[0];
+ if (!/[_-]+$/.test(text)) {
+ result.push({
+ text,
+ range: [m.index, m.index + text.length - 1],
+ url: `mailto:${text}`,
+ });
+ }
+ }
+
+ return result;
+}
+
+export function parseUrlLink(source) {
+ const reWwwAutolink = new RegExp(`(www|https?://)\.${DOMAIN}${PATH}`, 'g');
+ const result = [];
+ let m;
+
+ while ((m = reWwwAutolink.exec(source))) {
+ const text = trimTrailingEntity(trimUnmatchedTrailingParens(m[0]));
+ const scheme = m[1] === 'www' ? 'http://' : '';
+ result.push({
+ text,
+ range: [m.index, m.index + text.length - 1],
+ url: `${scheme}${text}`,
+ });
+ }
+
+ return result;
+}
+// end of raw toast-ui source
import { Viewer } from "@toast-ui/vue-editor";
import api from "../api";
import codeSyntaxHighlight from "@toast-ui/editor-plugin-code-syntax-highlight/dist/toastui-editor-plugin-code-syntax-highlight-all.js";
+import { extendedAutolinks } from '../autolinkParsers';
const reservedFilenameCharacters = /[<>:"/\\|?*]/;
viewerOptions: {
customHTMLRenderer: customHTMLRenderer,
plugins: [codeSyntaxHighlight],
- extendedAutolinks: true,
+ extendedAutolinks,
},
editorOptions: {
customHTMLRenderer: customHTMLRenderer,