170 lines
43 KiB
JavaScript
170 lines
43 KiB
JavaScript
|
/*
|
||
|
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
|
||
|
if you want to view the source visit the plugins github repository
|
||
|
*/
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
var obsidian = require('obsidian');
|
||
|
var state = require('@codemirror/state');
|
||
|
var view = require('@codemirror/view');
|
||
|
|
||
|
/******************************************************************************
|
||
|
Copyright (c) Microsoft Corporation.
|
||
|
|
||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||
|
purpose with or without fee is hereby granted.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||
|
PERFORMANCE OF THIS SOFTWARE.
|
||
|
***************************************************************************** */
|
||
|
|
||
|
function __awaiter(thisArg, _arguments, P, generator) {
|
||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
});
|
||
|
}
|
||
|
|
||
|
// Regular Expression for {{kanji|kana|kana|...}} format
|
||
|
const REGEXP = /{((?:[\u2E80-\uA4CF\uFF00-\uFFEF])+)((?:\\?\|[^ -\/{-~:-@\[-`]*)+)}/gm;
|
||
|
// Main Tags to search for Furigana Syntax
|
||
|
const TAGS = 'p, h1, h2, h3, h4, h5, h6, ol, ul, table';
|
||
|
const convertFurigana = (element) => {
|
||
|
const matches = Array.from(element.textContent.matchAll(REGEXP));
|
||
|
let lastNode = element;
|
||
|
for (const match of matches) {
|
||
|
const furi = match[2].split('|').slice(1); // First Element will be empty
|
||
|
const kanji = furi.length === 1 ? [match[1]] : match[1].split('');
|
||
|
if (kanji.length === furi.length) {
|
||
|
// Number of Characters in first section must be equal to number of furigana sections (unless only one furigana section)
|
||
|
const rubyNode = document.createElement('ruby');
|
||
|
rubyNode.addClass('furi');
|
||
|
kanji.forEach((k, i) => {
|
||
|
rubyNode.appendText(k);
|
||
|
rubyNode.createEl('rt', { text: furi[i] });
|
||
|
});
|
||
|
let offset = lastNode.textContent.indexOf(match[0]);
|
||
|
const nodeToReplace = lastNode.splitText(offset);
|
||
|
lastNode = nodeToReplace.splitText(match[0].length);
|
||
|
nodeToReplace.replaceWith(rubyNode);
|
||
|
}
|
||
|
}
|
||
|
return element;
|
||
|
};
|
||
|
class MarkdownFurigana extends obsidian.Plugin {
|
||
|
constructor() {
|
||
|
super(...arguments);
|
||
|
this.postprocessor = (el, ctx) => {
|
||
|
const blockToReplace = el.querySelectorAll(TAGS);
|
||
|
if (blockToReplace.length === 0)
|
||
|
return;
|
||
|
function replace(node) {
|
||
|
const childrenToReplace = [];
|
||
|
node.childNodes.forEach(child => {
|
||
|
if (child.nodeType === 3) {
|
||
|
// Nodes of Type 3 are TextElements
|
||
|
childrenToReplace.push(child);
|
||
|
}
|
||
|
else if (child.hasChildNodes() && child.nodeName !== 'CODE' && child.nodeName !== 'RUBY') {
|
||
|
// Ignore content in Code Blocks
|
||
|
replace(child);
|
||
|
}
|
||
|
});
|
||
|
childrenToReplace.forEach((child) => {
|
||
|
child.replaceWith(convertFurigana(child));
|
||
|
});
|
||
|
}
|
||
|
blockToReplace.forEach(block => {
|
||
|
replace(block);
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
onload() {
|
||
|
return __awaiter(this, void 0, void 0, function* () {
|
||
|
console.log('loading Markdown Furigana plugin');
|
||
|
this.registerMarkdownPostProcessor(this.postprocessor);
|
||
|
this.registerEditorExtension(viewPlugin);
|
||
|
});
|
||
|
}
|
||
|
onunload() {
|
||
|
console.log('unloading Markdown Furigana plugin');
|
||
|
}
|
||
|
}
|
||
|
class RubyWidget extends view.WidgetType {
|
||
|
constructor(kanji, furi) {
|
||
|
super();
|
||
|
this.kanji = kanji;
|
||
|
this.furi = furi;
|
||
|
}
|
||
|
toDOM(view) {
|
||
|
let ruby = document.createElement("ruby");
|
||
|
this.kanji.forEach((k, i) => {
|
||
|
ruby.appendText(k);
|
||
|
ruby.createEl("rt", { text: this.furi[i] });
|
||
|
});
|
||
|
return ruby;
|
||
|
}
|
||
|
}
|
||
|
const viewPlugin = view.ViewPlugin.fromClass(class {
|
||
|
constructor(view) {
|
||
|
this.decorations = this.buildDecorations(view);
|
||
|
}
|
||
|
update(update) {
|
||
|
if (update.docChanged ||
|
||
|
update.viewportChanged ||
|
||
|
update.selectionSet) {
|
||
|
this.decorations = this.buildDecorations(update.view);
|
||
|
}
|
||
|
}
|
||
|
destroy() { }
|
||
|
buildDecorations(view$1) {
|
||
|
let builder = new state.RangeSetBuilder();
|
||
|
let lines = [];
|
||
|
if (view$1.state.doc.length > 0) {
|
||
|
lines = Array.from({ length: view$1.state.doc.lines }, (_, i) => i + 1);
|
||
|
}
|
||
|
const currentSelections = [...view$1.state.selection.ranges];
|
||
|
for (let n of lines) {
|
||
|
const line = view$1.state.doc.line(n);
|
||
|
const startOfLine = line.from;
|
||
|
const endOfLine = line.to;
|
||
|
currentSelections.forEach((r) => {
|
||
|
if (r.to >= startOfLine && r.from <= endOfLine) {
|
||
|
return;
|
||
|
}
|
||
|
});
|
||
|
let matches = Array.from(line.text.matchAll(REGEXP));
|
||
|
for (const match of matches) {
|
||
|
let add = true;
|
||
|
const furi = match[2].split("|").slice(1);
|
||
|
const kanji = furi.length === 1 ? [match[1]] : match[1].split("");
|
||
|
const from = match.index != undefined ? match.index + line.from : -1;
|
||
|
const to = from + match[0].length;
|
||
|
currentSelections.forEach((r) => {
|
||
|
if (r.to >= from && r.from <= to) {
|
||
|
add = false;
|
||
|
}
|
||
|
});
|
||
|
if (add) {
|
||
|
builder.add(from, to, view.Decoration.widget({ widget: new RubyWidget(kanji, furi) }));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return builder.finish();
|
||
|
}
|
||
|
}, {
|
||
|
decorations: (v) => v.decorations,
|
||
|
});
|
||
|
|
||
|
module.exports = MarkdownFurigana;
|
||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG5Db3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi5cclxuXHJcblBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGFuZC9vciBkaXN0cmlidXRlIHRoaXMgc29mdHdhcmUgZm9yIGFueVxyXG5wdXJwb3NlIHdpdGggb3Igd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQuXHJcblxyXG5USEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiIEFORCBUSEUgQVVUSE9SIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIXHJcblJFR0FSRCBUTyBUSElTIFNPRlRXQVJFIElOQ0xVRElORyBBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWVxyXG5BTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsXHJcbklORElSRUNULCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgT1IgQU5ZIERBTUFHRVMgV0hBVFNPRVZFUiBSRVNVTFRJTkcgRlJPTVxyXG5MT1NTIE9GIFVTRSwgREFUQSBPUiBQUk9GSVRTLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUlxyXG5PVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SXHJcblBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuXHJcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovXHJcbi8qIGdsb2JhbCBSZWZsZWN0LCBQcm9taXNlICovXHJcblxyXG52YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG59O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZXh0ZW5kcyhkLCBiKSB7XHJcbiAgICBpZiAodHlwZW9mIGIgIT09IFwiZnVuY3Rpb25cIiAmJiBiICE9PSBudWxsKVxyXG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJDbGFzcyBleHRlbmRzIHZhbHVlIFwiICsgU3RyaW5nKGIpICsgXCIgaXMgbm90IGEgY29uc3RydWN0b3Igb3IgbnVsbFwiKTtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA
|