diff --git a/.obsidian/community-plugins.json b/.obsidian/community-plugins.json
index ce05972..adce6f0 100644
--- a/.obsidian/community-plugins.json
+++ b/.obsidian/community-plugins.json
@@ -25,5 +25,5 @@
"digitalgarden",
"pdf-plus",
"obsidian-tracker",
- "copy-as-html"
+ "copy-document-as-html"
]
\ No newline at end of file
diff --git a/.obsidian/hotkeys.json b/.obsidian/hotkeys.json
index e62b0e2..16ccbb6 100644
--- a/.obsidian/hotkeys.json
+++ b/.obsidian/hotkeys.json
@@ -59,5 +59,14 @@
],
"key": "C"
}
+ ],
+ "copy-document-as-html:copy-selection-as-html": [
+ {
+ "modifiers": [
+ "Mod",
+ "Shift"
+ ],
+ "key": "C"
+ }
]
}
\ No newline at end of file
diff --git a/.obsidian/plugins/copy-as-html/main.js b/.obsidian/plugins/copy-as-html/main.js
deleted file mode 100644
index 4c1c48f..0000000
--- a/.obsidian/plugins/copy-as-html/main.js
+++ /dev/null
@@ -1,3747 +0,0 @@
-/*
-THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
-if you want to view the source, please visit the github repository of this plugin
-*/
-
-var __create = Object.create;
-var __defProp = Object.defineProperty;
-var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
-var __getOwnPropNames = Object.getOwnPropertyNames;
-var __getProtoOf = Object.getPrototypeOf;
-var __hasOwnProp = Object.prototype.hasOwnProperty;
-var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
-var __commonJS = (cb, mod) => function __require() {
- return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
-};
-var __export = (target, all) => {
- __markAsModule(target);
- for (var name in all)
- __defProp(target, name, { get: all[name], enumerable: true });
-};
-var __reExport = (target, module2, desc) => {
- if (module2 && typeof module2 === "object" || typeof module2 === "function") {
- for (let key of __getOwnPropNames(module2))
- if (!__hasOwnProp.call(target, key) && key !== "default")
- __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
- }
- return target;
-};
-var __toModule = (module2) => {
- return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
-};
-var __async = (__this, __arguments, generator) => {
- return new Promise((resolve, reject) => {
- var fulfilled = (value) => {
- try {
- step(generator.next(value));
- } catch (e) {
- reject(e);
- }
- };
- var rejected = (value) => {
- try {
- step(generator.throw(value));
- } catch (e) {
- reject(e);
- }
- };
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
- step((generator = generator.apply(__this, __arguments)).next());
- });
-};
-
-// node_modules/showdown/dist/showdown.js
-var require_showdown = __commonJS({
- "node_modules/showdown/dist/showdown.js"(exports, module2) {
- (function() {
- function getDefaultOpts(simple) {
- "use strict";
- var defaultOptions = {
- omitExtraWLInCodeBlocks: {
- defaultValue: false,
- describe: "Omit the default extra whiteline added to code blocks",
- type: "boolean"
- },
- noHeaderId: {
- defaultValue: false,
- describe: "Turn on/off generated header id",
- type: "boolean"
- },
- prefixHeaderId: {
- defaultValue: false,
- describe: "Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic 'section-' prefix",
- type: "string"
- },
- rawPrefixHeaderId: {
- defaultValue: false,
- describe: 'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',
- type: "boolean"
- },
- ghCompatibleHeaderId: {
- defaultValue: false,
- describe: "Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)",
- type: "boolean"
- },
- rawHeaderId: {
- defaultValue: false,
- describe: `Remove only spaces, ' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids`,
- type: "boolean"
- },
- headerLevelStart: {
- defaultValue: false,
- describe: "The header blocks level start",
- type: "integer"
- },
- parseImgDimensions: {
- defaultValue: false,
- describe: "Turn on/off image dimension parsing",
- type: "boolean"
- },
- simplifiedAutoLink: {
- defaultValue: false,
- describe: "Turn on/off GFM autolink style",
- type: "boolean"
- },
- excludeTrailingPunctuationFromURLs: {
- defaultValue: false,
- describe: "Excludes trailing punctuation from links generated with autoLinking",
- type: "boolean"
- },
- literalMidWordUnderscores: {
- defaultValue: false,
- describe: "Parse midword underscores as literal underscores",
- type: "boolean"
- },
- literalMidWordAsterisks: {
- defaultValue: false,
- describe: "Parse midword asterisks as literal asterisks",
- type: "boolean"
- },
- strikethrough: {
- defaultValue: false,
- describe: "Turn on/off strikethrough support",
- type: "boolean"
- },
- tables: {
- defaultValue: false,
- describe: "Turn on/off tables support",
- type: "boolean"
- },
- tablesHeaderId: {
- defaultValue: false,
- describe: "Add an id to table headers",
- type: "boolean"
- },
- ghCodeBlocks: {
- defaultValue: true,
- describe: "Turn on/off GFM fenced code blocks support",
- type: "boolean"
- },
- tasklists: {
- defaultValue: false,
- describe: "Turn on/off GFM tasklist support",
- type: "boolean"
- },
- smoothLivePreview: {
- defaultValue: false,
- describe: "Prevents weird effects in live previews due to incomplete input",
- type: "boolean"
- },
- smartIndentationFix: {
- defaultValue: false,
- describe: "Tries to smartly fix indentation in es6 strings",
- type: "boolean"
- },
- disableForced4SpacesIndentedSublists: {
- defaultValue: false,
- describe: "Disables the requirement of indenting nested sublists by 4 spaces",
- type: "boolean"
- },
- simpleLineBreaks: {
- defaultValue: false,
- describe: "Parses simple line breaks as
(GFM Style)",
- type: "boolean"
- },
- requireSpaceBeforeHeadingText: {
- defaultValue: false,
- describe: "Makes adding a space between `#` and the header text mandatory (GFM Style)",
- type: "boolean"
- },
- ghMentions: {
- defaultValue: false,
- describe: "Enables github @mentions",
- type: "boolean"
- },
- ghMentionsLink: {
- defaultValue: "https://github.com/{u}",
- describe: "Changes the link generated by @mentions. Only applies if ghMentions option is enabled.",
- type: "string"
- },
- encodeEmails: {
- defaultValue: true,
- describe: "Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities",
- type: "boolean"
- },
- openLinksInNewWindow: {
- defaultValue: false,
- describe: "Open all links in new windows",
- type: "boolean"
- },
- backslashEscapesHTMLTags: {
- defaultValue: false,
- describe: "Support for HTML Tag escaping. ex:
[^\r]+?<\/pre>)/gm, function(wholeMatch, m1) {
- var pre = m1;
- pre = pre.replace(/^ /mg, "\xA80");
- pre = pre.replace(/¨0/g, "");
- return pre;
- });
- return showdown2.subParser("hashBlock")("\n" + bq + "\n
", options, globals);
- });
- text = globals.converter._dispatch("blockQuotes.after", text, options, globals);
- return text;
- });
- showdown2.subParser("codeBlocks", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("codeBlocks.before", text, options, globals);
- text += "\xA80";
- var pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;
- text = text.replace(pattern, function(wholeMatch, m1, m2) {
- var codeblock = m1, nextChar = m2, end = "\n";
- codeblock = showdown2.subParser("outdent")(codeblock, options, globals);
- codeblock = showdown2.subParser("encodeCode")(codeblock, options, globals);
- codeblock = showdown2.subParser("detab")(codeblock, options, globals);
- codeblock = codeblock.replace(/^\n+/g, "");
- codeblock = codeblock.replace(/\n+$/g, "");
- if (options.omitExtraWLInCodeBlocks) {
- end = "";
- }
- codeblock = "" + codeblock + end + "
";
- return showdown2.subParser("hashBlock")(codeblock, options, globals) + nextChar;
- });
- text = text.replace(/¨0/, "");
- text = globals.converter._dispatch("codeBlocks.after", text, options, globals);
- return text;
- });
- showdown2.subParser("codeSpans", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("codeSpans.before", text, options, globals);
- if (typeof text === "undefined") {
- text = "";
- }
- text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm, function(wholeMatch, m1, m2, m3) {
- var c = m3;
- c = c.replace(/^([ \t]*)/g, "");
- c = c.replace(/[ \t]*$/g, "");
- c = showdown2.subParser("encodeCode")(c, options, globals);
- c = m1 + "" + c + "";
- c = showdown2.subParser("hashHTMLSpans")(c, options, globals);
- return c;
- });
- text = globals.converter._dispatch("codeSpans.after", text, options, globals);
- return text;
- });
- showdown2.subParser("completeHTMLDocument", function(text, options, globals) {
- "use strict";
- if (!options.completeHTMLDocument) {
- return text;
- }
- text = globals.converter._dispatch("completeHTMLDocument.before", text, options, globals);
- var doctype = "html", doctypeParsed = "\n", title = "", charset = '\n', lang = "", metadata = "";
- if (typeof globals.metadata.parsed.doctype !== "undefined") {
- doctypeParsed = "\n";
- doctype = globals.metadata.parsed.doctype.toString().toLowerCase();
- if (doctype === "html" || doctype === "html5") {
- charset = '';
- }
- }
- for (var meta in globals.metadata.parsed) {
- if (globals.metadata.parsed.hasOwnProperty(meta)) {
- switch (meta.toLowerCase()) {
- case "doctype":
- break;
- case "title":
- title = "" + globals.metadata.parsed.title + " \n";
- break;
- case "charset":
- if (doctype === "html" || doctype === "html5") {
- charset = '\n';
- } else {
- charset = '\n';
- }
- break;
- case "language":
- case "lang":
- lang = ' lang="' + globals.metadata.parsed[meta] + '"';
- metadata += '\n';
- break;
- default:
- metadata += '\n';
- }
- }
- }
- text = doctypeParsed + "\n\n" + title + charset + metadata + "\n\n" + text.trim() + "\n\n";
- text = globals.converter._dispatch("completeHTMLDocument.after", text, options, globals);
- return text;
- });
- showdown2.subParser("detab", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("detab.before", text, options, globals);
- text = text.replace(/\t(?=\t)/g, " ");
- text = text.replace(/\t/g, "\xA8A\xA8B");
- text = text.replace(/¨B(.+?)¨A/g, function(wholeMatch, m1) {
- var leadingText = m1, numSpaces = 4 - leadingText.length % 4;
- for (var i = 0; i < numSpaces; i++) {
- leadingText += " ";
- }
- return leadingText;
- });
- text = text.replace(/¨A/g, " ");
- text = text.replace(/¨B/g, "");
- text = globals.converter._dispatch("detab.after", text, options, globals);
- return text;
- });
- showdown2.subParser("ellipsis", function(text, options, globals) {
- "use strict";
- if (!options.ellipsis) {
- return text;
- }
- text = globals.converter._dispatch("ellipsis.before", text, options, globals);
- text = text.replace(/\.\.\./g, "\u2026");
- text = globals.converter._dispatch("ellipsis.after", text, options, globals);
- return text;
- });
- showdown2.subParser("emoji", function(text, options, globals) {
- "use strict";
- if (!options.emoji) {
- return text;
- }
- text = globals.converter._dispatch("emoji.before", text, options, globals);
- var emojiRgx = /:([\S]+?):/g;
- text = text.replace(emojiRgx, function(wm, emojiCode) {
- if (showdown2.helper.emojis.hasOwnProperty(emojiCode)) {
- return showdown2.helper.emojis[emojiCode];
- }
- return wm;
- });
- text = globals.converter._dispatch("emoji.after", text, options, globals);
- return text;
- });
- showdown2.subParser("encodeAmpsAndAngles", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("encodeAmpsAndAngles.before", text, options, globals);
- text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g, "&");
- text = text.replace(/<(?![a-z\/?$!])/gi, "<");
- text = text.replace(//g, ">");
- text = globals.converter._dispatch("encodeAmpsAndAngles.after", text, options, globals);
- return text;
- });
- showdown2.subParser("encodeBackslashEscapes", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("encodeBackslashEscapes.before", text, options, globals);
- text = text.replace(/\\(\\)/g, showdown2.helper.escapeCharactersCallback);
- text = text.replace(/\\([`*_{}\[\]()>#+.!~=|:-])/g, showdown2.helper.escapeCharactersCallback);
- text = globals.converter._dispatch("encodeBackslashEscapes.after", text, options, globals);
- return text;
- });
- showdown2.subParser("encodeCode", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("encodeCode.before", text, options, globals);
- text = text.replace(/&/g, "&").replace(//g, ">").replace(/([*_{}\[\]\\=~-])/g, showdown2.helper.escapeCharactersCallback);
- text = globals.converter._dispatch("encodeCode.after", text, options, globals);
- return text;
- });
- showdown2.subParser("escapeSpecialCharsWithinTagAttributes", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("escapeSpecialCharsWithinTagAttributes.before", text, options, globals);
- var tags = /<\/?[a-z\d_:-]+(?:[\s]+[\s\S]+?)?>/gi, comments = /-]|-[^>])(?:[^-]|-[^-])*)--)>/gi;
- text = text.replace(tags, function(wholeMatch) {
- return wholeMatch.replace(/(.)<\/?code>(?=.)/g, "$1`").replace(/([\\`*_~=|])/g, showdown2.helper.escapeCharactersCallback);
- });
- text = text.replace(comments, function(wholeMatch) {
- return wholeMatch.replace(/([\\`*_~=|])/g, showdown2.helper.escapeCharactersCallback);
- });
- text = globals.converter._dispatch("escapeSpecialCharsWithinTagAttributes.after", text, options, globals);
- return text;
- });
- showdown2.subParser("githubCodeBlocks", function(text, options, globals) {
- "use strict";
- if (!options.ghCodeBlocks) {
- return text;
- }
- text = globals.converter._dispatch("githubCodeBlocks.before", text, options, globals);
- text += "\xA80";
- text = text.replace(/(?:^|\n)(?: {0,3})(```+|~~~+)(?: *)([^\s`~]*)\n([\s\S]*?)\n(?: {0,3})\1/g, function(wholeMatch, delim, language, codeblock) {
- var end = options.omitExtraWLInCodeBlocks ? "" : "\n";
- codeblock = showdown2.subParser("encodeCode")(codeblock, options, globals);
- codeblock = showdown2.subParser("detab")(codeblock, options, globals);
- codeblock = codeblock.replace(/^\n+/g, "");
- codeblock = codeblock.replace(/\n+$/g, "");
- codeblock = "" + codeblock + end + "
";
- codeblock = showdown2.subParser("hashBlock")(codeblock, options, globals);
- return "\n\n\xA8G" + (globals.ghCodeBlocks.push({ text: wholeMatch, codeblock }) - 1) + "G\n\n";
- });
- text = text.replace(/¨0/, "");
- return globals.converter._dispatch("githubCodeBlocks.after", text, options, globals);
- });
- showdown2.subParser("hashBlock", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("hashBlock.before", text, options, globals);
- text = text.replace(/(^\n+|\n+$)/g, "");
- text = "\n\n\xA8K" + (globals.gHtmlBlocks.push(text) - 1) + "K\n\n";
- text = globals.converter._dispatch("hashBlock.after", text, options, globals);
- return text;
- });
- showdown2.subParser("hashCodeTags", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("hashCodeTags.before", text, options, globals);
- var repFunc = function(wholeMatch, match, left, right) {
- var codeblock = left + showdown2.subParser("encodeCode")(match, options, globals) + right;
- return "\xA8C" + (globals.gHtmlSpans.push(codeblock) - 1) + "C";
- };
- text = showdown2.helper.replaceRecursiveRegExp(text, repFunc, "]*>", "", "gim");
- text = globals.converter._dispatch("hashCodeTags.after", text, options, globals);
- return text;
- });
- showdown2.subParser("hashElement", function(text, options, globals) {
- "use strict";
- return function(wholeMatch, m1) {
- var blockText = m1;
- blockText = blockText.replace(/\n\n/g, "\n");
- blockText = blockText.replace(/^\n/, "");
- blockText = blockText.replace(/\n+$/g, "");
- blockText = "\n\n\xA8K" + (globals.gHtmlBlocks.push(blockText) - 1) + "K\n\n";
- return blockText;
- };
- });
- showdown2.subParser("hashHTMLBlocks", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("hashHTMLBlocks.before", text, options, globals);
- var blockTags = [
- "pre",
- "div",
- "h1",
- "h2",
- "h3",
- "h4",
- "h5",
- "h6",
- "blockquote",
- "table",
- "dl",
- "ol",
- "ul",
- "script",
- "noscript",
- "form",
- "fieldset",
- "iframe",
- "math",
- "style",
- "section",
- "header",
- "footer",
- "nav",
- "article",
- "aside",
- "address",
- "audio",
- "canvas",
- "figure",
- "hgroup",
- "output",
- "video",
- "p"
- ], repFunc = function(wholeMatch, match, left, right) {
- var txt = wholeMatch;
- if (left.search(/\bmarkdown\b/) !== -1) {
- txt = left + globals.converter.makeHtml(match) + right;
- }
- return "\n\n\xA8K" + (globals.gHtmlBlocks.push(txt) - 1) + "K\n\n";
- };
- if (options.backslashEscapesHTMLTags) {
- text = text.replace(/\\<(\/?[^>]+?)>/g, function(wm, inside) {
- return "<" + inside + ">";
- });
- }
- for (var i = 0; i < blockTags.length; ++i) {
- var opTagPos, rgx1 = new RegExp("^ {0,3}(<" + blockTags[i] + "\\b[^>]*>)", "im"), patLeft = "<" + blockTags[i] + "\\b[^>]*>", patRight = "" + blockTags[i] + ">";
- while ((opTagPos = showdown2.helper.regexIndexOf(text, rgx1)) !== -1) {
- var subTexts = showdown2.helper.splitAtIndex(text, opTagPos), newSubText1 = showdown2.helper.replaceRecursiveRegExp(subTexts[1], repFunc, patLeft, patRight, "im");
- if (newSubText1 === subTexts[1]) {
- break;
- }
- text = subTexts[0].concat(newSubText1);
- }
- }
- text = text.replace(/(\n {0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g, showdown2.subParser("hashElement")(text, options, globals));
- text = showdown2.helper.replaceRecursiveRegExp(text, function(txt) {
- return "\n\n\xA8K" + (globals.gHtmlBlocks.push(txt) - 1) + "K\n\n";
- }, "^ {0,3}", "gm");
- text = text.replace(/(?:\n\n)( {0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g, showdown2.subParser("hashElement")(text, options, globals));
- text = globals.converter._dispatch("hashHTMLBlocks.after", text, options, globals);
- return text;
- });
- showdown2.subParser("hashHTMLSpans", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("hashHTMLSpans.before", text, options, globals);
- function hashHTMLSpan(html) {
- return "\xA8C" + (globals.gHtmlSpans.push(html) - 1) + "C";
- }
- text = text.replace(/<[^>]+?\/>/gi, function(wm) {
- return hashHTMLSpan(wm);
- });
- text = text.replace(/<([^>]+?)>[\s\S]*?<\/\1>/g, function(wm) {
- return hashHTMLSpan(wm);
- });
- text = text.replace(/<([^>]+?)\s[^>]+?>[\s\S]*?<\/\1>/g, function(wm) {
- return hashHTMLSpan(wm);
- });
- text = text.replace(/<[^>]+?>/gi, function(wm) {
- return hashHTMLSpan(wm);
- });
- text = globals.converter._dispatch("hashHTMLSpans.after", text, options, globals);
- return text;
- });
- showdown2.subParser("unhashHTMLSpans", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("unhashHTMLSpans.before", text, options, globals);
- for (var i = 0; i < globals.gHtmlSpans.length; ++i) {
- var repText = globals.gHtmlSpans[i], limit = 0;
- while (/¨C(\d+)C/.test(repText)) {
- var num = RegExp.$1;
- repText = repText.replace("\xA8C" + num + "C", globals.gHtmlSpans[num]);
- if (limit === 10) {
- console.error("maximum nesting of 10 spans reached!!!");
- break;
- }
- ++limit;
- }
- text = text.replace("\xA8C" + i + "C", repText);
- }
- text = globals.converter._dispatch("unhashHTMLSpans.after", text, options, globals);
- return text;
- });
- showdown2.subParser("hashPreCodeTags", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("hashPreCodeTags.before", text, options, globals);
- var repFunc = function(wholeMatch, match, left, right) {
- var codeblock = left + showdown2.subParser("encodeCode")(match, options, globals) + right;
- return "\n\n\xA8G" + (globals.ghCodeBlocks.push({ text: wholeMatch, codeblock }) - 1) + "G\n\n";
- };
- text = showdown2.helper.replaceRecursiveRegExp(text, repFunc, "^ {0,3}]*>\\s*]*>", "^ {0,3}\\s*
", "gim");
- text = globals.converter._dispatch("hashPreCodeTags.after", text, options, globals);
- return text;
- });
- showdown2.subParser("headers", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("headers.before", text, options, globals);
- var headerLevelStart = isNaN(parseInt(options.headerLevelStart)) ? 1 : parseInt(options.headerLevelStart), setextRegexH1 = options.smoothLivePreview ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm, setextRegexH2 = options.smoothLivePreview ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm;
- text = text.replace(setextRegexH1, function(wholeMatch, m1) {
- var spanGamut = showdown2.subParser("spanGamut")(m1, options, globals), hID = options.noHeaderId ? "" : ' id="' + headerId(m1) + '"', hLevel = headerLevelStart, hashBlock = "" + spanGamut + " ";
- return showdown2.subParser("hashBlock")(hashBlock, options, globals);
- });
- text = text.replace(setextRegexH2, function(matchFound, m1) {
- var spanGamut = showdown2.subParser("spanGamut")(m1, options, globals), hID = options.noHeaderId ? "" : ' id="' + headerId(m1) + '"', hLevel = headerLevelStart + 1, hashBlock = "" + spanGamut + " ";
- return showdown2.subParser("hashBlock")(hashBlock, options, globals);
- });
- var atxStyle = options.requireSpaceBeforeHeadingText ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;
- text = text.replace(atxStyle, function(wholeMatch, m1, m2) {
- var hText = m2;
- if (options.customizedHeaderId) {
- hText = m2.replace(/\s?\{([^{]+?)}\s*$/, "");
- }
- var span = showdown2.subParser("spanGamut")(hText, options, globals), hID = options.noHeaderId ? "" : ' id="' + headerId(m2) + '"', hLevel = headerLevelStart - 1 + m1.length, header = "" + span + " ";
- return showdown2.subParser("hashBlock")(header, options, globals);
- });
- function headerId(m) {
- var title, prefix;
- if (options.customizedHeaderId) {
- var match = m.match(/\{([^{]+?)}\s*$/);
- if (match && match[1]) {
- m = match[1];
- }
- }
- title = m;
- if (showdown2.helper.isString(options.prefixHeaderId)) {
- prefix = options.prefixHeaderId;
- } else if (options.prefixHeaderId === true) {
- prefix = "section-";
- } else {
- prefix = "";
- }
- if (!options.rawPrefixHeaderId) {
- title = prefix + title;
- }
- if (options.ghCompatibleHeaderId) {
- title = title.replace(/ /g, "-").replace(/&/g, "").replace(/¨T/g, "").replace(/¨D/g, "").replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, "").toLowerCase();
- } else if (options.rawHeaderId) {
- title = title.replace(/ /g, "-").replace(/&/g, "&").replace(/¨T/g, "\xA8").replace(/¨D/g, "$").replace(/["']/g, "-").toLowerCase();
- } else {
- title = title.replace(/[^\w]/g, "").toLowerCase();
- }
- if (options.rawPrefixHeaderId) {
- title = prefix + title;
- }
- if (globals.hashLinkCounts[title]) {
- title = title + "-" + globals.hashLinkCounts[title]++;
- } else {
- globals.hashLinkCounts[title] = 1;
- }
- return title;
- }
- text = globals.converter._dispatch("headers.after", text, options, globals);
- return text;
- });
- showdown2.subParser("horizontalRule", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("horizontalRule.before", text, options, globals);
- var key = showdown2.subParser("hashBlock")("
", options, globals);
- text = text.replace(/^ {0,2}( ?-){3,}[ \t]*$/gm, key);
- text = text.replace(/^ {0,2}( ?\*){3,}[ \t]*$/gm, key);
- text = text.replace(/^ {0,2}( ?_){3,}[ \t]*$/gm, key);
- text = globals.converter._dispatch("horizontalRule.after", text, options, globals);
- return text;
- });
- showdown2.subParser("images", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("images.before", text, options, globals);
- var inlineRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?([\S]+?(?:\([\S]*?\)[\S]*?)?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, crazyRegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?<([^>]*)>(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(?:(["'])([^"]*?)\6))?[ \t]?\)/g, base64RegExp = /!\[([^\]]*?)][ \t]*()\([ \t]?(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*(?:(["'])([^"]*?)\6)?[ \t]?\)/g, referenceRegExp = /!\[([^\]]*?)] ?(?:\n *)?\[([\s\S]*?)]()()()()()/g, refShortcutRegExp = /!\[([^\[\]]+)]()()()()()/g;
- function writeImageTagBase64(wholeMatch, altText, linkId, url, width, height, m5, title) {
- url = url.replace(/\s/g, "");
- return writeImageTag(wholeMatch, altText, linkId, url, width, height, m5, title);
- }
- function writeImageTag(wholeMatch, altText, linkId, url, width, height, m5, title) {
- var gUrls = globals.gUrls, gTitles = globals.gTitles, gDims = globals.gDimensions;
- linkId = linkId.toLowerCase();
- if (!title) {
- title = "";
- }
- if (wholeMatch.search(/\(\s*>? ?(['"].*['"])?\)$/m) > -1) {
- url = "";
- } else if (url === "" || url === null) {
- if (linkId === "" || linkId === null) {
- linkId = altText.toLowerCase().replace(/ ?\n/g, " ");
- }
- url = "#" + linkId;
- if (!showdown2.helper.isUndefined(gUrls[linkId])) {
- url = gUrls[linkId];
- if (!showdown2.helper.isUndefined(gTitles[linkId])) {
- title = gTitles[linkId];
- }
- if (!showdown2.helper.isUndefined(gDims[linkId])) {
- width = gDims[linkId].width;
- height = gDims[linkId].height;
- }
- } else {
- return wholeMatch;
- }
- }
- altText = altText.replace(/"/g, """).replace(showdown2.helper.regexes.asteriskDashAndColon, showdown2.helper.escapeCharactersCallback);
- url = url.replace(showdown2.helper.regexes.asteriskDashAndColon, showdown2.helper.escapeCharactersCallback);
- var result = '
";
- return result;
- }
- text = text.replace(referenceRegExp, writeImageTag);
- text = text.replace(base64RegExp, writeImageTagBase64);
- text = text.replace(crazyRegExp, writeImageTag);
- text = text.replace(inlineRegExp, writeImageTag);
- text = text.replace(refShortcutRegExp, writeImageTag);
- text = globals.converter._dispatch("images.after", text, options, globals);
- return text;
- });
- showdown2.subParser("italicsAndBold", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("italicsAndBold.before", text, options, globals);
- function parseInside(txt, left, right) {
- return left + txt + right;
- }
- if (options.literalMidWordUnderscores) {
- text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function(wm, txt) {
- return parseInside(txt, "", "");
- });
- text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function(wm, txt) {
- return parseInside(txt, "", "");
- });
- text = text.replace(/\b_(\S[\s\S]*?)_\b/g, function(wm, txt) {
- return parseInside(txt, "", "");
- });
- } else {
- text = text.replace(/___(\S[\s\S]*?)___/g, function(wm, m) {
- return /\S$/.test(m) ? parseInside(m, "", "") : wm;
- });
- text = text.replace(/__(\S[\s\S]*?)__/g, function(wm, m) {
- return /\S$/.test(m) ? parseInside(m, "", "") : wm;
- });
- text = text.replace(/_([^\s_][\s\S]*?)_/g, function(wm, m) {
- return /\S$/.test(m) ? parseInside(m, "", "") : wm;
- });
- }
- if (options.literalMidWordAsterisks) {
- text = text.replace(/([^*]|^)\B\*\*\*(\S[\s\S]*?)\*\*\*\B(?!\*)/g, function(wm, lead, txt) {
- return parseInside(txt, lead + "", "");
- });
- text = text.replace(/([^*]|^)\B\*\*(\S[\s\S]*?)\*\*\B(?!\*)/g, function(wm, lead, txt) {
- return parseInside(txt, lead + "", "");
- });
- text = text.replace(/([^*]|^)\B\*(\S[\s\S]*?)\*\B(?!\*)/g, function(wm, lead, txt) {
- return parseInside(txt, lead + "", "");
- });
- } else {
- text = text.replace(/\*\*\*(\S[\s\S]*?)\*\*\*/g, function(wm, m) {
- return /\S$/.test(m) ? parseInside(m, "", "") : wm;
- });
- text = text.replace(/\*\*(\S[\s\S]*?)\*\*/g, function(wm, m) {
- return /\S$/.test(m) ? parseInside(m, "", "") : wm;
- });
- text = text.replace(/\*([^\s*][\s\S]*?)\*/g, function(wm, m) {
- return /\S$/.test(m) ? parseInside(m, "", "") : wm;
- });
- }
- text = globals.converter._dispatch("italicsAndBold.after", text, options, globals);
- return text;
- });
- showdown2.subParser("lists", function(text, options, globals) {
- "use strict";
- function processListItems(listStr, trimTrailing) {
- globals.gListLevel++;
- listStr = listStr.replace(/\n{2,}$/, "\n");
- listStr += "\xA80";
- var rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0| {0,3}([*+-]|\d+[.])[ \t]+))/gm, isParagraphed = /\n[ \t]*\n(?!¨0)/.test(listStr);
- if (options.disableForced4SpacesIndentedSublists) {
- rgx = /(\n)?(^ {0,3})([*+-]|\d+[.])[ \t]+((\[(x|X| )?])?[ \t]*[^\r]+?(\n{1,2}))(?=\n*(¨0|\2([*+-]|\d+[.])[ \t]+))/gm;
- }
- listStr = listStr.replace(rgx, function(wholeMatch, m1, m2, m3, m4, taskbtn, checked) {
- checked = checked && checked.trim() !== "";
- var item = showdown2.subParser("outdent")(m4, options, globals), bulletStyle = "";
- if (taskbtn && options.tasklists) {
- bulletStyle = ' class="task-list-item" style="list-style-type: none;"';
- item = item.replace(/^[ \t]*\[(x|X| )?]/m, function() {
- var otp = '";
- return otp;
- });
- }
- item = item.replace(/^([-*+]|\d\.)[ \t]+[\S\n ]*/g, function(wm2) {
- return "\xA8A" + wm2;
- });
- if (m1 || item.search(/\n{2,}/) > -1) {
- item = showdown2.subParser("githubCodeBlocks")(item, options, globals);
- item = showdown2.subParser("blockGamut")(item, options, globals);
- } else {
- item = showdown2.subParser("lists")(item, options, globals);
- item = item.replace(/\n$/, "");
- item = showdown2.subParser("hashHTMLBlocks")(item, options, globals);
- item = item.replace(/\n\n+/g, "\n\n");
- if (isParagraphed) {
- item = showdown2.subParser("paragraphs")(item, options, globals);
- } else {
- item = showdown2.subParser("spanGamut")(item, options, globals);
- }
- }
- item = item.replace("\xA8A", "");
- item = ""); - str += "
"; - grafsOut.push(str); - } - } - end = grafsOut.length; - for (i = 0; i < end; i++) { - var blockText = "", grafsOutIt = grafsOut[i], codeFlag = false; - while (/¨(K|G)(\d+)\1/.test(grafsOutIt)) { - var delim = RegExp.$1, num = RegExp.$2; - if (delim === "K") { - blockText = globals.gHtmlBlocks[num]; - } else { - if (codeFlag) { - blockText = showdown2.subParser("encodeCode")(globals.ghCodeBlocks[num].text, options, globals); - } else { - blockText = globals.ghCodeBlocks[num].codeblock; - } - } - blockText = blockText.replace(/\$/g, "$$$$"); - grafsOutIt = grafsOutIt.replace(/(\n\n)?¨(K|G)\d+\2(\n\n)?/, blockText); - if (/^]*>\s*]*>/.test(grafsOutIt)) {
- codeFlag = true;
- }
- }
- grafsOut[i] = grafsOutIt;
- }
- text = grafsOut.join("\n");
- text = text.replace(/^\n+/g, "");
- text = text.replace(/\n+$/g, "");
- return globals.converter._dispatch("paragraphs.after", text, options, globals);
- });
- showdown2.subParser("runExtension", function(ext, text, options, globals) {
- "use strict";
- if (ext.filter) {
- text = ext.filter(text, globals.converter, options);
- } else if (ext.regex) {
- var re = ext.regex;
- if (!(re instanceof RegExp)) {
- re = new RegExp(re, "g");
- }
- text = text.replace(re, ext.replace);
- }
- return text;
- });
- showdown2.subParser("spanGamut", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("spanGamut.before", text, options, globals);
- text = showdown2.subParser("codeSpans")(text, options, globals);
- text = showdown2.subParser("escapeSpecialCharsWithinTagAttributes")(text, options, globals);
- text = showdown2.subParser("encodeBackslashEscapes")(text, options, globals);
- text = showdown2.subParser("images")(text, options, globals);
- text = showdown2.subParser("anchors")(text, options, globals);
- text = showdown2.subParser("autoLinks")(text, options, globals);
- text = showdown2.subParser("simplifiedAutoLinks")(text, options, globals);
- text = showdown2.subParser("emoji")(text, options, globals);
- text = showdown2.subParser("underline")(text, options, globals);
- text = showdown2.subParser("italicsAndBold")(text, options, globals);
- text = showdown2.subParser("strikethrough")(text, options, globals);
- text = showdown2.subParser("ellipsis")(text, options, globals);
- text = showdown2.subParser("hashHTMLSpans")(text, options, globals);
- text = showdown2.subParser("encodeAmpsAndAngles")(text, options, globals);
- if (options.simpleLineBreaks) {
- if (!/\n\n¨K/.test(text)) {
- text = text.replace(/\n+/g, "
\n");
- }
- } else {
- text = text.replace(/ +\n/g, "
\n");
- }
- text = globals.converter._dispatch("spanGamut.after", text, options, globals);
- return text;
- });
- showdown2.subParser("strikethrough", function(text, options, globals) {
- "use strict";
- function parseInside(txt) {
- if (options.simplifiedAutoLink) {
- txt = showdown2.subParser("simplifiedAutoLinks")(txt, options, globals);
- }
- return "" + txt + "";
- }
- if (options.strikethrough) {
- text = globals.converter._dispatch("strikethrough.before", text, options, globals);
- text = text.replace(/(?:~){2}([\s\S]+?)(?:~){2}/g, function(wm, txt) {
- return parseInside(txt);
- });
- text = globals.converter._dispatch("strikethrough.after", text, options, globals);
- }
- return text;
- });
- showdown2.subParser("stripLinkDefinitions", function(text, options, globals) {
- "use strict";
- var regex = /^ {0,3}\[([^\]]+)]:[ \t]*\n?[ \t]*([^>\s]+)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n+|(?=¨0))/gm, base64Regex = /^ {0,3}\[([^\]]+)]:[ \t]*\n?[ \t]*(data:.+?\/.+?;base64,[A-Za-z0-9+/=\n]+?)>?(?: =([*\d]+[A-Za-z%]{0,4})x([*\d]+[A-Za-z%]{0,4}))?[ \t]*\n?[ \t]*(?:(\n*)["|'(](.+?)["|')][ \t]*)?(?:\n\n|(?=¨0)|(?=\n\[))/gm;
- text += "\xA80";
- var replaceFunc = function(wholeMatch, linkId, url, width, height, blankLines, title) {
- linkId = linkId.toLowerCase();
- if (text.toLowerCase().split(linkId).length - 1 < 2) {
- return wholeMatch;
- }
- if (url.match(/^data:.+?\/.+?;base64,/)) {
- globals.gUrls[linkId] = url.replace(/\s/g, "");
- } else {
- globals.gUrls[linkId] = showdown2.subParser("encodeAmpsAndAngles")(url, options, globals);
- }
- if (blankLines) {
- return blankLines + title;
- } else {
- if (title) {
- globals.gTitles[linkId] = title.replace(/"|'/g, """);
- }
- if (options.parseImgDimensions && width && height) {
- globals.gDimensions[linkId] = {
- width,
- height
- };
- }
- }
- return "";
- };
- text = text.replace(base64Regex, replaceFunc);
- text = text.replace(regex, replaceFunc);
- text = text.replace(/¨0/, "");
- return text;
- });
- showdown2.subParser("tables", function(text, options, globals) {
- "use strict";
- if (!options.tables) {
- return text;
- }
- var tableRgx = /^ {0,3}\|?.+\|.+\n {0,3}\|?[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*:?[ \t]*(?:[-=]){2,}[\s\S]+?(?:\n\n|¨0)/gm, singeColTblRgx = /^ {0,3}\|.+\|[ \t]*\n {0,3}\|[ \t]*:?[ \t]*(?:[-=]){2,}[ \t]*:?[ \t]*\|[ \t]*\n( {0,3}\|.+\|[ \t]*\n)*(?:\n|¨0)/gm;
- function parseStyles(sLine) {
- if (/^:[ \t]*--*$/.test(sLine)) {
- return ' style="text-align:left;"';
- } else if (/^--*[ \t]*:[ \t]*$/.test(sLine)) {
- return ' style="text-align:right;"';
- } else if (/^:[ \t]*--*[ \t]*:$/.test(sLine)) {
- return ' style="text-align:center;"';
- } else {
- return "";
- }
- }
- function parseHeaders(header, style) {
- var id = "";
- header = header.trim();
- if (options.tablesHeaderId || options.tableHeaderId) {
- id = ' id="' + header.replace(/ /g, "_").toLowerCase() + '"';
- }
- header = showdown2.subParser("spanGamut")(header, options, globals);
- return "" + header + " \n";
- }
- function parseCells(cell, style) {
- var subText = showdown2.subParser("spanGamut")(cell, options, globals);
- return "" + subText + " \n";
- }
- function buildTable(headers, cells) {
- var tb = "\n\n\n", tblLgn = headers.length;
- for (var i = 0; i < tblLgn; ++i) {
- tb += headers[i];
- }
- tb += " \n\n\n";
- for (i = 0; i < cells.length; ++i) {
- tb += "\n";
- for (var ii = 0; ii < tblLgn; ++ii) {
- tb += cells[i][ii];
- }
- tb += " \n";
- }
- tb += "\n
\n";
- return tb;
- }
- function parseTable(rawTable) {
- var i, tableLines = rawTable.split("\n");
- for (i = 0; i < tableLines.length; ++i) {
- if (/^ {0,3}\|/.test(tableLines[i])) {
- tableLines[i] = tableLines[i].replace(/^ {0,3}\|/, "");
- }
- if (/\|[ \t]*$/.test(tableLines[i])) {
- tableLines[i] = tableLines[i].replace(/\|[ \t]*$/, "");
- }
- tableLines[i] = showdown2.subParser("codeSpans")(tableLines[i], options, globals);
- }
- var rawHeaders = tableLines[0].split("|").map(function(s) {
- return s.trim();
- }), rawStyles = tableLines[1].split("|").map(function(s) {
- return s.trim();
- }), rawCells = [], headers = [], styles = [], cells = [];
- tableLines.shift();
- tableLines.shift();
- for (i = 0; i < tableLines.length; ++i) {
- if (tableLines[i].trim() === "") {
- continue;
- }
- rawCells.push(tableLines[i].split("|").map(function(s) {
- return s.trim();
- }));
- }
- if (rawHeaders.length < rawStyles.length) {
- return rawTable;
- }
- for (i = 0; i < rawStyles.length; ++i) {
- styles.push(parseStyles(rawStyles[i]));
- }
- for (i = 0; i < rawHeaders.length; ++i) {
- if (showdown2.helper.isUndefined(styles[i])) {
- styles[i] = "";
- }
- headers.push(parseHeaders(rawHeaders[i], styles[i]));
- }
- for (i = 0; i < rawCells.length; ++i) {
- var row = [];
- for (var ii = 0; ii < headers.length; ++ii) {
- if (showdown2.helper.isUndefined(rawCells[i][ii])) {
- }
- row.push(parseCells(rawCells[i][ii], styles[ii]));
- }
- cells.push(row);
- }
- return buildTable(headers, cells);
- }
- text = globals.converter._dispatch("tables.before", text, options, globals);
- text = text.replace(/\\(\|)/g, showdown2.helper.escapeCharactersCallback);
- text = text.replace(tableRgx, parseTable);
- text = text.replace(singeColTblRgx, parseTable);
- text = globals.converter._dispatch("tables.after", text, options, globals);
- return text;
- });
- showdown2.subParser("underline", function(text, options, globals) {
- "use strict";
- if (!options.underline) {
- return text;
- }
- text = globals.converter._dispatch("underline.before", text, options, globals);
- if (options.literalMidWordUnderscores) {
- text = text.replace(/\b___(\S[\s\S]*?)___\b/g, function(wm, txt) {
- return "" + txt + "";
- });
- text = text.replace(/\b__(\S[\s\S]*?)__\b/g, function(wm, txt) {
- return "" + txt + "";
- });
- } else {
- text = text.replace(/___(\S[\s\S]*?)___/g, function(wm, m) {
- return /\S$/.test(m) ? "" + m + "" : wm;
- });
- text = text.replace(/__(\S[\s\S]*?)__/g, function(wm, m) {
- return /\S$/.test(m) ? "" + m + "" : wm;
- });
- }
- text = text.replace(/(_)/g, showdown2.helper.escapeCharactersCallback);
- text = globals.converter._dispatch("underline.after", text, options, globals);
- return text;
- });
- showdown2.subParser("unescapeSpecialChars", function(text, options, globals) {
- "use strict";
- text = globals.converter._dispatch("unescapeSpecialChars.before", text, options, globals);
- text = text.replace(/¨E(\d+)E/g, function(wholeMatch, m1) {
- var charCodeToReplace = parseInt(m1);
- return String.fromCharCode(charCodeToReplace);
- });
- text = globals.converter._dispatch("unescapeSpecialChars.after", text, options, globals);
- return text;
- });
- showdown2.subParser("makeMarkdown.blockquote", function(node, globals) {
- "use strict";
- var txt = "";
- if (node.hasChildNodes()) {
- var children = node.childNodes, childrenLength = children.length;
- for (var i = 0; i < childrenLength; ++i) {
- var innerTxt = showdown2.subParser("makeMarkdown.node")(children[i], globals);
- if (innerTxt === "") {
- continue;
- }
- txt += innerTxt;
- }
- }
- txt = txt.trim();
- txt = "> " + txt.split("\n").join("\n> ");
- return txt;
- });
- showdown2.subParser("makeMarkdown.codeBlock", function(node, globals) {
- "use strict";
- var lang = node.getAttribute("language"), num = node.getAttribute("precodenum");
- return "```" + lang + "\n" + globals.preList[num] + "\n```";
- });
- showdown2.subParser("makeMarkdown.codeSpan", function(node) {
- "use strict";
- return "`" + node.innerHTML + "`";
- });
- showdown2.subParser("makeMarkdown.emphasis", function(node, globals) {
- "use strict";
- var txt = "";
- if (node.hasChildNodes()) {
- txt += "*";
- var children = node.childNodes, childrenLength = children.length;
- for (var i = 0; i < childrenLength; ++i) {
- txt += showdown2.subParser("makeMarkdown.node")(children[i], globals);
- }
- txt += "*";
- }
- return txt;
- });
- showdown2.subParser("makeMarkdown.header", function(node, globals, headerLevel) {
- "use strict";
- var headerMark = new Array(headerLevel + 1).join("#"), txt = "";
- if (node.hasChildNodes()) {
- txt = headerMark + " ";
- var children = node.childNodes, childrenLength = children.length;
- for (var i = 0; i < childrenLength; ++i) {
- txt += showdown2.subParser("makeMarkdown.node")(children[i], globals);
- }
- }
- return txt;
- });
- showdown2.subParser("makeMarkdown.hr", function() {
- "use strict";
- return "---";
- });
- showdown2.subParser("makeMarkdown.image", function(node) {
- "use strict";
- var txt = "";
- if (node.hasAttribute("src")) {
- txt += " + ">";
- if (node.hasAttribute("width") && node.hasAttribute("height")) {
- txt += " =" + node.getAttribute("width") + "x" + node.getAttribute("height");
- }
- if (node.hasAttribute("title")) {
- txt += ' "' + node.getAttribute("title") + '"';
- }
- txt += ")";
- }
- return txt;
- });
- showdown2.subParser("makeMarkdown.links", function(node, globals) {
- "use strict";
- var txt = "";
- if (node.hasChildNodes() && node.hasAttribute("href")) {
- var children = node.childNodes, childrenLength = children.length;
- txt = "[";
- for (var i = 0; i < childrenLength; ++i) {
- txt += showdown2.subParser("makeMarkdown.node")(children[i], globals);
- }
- txt += "](";
- txt += "<" + node.getAttribute("href") + ">";
- if (node.hasAttribute("title")) {
- txt += ' "' + node.getAttribute("title") + '"';
- }
- txt += ")";
- }
- return txt;
- });
- showdown2.subParser("makeMarkdown.list", function(node, globals, type) {
- "use strict";
- var txt = "";
- if (!node.hasChildNodes()) {
- return "";
- }
- var listItems = node.childNodes, listItemsLenght = listItems.length, listNum = node.getAttribute("start") || 1;
- for (var i = 0; i < listItemsLenght; ++i) {
- if (typeof listItems[i].tagName === "undefined" || listItems[i].tagName.toLowerCase() !== "li") {
- continue;
- }
- var bullet = "";
- if (type === "ol") {
- bullet = listNum.toString() + ". ";
- } else {
- bullet = "- ";
- }
- txt += bullet + showdown2.subParser("makeMarkdown.listItem")(listItems[i], globals);
- ++listNum;
- }
- txt += "\n\n";
- return txt.trim();
- });
- showdown2.subParser("makeMarkdown.listItem", function(node, globals) {
- "use strict";
- var listItemTxt = "";
- var children = node.childNodes, childrenLenght = children.length;
- for (var i = 0; i < childrenLenght; ++i) {
- listItemTxt += showdown2.subParser("makeMarkdown.node")(children[i], globals);
- }
- if (!/\n$/.test(listItemTxt)) {
- listItemTxt += "\n";
- } else {
- listItemTxt = listItemTxt.split("\n").join("\n ").replace(/^ {4}$/gm, "").replace(/\n\n+/g, "\n\n");
- }
- return listItemTxt;
- });
- showdown2.subParser("makeMarkdown.node", function(node, globals, spansOnly) {
- "use strict";
- spansOnly = spansOnly || false;
- var txt = "";
- if (node.nodeType === 3) {
- return showdown2.subParser("makeMarkdown.txt")(node, globals);
- }
- if (node.nodeType === 8) {
- return "\n\n";
- }
- if (node.nodeType !== 1) {
- return "";
- }
- var tagName = node.tagName.toLowerCase();
- switch (tagName) {
- case "h1":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.header")(node, globals, 1) + "\n\n";
- }
- break;
- case "h2":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.header")(node, globals, 2) + "\n\n";
- }
- break;
- case "h3":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.header")(node, globals, 3) + "\n\n";
- }
- break;
- case "h4":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.header")(node, globals, 4) + "\n\n";
- }
- break;
- case "h5":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.header")(node, globals, 5) + "\n\n";
- }
- break;
- case "h6":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.header")(node, globals, 6) + "\n\n";
- }
- break;
- case "p":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.paragraph")(node, globals) + "\n\n";
- }
- break;
- case "blockquote":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.blockquote")(node, globals) + "\n\n";
- }
- break;
- case "hr":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.hr")(node, globals) + "\n\n";
- }
- break;
- case "ol":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.list")(node, globals, "ol") + "\n\n";
- }
- break;
- case "ul":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.list")(node, globals, "ul") + "\n\n";
- }
- break;
- case "precode":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.codeBlock")(node, globals) + "\n\n";
- }
- break;
- case "pre":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.pre")(node, globals) + "\n\n";
- }
- break;
- case "table":
- if (!spansOnly) {
- txt = showdown2.subParser("makeMarkdown.table")(node, globals) + "\n\n";
- }
- break;
- case "code":
- txt = showdown2.subParser("makeMarkdown.codeSpan")(node, globals);
- break;
- case "em":
- case "i":
- txt = showdown2.subParser("makeMarkdown.emphasis")(node, globals);
- break;
- case "strong":
- case "b":
- txt = showdown2.subParser("makeMarkdown.strong")(node, globals);
- break;
- case "del":
- txt = showdown2.subParser("makeMarkdown.strikethrough")(node, globals);
- break;
- case "a":
- txt = showdown2.subParser("makeMarkdown.links")(node, globals);
- break;
- case "img":
- txt = showdown2.subParser("makeMarkdown.image")(node, globals);
- break;
- default:
- txt = node.outerHTML + "\n\n";
- }
- return txt;
- });
- showdown2.subParser("makeMarkdown.paragraph", function(node, globals) {
- "use strict";
- var txt = "";
- if (node.hasChildNodes()) {
- var children = node.childNodes, childrenLength = children.length;
- for (var i = 0; i < childrenLength; ++i) {
- txt += showdown2.subParser("makeMarkdown.node")(children[i], globals);
- }
- }
- txt = txt.trim();
- return txt;
- });
- showdown2.subParser("makeMarkdown.pre", function(node, globals) {
- "use strict";
- var num = node.getAttribute("prenum");
- return "" + globals.preList[num] + "
";
- });
- showdown2.subParser("makeMarkdown.strikethrough", function(node, globals) {
- "use strict";
- var txt = "";
- if (node.hasChildNodes()) {
- txt += "~~";
- var children = node.childNodes, childrenLength = children.length;
- for (var i = 0; i < childrenLength; ++i) {
- txt += showdown2.subParser("makeMarkdown.node")(children[i], globals);
- }
- txt += "~~";
- }
- return txt;
- });
- showdown2.subParser("makeMarkdown.strong", function(node, globals) {
- "use strict";
- var txt = "";
- if (node.hasChildNodes()) {
- txt += "**";
- var children = node.childNodes, childrenLength = children.length;
- for (var i = 0; i < childrenLength; ++i) {
- txt += showdown2.subParser("makeMarkdown.node")(children[i], globals);
- }
- txt += "**";
- }
- return txt;
- });
- showdown2.subParser("makeMarkdown.table", function(node, globals) {
- "use strict";
- var txt = "", tableArray = [[], []], headings = node.querySelectorAll("thead>tr>th"), rows = node.querySelectorAll("tbody>tr"), i, ii;
- for (i = 0; i < headings.length; ++i) {
- var headContent = showdown2.subParser("makeMarkdown.tableCell")(headings[i], globals), allign = "---";
- if (headings[i].hasAttribute("style")) {
- var style = headings[i].getAttribute("style").toLowerCase().replace(/\s/g, "");
- switch (style) {
- case "text-align:left;":
- allign = ":---";
- break;
- case "text-align:right;":
- allign = "---:";
- break;
- case "text-align:center;":
- allign = ":---:";
- break;
- }
- }
- tableArray[0][i] = headContent.trim();
- tableArray[1][i] = allign;
- }
- for (i = 0; i < rows.length; ++i) {
- var r = tableArray.push([]) - 1, cols = rows[i].getElementsByTagName("td");
- for (ii = 0; ii < headings.length; ++ii) {
- var cellContent = " ";
- if (typeof cols[ii] !== "undefined") {
- cellContent = showdown2.subParser("makeMarkdown.tableCell")(cols[ii], globals);
- }
- tableArray[r].push(cellContent);
- }
- }
- var cellSpacesCount = 3;
- for (i = 0; i < tableArray.length; ++i) {
- for (ii = 0; ii < tableArray[i].length; ++ii) {
- var strLen = tableArray[i][ii].length;
- if (strLen > cellSpacesCount) {
- cellSpacesCount = strLen;
- }
- }
- }
- for (i = 0; i < tableArray.length; ++i) {
- for (ii = 0; ii < tableArray[i].length; ++ii) {
- if (i === 1) {
- if (tableArray[i][ii].slice(-1) === ":") {
- tableArray[i][ii] = showdown2.helper.padEnd(tableArray[i][ii].slice(-1), cellSpacesCount - 1, "-") + ":";
- } else {
- tableArray[i][ii] = showdown2.helper.padEnd(tableArray[i][ii], cellSpacesCount, "-");
- }
- } else {
- tableArray[i][ii] = showdown2.helper.padEnd(tableArray[i][ii], cellSpacesCount);
- }
- }
- txt += "| " + tableArray[i].join(" | ") + " |\n";
- }
- return txt.trim();
- });
- showdown2.subParser("makeMarkdown.tableCell", function(node, globals) {
- "use strict";
- var txt = "";
- if (!node.hasChildNodes()) {
- return "";
- }
- var children = node.childNodes, childrenLength = children.length;
- for (var i = 0; i < childrenLength; ++i) {
- txt += showdown2.subParser("makeMarkdown.node")(children[i], globals, true);
- }
- return txt.trim();
- });
- showdown2.subParser("makeMarkdown.txt", function(node) {
- "use strict";
- var txt = node.nodeValue;
- txt = txt.replace(/ +/g, " ");
- txt = txt.replace(/¨NBSP;/g, " ");
- txt = showdown2.helper.unescapeHTMLEntities(txt);
- txt = txt.replace(/([*_~|`])/g, "\\$1");
- txt = txt.replace(/^(\s*)>/g, "\\$1>");
- txt = txt.replace(/^#/gm, "\\#");
- txt = txt.replace(/^(\s*)([-=]{3,})(\s*)$/, "$1\\$2$3");
- txt = txt.replace(/^( {0,3}\d+)\./gm, "$1\\.");
- txt = txt.replace(/^( {0,3})([+-])/gm, "$1\\$2");
- txt = txt.replace(/]([\s]*)\(/g, "\\]$1\\(");
- txt = txt.replace(/^ {0,3}\[([\S \t]*?)]:/gm, "\\[$1]:");
- return txt;
- });
- var root = this;
- if (typeof define === "function" && define.amd) {
- define(function() {
- "use strict";
- return showdown2;
- });
- } else if (typeof module2 !== "undefined" && module2.exports) {
- module2.exports = showdown2;
- } else {
- root.showdown = showdown2;
- }
- }).call(exports);
- }
-});
-
-// main.ts
-__export(exports, {
- default: () => MarkdownToHTML
-});
-var import_obsidian = __toModule(require("obsidian"));
-var showdown = __toModule(require_showdown());
-var DEFAULT_SETTINGS = {
- removeBrackets: true,
- removeEmphasis: false,
- removeTags: false,
- removeComments: false
-};
-var MarkdownToHTML = class extends import_obsidian.Plugin {
- onload() {
- return __async(this, null, function* () {
- yield this.loadSettings();
- this.addCommand({
- id: "copy-as-html-command",
- name: "Copy as HTML command",
- editorCallback: (editor) => this.markdownToHTML(editor)
- });
- this.addSettingTab(new MarkdownToHTMLSettingTab(this.app, this));
- });
- }
- markdownToHTML(editor) {
- const converter = new showdown.Converter();
- converter.setFlavor("github");
- converter.setOption("ellipsis", false);
- let text = editor.getSelection();
- text = text.replace(/==/g, "");
- text = text.replace(/\^\w+/g, "");
- if (this.settings.removeBrackets) {
- text = text.replace(/\[\[(.*?)\]\]/g, "$1");
- }
- if (this.settings.removeEmphasis) {
- text = text.replace(/[*~]+(\w+)[*~]+/g, "$1");
- }
- if (this.settings.removeTags) {
- text = text.replace(/#\w+/g, "");
- }
- if (this.settings.removeComments) {
- text = text.replace(/%%.+%%/g, "");
- }
- const html = converter.makeHtml(text).toString();
- const withDivWrapper = `
- ${html}`;
- const blob = new Blob([withDivWrapper], {
- type: ["text/plain", "text/html"]
- });
- const data = [new ClipboardItem({
- ["text/plain"]: blob,
- ["text/html"]: blob
- })];
- navigator.clipboard.write(data);
- }
- loadSettings() {
- return __async(this, null, function* () {
- this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
- });
- }
- saveSettings() {
- return __async(this, null, function* () {
- yield this.saveData(this.settings);
- });
- }
- onunload() {
- }
-};
-var MarkdownToHTMLSettingTab = class extends import_obsidian.PluginSettingTab {
- constructor(app, plugin) {
- super(app, plugin);
- this.plugin = plugin;
- }
- display() {
- let { containerEl } = this;
- containerEl.empty();
- new import_obsidian.Setting(containerEl).setName("Remove Wikilink brackets").setDesc("If enabled, removes wikilink brackets from copied text.").addToggle((toggle) => toggle.setValue(this.plugin.settings.removeBrackets).onChange((value) => __async(this, null, function* () {
- this.plugin.settings.removeBrackets = value;
- yield this.plugin.saveSettings();
- })));
- new import_obsidian.Setting(containerEl).setName("Remove text emphasis").setDesc("If enabled, removes text styling such as bold, italics, and highlights.").addToggle((toggle) => toggle.setValue(this.plugin.settings.removeEmphasis).onChange((value) => __async(this, null, function* () {
- this.plugin.settings.removeEmphasis = value;
- yield this.plugin.saveSettings();
- })));
- new import_obsidian.Setting(containerEl).setName("Remove hashtags").setDesc("If enabled, removes text immediately after a hashtag.").addToggle((toggle) => toggle.setValue(this.plugin.settings.removeTags).onChange((value) => __async(this, null, function* () {
- this.plugin.settings.removeTags = value;
- yield this.plugin.saveSettings();
- })));
- new import_obsidian.Setting(containerEl).setName("Remove comments").setDesc("If enabled, removes commented text.").addToggle((toggle) => toggle.setValue(this.plugin.settings.removeComments).onChange((value) => __async(this, null, function* () {
- this.plugin.settings.removeComments = value;
- yield this.plugin.saveSettings();
- })));
- }
-};
-/*! showdown v 2.1.0 - 21-04-2022 */
-
-/* nosourcemap */
\ No newline at end of file
diff --git a/.obsidian/plugins/copy-as-html/manifest.json b/.obsidian/plugins/copy-as-html/manifest.json
deleted file mode 100644
index fcbc57e..0000000
--- a/.obsidian/plugins/copy-as-html/manifest.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "id": "copy-as-html",
- "name": "Copy as HTML",
- "version": "1.1.3",
- "minAppVersion": "0.12.0",
- "description": "This is a simple plugin that converts the selected markdown to HTML and copies it to the clipboard.",
- "author": "Bailey Jennings",
- "authorUrl": "https://twitter.com/Bailey_Jennings",
- "isDesktopOnly": false
-}
\ No newline at end of file
diff --git a/.obsidian/plugins/copy-document-as-html/data.json b/.obsidian/plugins/copy-document-as-html/data.json
new file mode 100644
index 0000000..19c89e3
--- /dev/null
+++ b/.obsidian/plugins/copy-document-as-html/data.json
@@ -0,0 +1,17 @@
+{
+ "removeFrontMatter": true,
+ "convertSvgToBitmap": true,
+ "useCustomStylesheet": true,
+ "useCustomHtmlTemplate": true,
+ "embedExternalLinks": false,
+ "removeDataviewMetadataLines": false,
+ "formatCodeWithTables": false,
+ "formatCalloutsWithTables": false,
+ "footnoteHandling": 2,
+ "internalLinkHandling": 0,
+ "styleSheet": "body,input {\n font-family: \"Roboto\",\"Helvetica Neue\",Helvetica,Arial,sans-serif\n}\n\ncode, kbd, pre {\n font-family: \"Roboto Mono\", \"Courier New\", Courier, monospace;\n background-color: #f5f5f5;\n}\n\npre {\n padding: 1em 0.5em;\n}\n\nmark {\n background-color: yellow;\n background: yellow;\n mso-highlight: yellow;\n color: red;\n}\n\ndel {\n text-decoration: line-through;\n}\n\nem {\n color: grey;\n font-style: italic;\n}\n\nstrong {\n font-style: bold;\n}\n\ntable {\n background: white;\n border: 1px solid #666;\n border-collapse: collapse;\n padding: 0.5em;\n}\n\ntable thead th,\ntable tfoot th {\n text-align: left;\n background-color: #eaeaea;\n color: black;\n}\n\ntable th, table td {\n border: 1px solid #ddd;\n padding: 0.5em;\n}\n\ntable td {\n color: #222222;\n}\n\n.callout[data-callout=\"abstract\"] .callout-title,\n.callout[data-callout=\"summary\"] .callout-title,\n.callout[data-callout=\"tldr\"] .callout-title,\n.callout[data-callout=\"faq\"] .callout-title,\n.callout[data-callout=\"info\"] .callout-title,\n.callout[data-callout=\"help\"] .callout-title {\n background-color: #828ee7;\n}\n.callout[data-callout=\"tip\"] .callout-title,\n.callout[data-callout=\"hint\"] .callout-title,\n.callout[data-callout=\"important\"] .callout-title {\n background-color: #34bbe6;\n}\n.callout[data-callout=\"success\"] .callout-title,\n.callout[data-callout=\"check\"] .callout-title,\n.callout[data-callout=\"done\"] .callout-title {\n background-color: #a3e048;\n}\n.callout[data-callout=\"question\"] .callout-title,\n.callout[data-callout=\"todo\"] .callout-title {\n background-color: #49da9a;\n}\n.callout[data-callout=\"caution\"] .callout-title,\n.callout[data-callout=\"attention\"] .callout-title {\n background-color: #f7d038;\n}\n.callout[data-callout=\"warning\"] .callout-title,\n.callout[data-callout=\"missing\"] .callout-title,\n.callout[data-callout=\"bug\"] .callout-title {\n background-color: #eb7532;\n}\n.callout[data-callout=\"failure\"] .callout-title,\n.callout[data-callout=\"fail\"] .callout-title,\n.callout[data-callout=\"danger\"] .callout-title,\n.callout[data-callout=\"error\"] .callout-title {\n background-color: #e6261f;\n}\n.callout[data-callout=\"example\"] .callout-title {\n background-color: #d23be7;\n}\n.callout[data-callout=\"quote\"] .callout-title,\n.callout[data-callout=\"cite\"] .callout-title {\n background-color: #aaaaaa;\n}\n\n.callout-icon {\n flex: 0 0 auto;\n display: flex;\n align-self: center;\n}\n\nsvg.svg-icon {\n height: 18px;\n width: 18px;\n stroke-width: 1.75px;\n}\n\n.callout {\n overflow: hidden;\n margin: 1em 0;\n box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);\n border-radius: 4px;\n}\n\n.callout-title {\n padding: .5em;\n display: flex;\n gap: 8px;\n font-size: inherit;\n color: black;\n line-height: 1.3em;\n}\n\n.callout-title-inner {\n font-weight: bold;\n color: black;\n}\n\n.callout-content {\n overflow-x: auto;\n padding: 0.25em .5em;\n color: #222222;\n background-color: white !important;\n}\n\nul.contains-task-list {\n padding-left: 0;\n list-style: none;\n}\n\nul.contains-task-list ul.contains-task-list {\n padding-left: 2em;\n}\n\nul.contains-task-list li input[type=\"checkbox\"] {\n margin-right: .5em;\n}\n\n.callout-table,\n.callout-table tr,\n.callout-table p {\n width: 100%;\n padding: 0;\n}\n\n.callout-table td {\n width: 100%;\n padding: 0 1em;\n}\n\n.callout-table p {\n padding-bottom: 0.5em;\n}\n\n.source-table {\n width: 100%;\n background-color: #f5f5f5;\n}\n",
+ "htmlTemplate": "\n\n\n \n ${title} \n \n\n\n${body}\n\n\n",
+ "bareHtmlOnly": false,
+ "fileNameAsHeader": false,
+ "disableImageEmbedding": false
+}
\ No newline at end of file
diff --git a/.obsidian/plugins/copy-document-as-html/main.js b/.obsidian/plugins/copy-document-as-html/main.js
new file mode 100644
index 0000000..39f2857
--- /dev/null
+++ b/.obsidian/plugins/copy-document-as-html/main.js
@@ -0,0 +1,897 @@
+/*
+THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
+if you want to view the source, please visit the github repository of this plugin
+*/
+
+var __defProp = Object.defineProperty;
+var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
+var __getOwnPropNames = Object.getOwnPropertyNames;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __export = (target, all) => {
+ for (var name in all)
+ __defProp(target, name, { get: all[name], enumerable: true });
+};
+var __copyProps = (to, from, except, desc) => {
+ if (from && typeof from === "object" || typeof from === "function") {
+ for (let key of __getOwnPropNames(from))
+ if (!__hasOwnProp.call(to, key) && key !== except)
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
+ }
+ return to;
+};
+var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
+
+// main.ts
+var main_exports = {};
+__export(main_exports, {
+ default: () => CopyDocumentAsHTMLPlugin
+});
+module.exports = __toCommonJS(main_exports);
+var import_obsidian = require("obsidian");
+function allWithProgress(promises, callback) {
+ let count = 0;
+ callback(0);
+ for (const promise of promises) {
+ promise.then(() => {
+ count++;
+ callback(count * 100 / promises.length);
+ });
+ }
+ return Promise.all(promises);
+}
+async function delay(milliseconds) {
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
+}
+var DEFAULT_STYLESHEET = `body,input {
+ font-family: "Roboto","Helvetica Neue",Helvetica,Arial,sans-serif
+}
+
+code, kbd, pre {
+ font-family: "Roboto Mono", "Courier New", Courier, monospace;
+ background-color: #f5f5f5;
+}
+
+pre {
+ padding: 1em 0.5em;
+}
+
+table {
+ background: white;
+ border: 1px solid #666;
+ border-collapse: collapse;
+ padding: 0.5em;
+}
+
+table thead th,
+table tfoot th {
+ text-align: left;
+ background-color: #eaeaea;
+ color: black;
+}
+
+table th, table td {
+ border: 1px solid #ddd;
+ padding: 0.5em;
+}
+
+table td {
+ color: #222222;
+}
+
+.callout[data-callout="abstract"] .callout-title,
+.callout[data-callout="summary"] .callout-title,
+.callout[data-callout="tldr"] .callout-title,
+.callout[data-callout="faq"] .callout-title,
+.callout[data-callout="info"] .callout-title,
+.callout[data-callout="help"] .callout-title {
+ background-color: #828ee7;
+}
+.callout[data-callout="tip"] .callout-title,
+.callout[data-callout="hint"] .callout-title,
+.callout[data-callout="important"] .callout-title {
+ background-color: #34bbe6;
+}
+.callout[data-callout="success"] .callout-title,
+.callout[data-callout="check"] .callout-title,
+.callout[data-callout="done"] .callout-title {
+ background-color: #a3e048;
+}
+.callout[data-callout="question"] .callout-title,
+.callout[data-callout="todo"] .callout-title {
+ background-color: #49da9a;
+}
+.callout[data-callout="caution"] .callout-title,
+.callout[data-callout="attention"] .callout-title {
+ background-color: #f7d038;
+}
+.callout[data-callout="warning"] .callout-title,
+.callout[data-callout="missing"] .callout-title,
+.callout[data-callout="bug"] .callout-title {
+ background-color: #eb7532;
+}
+.callout[data-callout="failure"] .callout-title,
+.callout[data-callout="fail"] .callout-title,
+.callout[data-callout="danger"] .callout-title,
+.callout[data-callout="error"] .callout-title {
+ background-color: #e6261f;
+}
+.callout[data-callout="example"] .callout-title {
+ background-color: #d23be7;
+}
+.callout[data-callout="quote"] .callout-title,
+.callout[data-callout="cite"] .callout-title {
+ background-color: #aaaaaa;
+}
+
+.callout-icon {
+ flex: 0 0 auto;
+ display: flex;
+ align-self: center;
+}
+
+svg.svg-icon {
+ height: 18px;
+ width: 18px;
+ stroke-width: 1.75px;
+}
+
+.callout {
+ overflow: hidden;
+ margin: 1em 0;
+ box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
+ border-radius: 4px;
+}
+
+.callout-title {
+ padding: .5em;
+ display: flex;
+ gap: 8px;
+ font-size: inherit;
+ color: black;
+ line-height: 1.3em;
+}
+
+.callout-title-inner {
+ font-weight: bold;
+ color: black;
+}
+
+.callout-content {
+ overflow-x: auto;
+ padding: 0.25em .5em;
+ color: #222222;
+ background-color: white !important;
+}
+
+ul.contains-task-list {
+ padding-left: 0;
+ list-style: none;
+}
+
+ul.contains-task-list ul.contains-task-list {
+ padding-left: 2em;
+}
+
+ul.contains-task-list li input[type="checkbox"] {
+ margin-right: .5em;
+}
+
+.callout-table,
+.callout-table tr,
+.callout-table p {
+ width: 100%;
+ padding: 0;
+}
+
+.callout-table td {
+ width: 100%;
+ padding: 0 1em;
+}
+
+.callout-table p {
+ padding-bottom: 0.5em;
+}
+
+.source-table {
+ width: 100%;
+ background-color: #f5f5f5;
+}
+`;
+var MERMAID_STYLESHEET = `
+:root {
+ --default-font: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Microsoft YaHei Light", sans-serif;
+ --font-monospace: 'Source Code Pro', monospace;
+ --background-primary: #ffffff;
+ --background-modifier-border: #ddd;
+ --text-accent: #705dcf;
+ --text-accent-hover: #7a6ae6;
+ --text-normal: #2e3338;
+ --background-secondary: #f2f3f5;
+ --background-secondary-alt: #fcfcfc;
+ --text-muted: #888888;
+ --font-mermaid: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Inter", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Microsoft YaHei Light", sans-serif;
+ --text-error: #E4374B;
+ --background-primary-alt: '#fafafa';
+ --background-accent: '';
+ --interactive-accent: hsl( 254, 80%, calc( 68% + 2.5%));
+ --background-modifier-error: #E4374B;
+ --background-primary-alt: #fafafa;
+ --background-modifier-border: #e0e0e0;
+}
+`;
+var DEFAULT_HTML_TEMPLATE = `
+
+
+
+ \${title}
+
+
+
+\${body}
+
+
+`;
+var copyIsRunning = false;
+var ppIsProcessing = false;
+var ppLastBlockDate = Date.now();
+var documentRendererDefaults = {
+ convertSvgToBitmap: true,
+ removeFrontMatter: true,
+ formatCodeWithTables: false,
+ formatCalloutsWithTables: false,
+ embedExternalLinks: false,
+ removeDataviewMetadataLines: false,
+ footnoteHandling: 2 /* REMOVE_LINK */,
+ internalLinkHandling: 0 /* CONVERT_TO_TEXT */,
+ disableImageEmbedding: false
+};
+var DocumentRenderer = class {
+ constructor(app, options = documentRendererDefaults) {
+ this.app = app;
+ this.options = options;
+ this.optionRenderSettlingDelay = 100;
+ this.mimeMap = /* @__PURE__ */ new Map([
+ ["svg", "image/svg+xml"],
+ ["jpg", "image/jpeg"]
+ ]);
+ this.externalSchemes = ["http", "https"];
+ this.vaultPath = this.app.vault.getRoot().vault.adapter.getBasePath().replace(/\\/g, "/");
+ this.vaultLocalUriPrefix = `app://local/${this.vaultPath}`;
+ this.vaultOpenUri = `obsidian://open?vault=${encodeURIComponent(this.app.vault.getName())}`;
+ this.vaultSearchUri = `obsidian://search?vault=${encodeURIComponent(this.app.vault.getName())}`;
+ this.view = new import_obsidian.Component();
+ }
+ async renderDocument(markdown, path) {
+ this.modal = new CopyingToHtmlModal(this.app);
+ this.modal.open();
+ try {
+ const topNode = await this.renderMarkdown(markdown, path);
+ return await this.transformHTML(topNode);
+ } finally {
+ this.modal.close();
+ }
+ }
+ async renderMarkdown(markdown, path) {
+ const processedMarkdown = this.preprocessMarkdown(markdown);
+ const wrapper = document.createElement("div");
+ wrapper.style.display = "hidden";
+ document.body.appendChild(wrapper);
+ await import_obsidian.MarkdownRenderer.render(this.app, processedMarkdown, wrapper, path, this.view);
+ await this.untilRendered();
+ await this.loadComponents(this.view);
+ const result = wrapper.cloneNode(true);
+ document.body.removeChild(wrapper);
+ this.view.unload();
+ return result;
+ }
+ async loadComponents(view) {
+ const internalView = view;
+ const loadChildren = async (component, visited = /* @__PURE__ */ new Set()) => {
+ var _a, _b;
+ if (visited.has(component)) {
+ return;
+ }
+ visited.add(component);
+ const internalComponent = component;
+ if ((_a = internalComponent._children) == null ? void 0 : _a.length) {
+ for (const child of internalComponent._children) {
+ await loadChildren(child, visited);
+ }
+ }
+ try {
+ if (((_b = component == null ? void 0 : component.constructor) == null ? void 0 : _b.name) === "SheetElement") {
+ await component.onload();
+ }
+ } catch (error) {
+ console.error(`Error calling onload()`, error);
+ }
+ };
+ await loadChildren(internalView);
+ }
+ preprocessMarkdown(markdown) {
+ let processed = markdown;
+ if (this.options.removeDataviewMetadataLines) {
+ processed = processed.replace(/^[^ \t:#`<>][^:#`<>]+::.*$/gm, "");
+ }
+ return processed;
+ }
+ async untilRendered() {
+ while (ppIsProcessing || Date.now() - ppLastBlockDate < this.optionRenderSettlingDelay) {
+ if (ppLastBlockDate === 0) {
+ break;
+ }
+ await delay(20);
+ }
+ }
+ async transformHTML(element) {
+ const node = element.cloneNode(true);
+ node.removeAttribute("style");
+ if (this.options.removeFrontMatter) {
+ this.removeFrontMatter(node);
+ }
+ this.replaceLinksOfClass(node, "internal-link");
+ this.replaceLinksOfClass(node, "tag");
+ this.makeCheckboxesReadOnly(node);
+ this.removeCollapseIndicators(node);
+ this.removeButtons(node);
+ this.removeStrangeNewWorldsLinks(node);
+ if (this.options.formatCodeWithTables) {
+ this.transformCodeToTables(node);
+ }
+ if (this.options.formatCalloutsWithTables) {
+ this.transformCalloutsToTables(node);
+ }
+ if (this.options.footnoteHandling == 0 /* REMOVE_ALL */) {
+ this.removeAllFootnotes(node);
+ }
+ if (this.options.footnoteHandling == 2 /* REMOVE_LINK */) {
+ this.removeFootnoteLinks(node);
+ } else if (this.options.footnoteHandling == 3 /* TITLE_ATTRIBUTE */) {
+ }
+ if (!this.options.disableImageEmbedding) {
+ await this.embedImages(node);
+ await this.renderSvg(node);
+ }
+ return node;
+ }
+ removeFrontMatter(node) {
+ node.querySelectorAll(".frontmatter, .frontmatter-container").forEach((node2) => node2.remove());
+ }
+ replaceLinksOfClass(node, className) {
+ if (this.options.internalLinkHandling === 3 /* LEAVE_AS_IS */) {
+ return;
+ }
+ node.querySelectorAll(`a.${className}`).forEach((node2) => {
+ switch (this.options.internalLinkHandling) {
+ case 1 /* CONVERT_TO_OBSIDIAN_URI */:
+ {
+ const linkNode = node2.parentNode.createEl("a");
+ linkNode.innerText = node2.getText();
+ if (className === "tag") {
+ linkNode.href = this.vaultSearchUri + "&query=tag:" + encodeURIComponent(node2.getAttribute("href"));
+ } else {
+ if (node2.getAttribute("href").startsWith("#")) {
+ linkNode.href = node2.getAttribute("href");
+ } else {
+ linkNode.href = this.vaultOpenUri + "&file=" + encodeURIComponent(node2.getAttribute("href"));
+ }
+ }
+ linkNode.className = className;
+ node2.parentNode.replaceChild(linkNode, node2);
+ }
+ break;
+ case 2 /* LINK_TO_HTML */:
+ {
+ const linkNode = node2.parentNode.createEl("a");
+ linkNode.innerText = node2.getAttribute("href");
+ linkNode.className = className;
+ if (node2.getAttribute("href").startsWith("#")) {
+ linkNode.href = node2.getAttribute("href");
+ } else {
+ linkNode.href = node2.getAttribute("href").replace(/^(.*?)(?:\.md)?(#.*?)?$/, "$1.html$2");
+ }
+ node2.parentNode.replaceChild(linkNode, node2);
+ }
+ break;
+ case 0 /* CONVERT_TO_TEXT */:
+ default:
+ {
+ const textNode = node2.parentNode.createEl("span");
+ textNode.innerText = node2.getText();
+ textNode.className = className;
+ node2.parentNode.replaceChild(textNode, node2);
+ }
+ break;
+ }
+ });
+ }
+ makeCheckboxesReadOnly(node) {
+ node.querySelectorAll('input[type="checkbox"]').forEach((node2) => node2.setAttribute("disabled", "disabled"));
+ }
+ removeCollapseIndicators(node) {
+ node.querySelectorAll(".collapse-indicator").forEach((node2) => node2.remove());
+ }
+ removeButtons(node) {
+ node.querySelectorAll("button").forEach((node2) => node2.remove());
+ }
+ removeStrangeNewWorldsLinks(node) {
+ node.querySelectorAll(".snw-reference").forEach((node2) => node2.remove());
+ }
+ transformCodeToTables(node) {
+ node.querySelectorAll("pre").forEach((node2) => {
+ const codeEl = node2.querySelector("code");
+ if (codeEl) {
+ const code = codeEl.innerHTML.replace(/\n*$/, "");
+ const table = node2.parentElement.createEl("table");
+ table.className = "source-table";
+ table.innerHTML = `${code} `;
+ node2.parentElement.replaceChild(table, node2);
+ }
+ });
+ }
+ transformCalloutsToTables(node) {
+ node.querySelectorAll(".callout").forEach((node2) => {
+ var _a;
+ const callout = node2.parentElement.createEl("table");
+ callout.addClass("callout-table", "callout");
+ callout.setAttribute("data-callout", (_a = node2.getAttribute("data-callout")) != null ? _a : "quote");
+ const headRow = callout.createEl("tr");
+ const headColumn = headRow.createEl("td");
+ headColumn.addClass("callout-title");
+ const title = node2.querySelector(".callout-title-inner");
+ if (title) {
+ const span = headColumn.createEl("span");
+ span.innerHTML = title.innerHTML;
+ }
+ const originalContent = node2.querySelector(".callout-content");
+ if (originalContent) {
+ const row = callout.createEl("tr");
+ const column = row.createEl("td");
+ column.innerHTML = originalContent.innerHTML;
+ }
+ node2.replaceWith(callout);
+ });
+ }
+ removeAllFootnotes(node) {
+ node.querySelectorAll("section.footnotes").forEach((section) => section.parentNode.removeChild(section));
+ node.querySelectorAll(".footnote-link").forEach((link) => {
+ link.parentNode.parentNode.removeChild(link.parentNode);
+ });
+ }
+ removeFootnoteLinks(node) {
+ node.querySelectorAll(".footnote-link").forEach((link) => {
+ const text = link.getText();
+ if (text === "\u21A9\uFE0E") {
+ link.parentNode.removeChild(link);
+ } else {
+ const span = link.parentNode.createEl("span", { text: link.getText(), cls: "footnote-link" });
+ link.parentNode.replaceChild(span, link);
+ }
+ });
+ }
+ async embedImages(node) {
+ const promises = [];
+ node.querySelectorAll("img").forEach((img) => {
+ if (img.src) {
+ if (img.src.startsWith("data:image/svg+xml") && this.options.convertSvgToBitmap) {
+ promises.push(this.replaceImageSource(img));
+ return;
+ }
+ if (!this.options.embedExternalLinks) {
+ const [scheme] = img.src.split(":", 1);
+ if (this.externalSchemes.includes(scheme.toLowerCase())) {
+ return;
+ } else {
+ }
+ }
+ if (!img.src.startsWith("data:")) {
+ promises.push(this.replaceImageSource(img));
+ return;
+ }
+ }
+ });
+ this.modal.progress.max = 100;
+ await allWithProgress(promises, (percentCompleted) => this.modal.progress.value = percentCompleted);
+ return node;
+ }
+ async renderSvg(node) {
+ const xmlSerializer = new XMLSerializer();
+ if (!this.options.convertSvgToBitmap) {
+ return node;
+ }
+ const promises = [];
+ const replaceSvg = async (svg) => {
+ const style = svg.querySelector("style") || svg.appendChild(document.createElement("style"));
+ style.innerHTML += MERMAID_STYLESHEET;
+ const svgAsString = xmlSerializer.serializeToString(svg);
+ const svgData = `data:image/svg+xml;base64,` + Buffer.from(svgAsString).toString("base64");
+ const dataUri = await this.imageToDataUri(svgData);
+ const img = svg.createEl("img");
+ img.style.cssText = svg.style.cssText;
+ img.src = dataUri;
+ svg.parentElement.replaceChild(img, svg);
+ };
+ node.querySelectorAll("svg").forEach((svg) => {
+ promises.push(replaceSvg(svg));
+ });
+ this.modal.progress.max = 0;
+ await allWithProgress(promises, (percentCompleted) => this.modal.progress.value = percentCompleted);
+ return node;
+ }
+ async replaceImageSource(image) {
+ const imageSourcePath = decodeURI(image.src);
+ if (imageSourcePath.startsWith(this.vaultLocalUriPrefix)) {
+ let path = imageSourcePath.substring(this.vaultLocalUriPrefix.length + 1).replace(/[?#].*/, "");
+ path = decodeURI(path);
+ const mimeType = this.guessMimeType(path);
+ const data = await this.readFromVault(path, mimeType);
+ if (this.isSvg(mimeType) && this.options.convertSvgToBitmap) {
+ image.src = await this.imageToDataUri(data);
+ } else {
+ image.src = data;
+ }
+ } else {
+ image.src = await this.imageToDataUri(image.src);
+ }
+ }
+ async imageToDataUri(url) {
+ const canvas = document.createElement("canvas");
+ const ctx = canvas.getContext("2d");
+ const image = new Image();
+ image.setAttribute("crossOrigin", "anonymous");
+ const dataUriPromise = new Promise((resolve, reject) => {
+ image.onload = () => {
+ canvas.width = image.naturalWidth;
+ canvas.height = image.naturalHeight;
+ ctx.drawImage(image, 0, 0);
+ try {
+ const uri = canvas.toDataURL("image/png");
+ resolve(uri);
+ } catch (err) {
+ console.log(`failed ${url}`, err);
+ resolve(url);
+ }
+ canvas.remove();
+ };
+ image.onerror = (err) => {
+ console.log("could not load data uri");
+ resolve(url);
+ };
+ });
+ image.src = url;
+ return dataUriPromise;
+ }
+ async readFromVault(path, mimeType) {
+ const tfile = this.app.vault.getAbstractFileByPath(path);
+ const data = await this.app.vault.readBinary(tfile);
+ return `data:${mimeType};base64,` + (0, import_obsidian.arrayBufferToBase64)(data);
+ }
+ guessMimeType(filePath) {
+ const extension = this.getExtension(filePath) || "png";
+ return this.mimeMap.get(extension) || `image/${extension}`;
+ }
+ getExtension(filePath) {
+ const fileName = filePath.slice(filePath.lastIndexOf("/") + 1);
+ return fileName.slice(fileName.lastIndexOf(".") + 1 || fileName.length).toLowerCase();
+ }
+ isSvg(mimeType) {
+ return mimeType === "image/svg+xml";
+ }
+};
+var CopyingToHtmlModal = class extends import_obsidian.Modal {
+ constructor(app) {
+ super(app);
+ }
+ get progress() {
+ return this._progress;
+ }
+ onOpen() {
+ const { titleEl, contentEl } = this;
+ titleEl.setText("Copying to clipboard");
+ this._progress = contentEl.createEl("progress");
+ this._progress.style.width = "100%";
+ }
+ onClose() {
+ const { contentEl } = this;
+ contentEl.empty();
+ }
+};
+var _CopyDocumentAsHTMLSettingsTab = class extends import_obsidian.PluginSettingTab {
+ constructor(app, plugin) {
+ super(app, plugin);
+ this.plugin = plugin;
+ this.plugin = plugin;
+ }
+ display() {
+ const { containerEl } = this;
+ containerEl.empty();
+ containerEl.createEl("h2", { text: "Copy document as HTML Settings" });
+ containerEl.createEl("h3", { text: "Compatibility" });
+ new import_obsidian.Setting(containerEl).setName("Convert SVG files to bitmap").setDesc("If checked, SVG files are converted to bitmap. This makes the copied documents heavier but improves compatibility (eg. with gmail).").addToggle((toggle) => toggle.setValue(this.plugin.settings.convertSvgToBitmap).onChange(async (value) => {
+ this.plugin.settings.convertSvgToBitmap = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Embed external images").setDesc("If checked, external images are downloaded and embedded. If unchecked, the resulting document may contain links to external resources").addToggle((toggle) => toggle.setValue(this.plugin.settings.embedExternalLinks).onChange(async (value) => {
+ this.plugin.settings.embedExternalLinks = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Render code with tables").setDesc("If checked code blocks are rendered as tables, which makes pasting into Google docs somewhat prettier.").addToggle((toggle) => toggle.setValue(this.plugin.settings.formatCodeWithTables).onChange(async (value) => {
+ this.plugin.settings.formatCodeWithTables = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Render callouts with tables").setDesc("If checked callouts are rendered as tables, which makes pasting into Google docs somewhat prettier.").addToggle((toggle) => toggle.setValue(this.plugin.settings.formatCalloutsWithTables).onChange(async (value) => {
+ this.plugin.settings.formatCalloutsWithTables = value;
+ await this.plugin.saveSettings();
+ }));
+ containerEl.createEl("h3", { text: "Rendering" });
+ new import_obsidian.Setting(containerEl).setName("Include filename as header").setDesc("If checked, the filename is inserted as a level 1 header. (only if an entire document is copied)").addToggle((toggle) => toggle.setValue(this.plugin.settings.fileNameAsHeader).onChange(async (value) => {
+ this.plugin.settings.fileNameAsHeader = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Copy HTML fragment only").setDesc("If checked, only generate a HTML fragment and not a full HTML document. This excludes the header, and effectively disables all styling.").addToggle((toggle) => toggle.setValue(this.plugin.settings.bareHtmlOnly).onChange(async (value) => {
+ this.plugin.settings.bareHtmlOnly = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Remove properties / front-matter sections").setDesc("If checked, the YAML content between --- lines at the front of the document are removed. If you don't know what this means, leave it on.").addToggle((toggle) => toggle.setValue(this.plugin.settings.removeFrontMatter).onChange(async (value) => {
+ this.plugin.settings.removeFrontMatter = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Remove dataview metadata lines").setDesc(_CopyDocumentAsHTMLSettingsTab.createFragmentWithHTML(`
+ Remove lines that only contain dataview meta-data, eg. "rating:: 9". Metadata between square brackets is left intact.
+ Current limitations are that lines starting with a space are not removed, and lines that look like metadata in code blocks are removed if they don't start with a space
`)).addToggle((toggle) => toggle.setValue(this.plugin.settings.removeDataviewMetadataLines).onChange(async (value) => {
+ this.plugin.settings.removeDataviewMetadataLines = value;
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Footnote handling").setDesc(_CopyDocumentAsHTMLSettingsTab.createFragmentWithHTML(`
+
+ - Remove everything: Remove references and links.
+ - Display only: leave reference and foot-note, but don't display as a link.
+ - Display and link: attempt to link the reference to the footnote, may not work depending on paste target.
+
`)).addDropdown((dropdown) => dropdown.addOption(0 /* REMOVE_ALL */.toString(), "Remove everything").addOption(2 /* REMOVE_LINK */.toString(), "Display only").addOption(1 /* LEAVE_LINK */.toString(), "Display and link").setValue(this.plugin.settings.footnoteHandling.toString()).onChange(async (value) => {
+ switch (value) {
+ case 3 /* TITLE_ATTRIBUTE */.toString():
+ this.plugin.settings.footnoteHandling = 3 /* TITLE_ATTRIBUTE */;
+ break;
+ case 0 /* REMOVE_ALL */.toString():
+ this.plugin.settings.footnoteHandling = 0 /* REMOVE_ALL */;
+ break;
+ case 2 /* REMOVE_LINK */.toString():
+ this.plugin.settings.footnoteHandling = 2 /* REMOVE_LINK */;
+ break;
+ case 1 /* LEAVE_LINK */.toString():
+ default:
+ this.plugin.settings.footnoteHandling = 1 /* LEAVE_LINK */;
+ break;
+ }
+ await this.plugin.saveSettings();
+ }));
+ new import_obsidian.Setting(containerEl).setName("Link handling").setDesc(_CopyDocumentAsHTMLSettingsTab.createFragmentWithHTML(`
+ This option controls how links to Obsidian documents and tags are handled.
+
+ - Don't link: only render the link title
+ - Open with Obsidian: convert the link to an obsidian:// URI
+ - Link to HTML: keep the link, but convert the extension to .html
+ - Leave as is: keep the generated link
+
`)).addDropdown((dropdown) => dropdown.addOption(0 /* CONVERT_TO_TEXT */.toString(), "Don't link").addOption(1 /* CONVERT_TO_OBSIDIAN_URI */.toString(), "Open with Obsidian").addOption(2 /* LINK_TO_HTML */.toString(), "Link to HTML").addOption(3 /* LEAVE_AS_IS */.toString(), "Leave as is").setValue(this.plugin.settings.internalLinkHandling.toString()).onChange(async (value) => {
+ switch (value) {
+ case 1 /* CONVERT_TO_OBSIDIAN_URI */.toString():
+ this.plugin.settings.internalLinkHandling = 1 /* CONVERT_TO_OBSIDIAN_URI */;
+ break;
+ case 2 /* LINK_TO_HTML */.toString():
+ this.plugin.settings.internalLinkHandling = 2 /* LINK_TO_HTML */;
+ break;
+ case 3 /* LEAVE_AS_IS */.toString():
+ this.plugin.settings.internalLinkHandling = 3 /* LEAVE_AS_IS */;
+ break;
+ case 0 /* CONVERT_TO_TEXT */.toString():
+ default:
+ this.plugin.settings.internalLinkHandling = 0 /* CONVERT_TO_TEXT */;
+ break;
+ }
+ await this.plugin.saveSettings();
+ }));
+ containerEl.createEl("h3", { text: "Custom templates (advanced)" });
+ const useCustomStylesheetSetting = new import_obsidian.Setting(containerEl).setName("Provide a custom stylesheet").setDesc("The default stylesheet provides minimalistic theming. You may want to customize it for better looks. Disabling this setting will restore the default stylesheet.");
+ const customStylesheetSetting = new import_obsidian.Setting(containerEl).setClass("customizable-text-setting").addTextArea((textArea) => textArea.setValue(this.plugin.settings.styleSheet).onChange(async (value) => {
+ this.plugin.settings.styleSheet = value;
+ await this.plugin.saveSettings();
+ }));
+ useCustomStylesheetSetting.addToggle((toggle) => {
+ customStylesheetSetting.settingEl.toggle(this.plugin.settings.useCustomStylesheet);
+ toggle.setValue(this.plugin.settings.useCustomStylesheet).onChange(async (value) => {
+ this.plugin.settings.useCustomStylesheet = value;
+ customStylesheetSetting.settingEl.toggle(this.plugin.settings.useCustomStylesheet);
+ if (!value) {
+ this.plugin.settings.styleSheet = DEFAULT_STYLESHEET;
+ }
+ await this.plugin.saveSettings();
+ });
+ });
+ const useCustomHtmlTemplateSetting = new import_obsidian.Setting(containerEl).setName("Provide a custom HTML template").setDesc(_CopyDocumentAsHTMLSettingsTab.createFragmentWithHTML(`For even more customization, you can
+provide a custom HTML template. Disabling this setting will restore the default template.
+Note that the template is not used if the "Copy HTML fragment only" setting is enabled.`));
+ const customHtmlTemplateSetting = new import_obsidian.Setting(containerEl).setDesc(_CopyDocumentAsHTMLSettingsTab.createFragmentWithHTML(`
+ The template should include the following placeholders :
+
+ \${title}: the document title
+ \${stylesheet}: the CSS stylesheet. The custom stylesheet will be applied if any is specified
+ \${MERMAID_STYLESHEET}: the CSS for mermaid diagrams
+ \${body}: the document body
+
`)).setClass("customizable-text-setting").addTextArea((textArea) => textArea.setValue(this.plugin.settings.htmlTemplate).onChange(async (value) => {
+ this.plugin.settings.htmlTemplate = value;
+ await this.plugin.saveSettings();
+ }));
+ useCustomHtmlTemplateSetting.addToggle((toggle) => {
+ customHtmlTemplateSetting.settingEl.toggle(this.plugin.settings.useCustomHtmlTemplate);
+ toggle.setValue(this.plugin.settings.useCustomHtmlTemplate).onChange(async (value) => {
+ this.plugin.settings.useCustomHtmlTemplate = value;
+ customHtmlTemplateSetting.settingEl.toggle(this.plugin.settings.useCustomHtmlTemplate);
+ if (!value) {
+ this.plugin.settings.htmlTemplate = DEFAULT_HTML_TEMPLATE;
+ }
+ await this.plugin.saveSettings();
+ });
+ });
+ containerEl.createEl("h3", { text: "Exotic / Developer options" });
+ new import_obsidian.Setting(containerEl).setName("Don't embed images").setDesc("When this option is enabled, images will not be embedded in the HTML document, but broken links will be left in place. This is not recommended.").addToggle((toggle) => toggle.setValue(this.plugin.settings.disableImageEmbedding).onChange(async (value) => {
+ this.plugin.settings.disableImageEmbedding = value;
+ await this.plugin.saveSettings();
+ }));
+ }
+};
+var CopyDocumentAsHTMLSettingsTab = _CopyDocumentAsHTMLSettingsTab;
+CopyDocumentAsHTMLSettingsTab.createFragmentWithHTML = (html) => createFragment((documentFragment) => documentFragment.createDiv().innerHTML = html);
+var DEFAULT_SETTINGS = {
+ removeFrontMatter: true,
+ convertSvgToBitmap: true,
+ useCustomStylesheet: false,
+ useCustomHtmlTemplate: false,
+ embedExternalLinks: false,
+ removeDataviewMetadataLines: false,
+ formatCodeWithTables: false,
+ formatCalloutsWithTables: false,
+ footnoteHandling: 2 /* REMOVE_LINK */,
+ internalLinkHandling: 0 /* CONVERT_TO_TEXT */,
+ styleSheet: DEFAULT_STYLESHEET,
+ htmlTemplate: DEFAULT_HTML_TEMPLATE,
+ bareHtmlOnly: false,
+ fileNameAsHeader: false,
+ disableImageEmbedding: false
+};
+var CopyDocumentAsHTMLPlugin = class extends import_obsidian.Plugin {
+ async onload() {
+ await this.loadSettings();
+ this.addCommand({
+ id: "smart-copy-as-html",
+ name: "Copy selection or document to clipboard",
+ checkCallback: this.buildCheckCallback((view) => this.copyFromView(view, view.editor.somethingSelected()))
+ });
+ this.addCommand({
+ id: "copy-as-html",
+ name: "Copy entire document to clipboard",
+ checkCallback: this.buildCheckCallback((view) => this.copyFromView(view, false))
+ });
+ this.addCommand({
+ id: "copy-selection-as-html",
+ name: "Copy current selection to clipboard",
+ checkCallback: this.buildCheckCallback((view) => this.copyFromView(view, true))
+ });
+ const beforeAllPostProcessor = this.registerMarkdownPostProcessor(async () => {
+ ppIsProcessing = true;
+ });
+ beforeAllPostProcessor.sortOrder = -1e4;
+ const afterAllPostProcessor = this.registerMarkdownPostProcessor(async () => {
+ ppLastBlockDate = Date.now();
+ ppIsProcessing = false;
+ });
+ afterAllPostProcessor.sortOrder = 1e4;
+ this.addSettingTab(new CopyDocumentAsHTMLSettingsTab(this.app, this));
+ this.setupEditorMenuEntry();
+ }
+ async loadSettings() {
+ this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
+ if (!this.settings.useCustomStylesheet) {
+ this.settings.styleSheet = DEFAULT_STYLESHEET;
+ }
+ if (!this.settings.useCustomHtmlTemplate) {
+ this.settings.htmlTemplate = DEFAULT_HTML_TEMPLATE;
+ }
+ }
+ async saveSettings() {
+ await this.saveData(this.settings);
+ }
+ buildCheckCallback(action) {
+ return (checking) => {
+ if (copyIsRunning) {
+ console.log("Document is already being copied");
+ return false;
+ }
+ const activeView = this.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView);
+ if (!activeView) {
+ console.log("Nothing to copy: No active markdown view");
+ return false;
+ }
+ if (!checking) {
+ action(activeView);
+ }
+ return true;
+ };
+ }
+ async copyFromView(activeView, onlySelected) {
+ if (!activeView.editor) {
+ console.error("No editor in active view, nothing to copy");
+ return;
+ }
+ if (!activeView.file) {
+ console.error("No file in active view, nothing to copy");
+ return;
+ }
+ const markdown = onlySelected ? activeView.editor.getSelection() : activeView.data;
+ const path = activeView.file.path;
+ const name = activeView.file.name;
+ return this.doCopy(markdown, path, name, !onlySelected);
+ }
+ async copyFromFile(file) {
+ if (!(file instanceof import_obsidian.TFile)) {
+ console.log(`cannot copy folder to HTML: ${file.path}`);
+ return;
+ }
+ if (file.extension.toLowerCase() !== "md") {
+ console.log(`cannot only copy .md files to HTML: ${file.path}`);
+ return;
+ }
+ const markdown = await file.vault.cachedRead(file);
+ return this.doCopy(markdown, file.path, file.name, true);
+ }
+ async doCopy(markdown, path, name, isFullDocument) {
+ console.log(`Copying "${path}" to clipboard...`);
+ const title = name.replace(/\.md$/i, "");
+ const copier = new DocumentRenderer(this.app, this.settings);
+ try {
+ copyIsRunning = true;
+ ppLastBlockDate = Date.now();
+ ppIsProcessing = true;
+ const htmlBody = await copier.renderDocument(markdown, path);
+ if (this.settings.fileNameAsHeader && isFullDocument) {
+ const h1 = htmlBody.createEl("h1");
+ h1.innerHTML = title;
+ htmlBody.insertBefore(h1, htmlBody.firstChild);
+ }
+ const htmlDocument = this.settings.bareHtmlOnly ? htmlBody.outerHTML : this.expandHtmlTemplate(htmlBody.outerHTML, title);
+ const data = new ClipboardItem({
+ "text/html": new Blob([htmlDocument], {
+ type: ["text/html", "text/plain"]
+ }),
+ "text/plain": new Blob([htmlDocument], {
+ type: "text/plain"
+ })
+ });
+ await navigator.clipboard.write([data]);
+ console.log(`Copied to clipboard as HTML`);
+ new import_obsidian.Notice(`Copied to clipboard as HTML`);
+ } catch (error) {
+ new import_obsidian.Notice(`copy failed: ${error}`);
+ console.error("copy failed", error);
+ } finally {
+ copyIsRunning = false;
+ }
+ }
+ expandHtmlTemplate(html, title) {
+ const template = this.settings.useCustomHtmlTemplate ? this.settings.htmlTemplate : DEFAULT_HTML_TEMPLATE;
+ return template.replace("${title}", title).replace("${body}", html).replace("${stylesheet}", this.settings.styleSheet).replace("${MERMAID_STYLESHEET}", MERMAID_STYLESHEET);
+ }
+ setupEditorMenuEntry() {
+ this.registerEvent(this.app.workspace.on("file-menu", (menu, file, view) => {
+ menu.addItem((item) => {
+ item.setTitle("Copy as HTML").setIcon("clipboard-copy").onClick(async () => {
+ return this.copyFromFile(file);
+ });
+ });
+ }));
+ }
+};
+
+/* nosourcemap */
\ No newline at end of file
diff --git a/.obsidian/plugins/copy-document-as-html/manifest.json b/.obsidian/plugins/copy-document-as-html/manifest.json
new file mode 100644
index 0000000..4b5d7c3
--- /dev/null
+++ b/.obsidian/plugins/copy-document-as-html/manifest.json
@@ -0,0 +1,10 @@
+{
+ "id": "copy-document-as-html",
+ "name": "Copy document as HTML",
+ "version": "0.8.1",
+ "minAppVersion": "1.6.3",
+ "description": "Copy the current document to clipboard as HTML, including images, diagrams etc...",
+ "author": "mvdkwast",
+ "authorUrl": "https://github.com/mvdkwast",
+ "isDesktopOnly": true
+}
diff --git a/.obsidian/plugins/copy-document-as-html/styles.css b/.obsidian/plugins/copy-document-as-html/styles.css
new file mode 100644
index 0000000..5853e4e
--- /dev/null
+++ b/.obsidian/plugins/copy-document-as-html/styles.css
@@ -0,0 +1,25 @@
+
+.customizable-text-setting {
+ display: flex;
+ flex-direction: column;
+ border: none;
+}
+
+.customizable-text-setting .setting-item-info {
+ width: 100%;
+ margin-left: 16px;
+}
+
+.customizable-text-setting .setting-item-info .setting-item-description {
+ margin-bottom: 16px;
+}
+
+.customizable-text-setting .setting-item-control {
+ width: 100%;
+ flex-direction: column;
+}
+
+.customizable-text-setting .setting-item-control textarea {
+ width: 100%;
+ height: 15em;
+}
diff --git a/2026-02-11_12-12-16.md b/2026-02-11_12-12-16.md
index 86edc35..851155a 100644
--- a/2026-02-11_12-12-16.md
+++ b/2026-02-11_12-12-16.md
@@ -18,30 +18,31 @@ yearly: "[[2026]]"
Hello Team,
-Below is a comprehensive list of means & methods for {Project Name}.
-Please confirm you have received this email and respond with any questions or comments.
+Below is a comprehensive list of means & methods for **1990 K Street**.
+Please confirm you have received this email
+and respond with any questions or comments.
* **Takeoff Request Stage:** Full Takeoff
-
+ %% Stage 1, Stage 1 + Units, Full takeoff %%
* **Delivery Method:** Plans & Specs
-
+ %% Plans & Specs, Design Build, Design Assist, P&S with Approved VE %%
* **Document Stage:** Permit
-
+ %% DD, CD, Permit, GMP, Bid, Awarded %%
* **Drawings Date:** 2025-12-05
-* **Project Manual Date:** 2025-10-29
-* **Proposal Date:** 2026-02-11
+* **Project Manual Date:** 2025-12-05
+* **Proposal Date:** 2026-01-22
-## Project Specification Callouts
+### Project Specification Callouts
-
+%% Put page of Drawing or PM after answer %%
-* **Conduit:**
- * EMT Fittings: Set-screw. _---Spec 260533.13 (p. 1423)_
-
+* **Conduit:**
+ * EMT Fittings: Set-screw _---Spec 260533.13 (p. 1423)_
+ %% GRC, coupling specs, etc. %%
-* **Wire:**
- * Material: Aluminum 100A and larger
- * Acceptable Manufacturers:
+* **Wire:**
+ * Material: Aluminum 100A and larger _---E021 "ALUMINUM FEEDER SCHEDULE" Note 1(b)_
+ * Acceptable Manufacturers: _---Spec 260519 (p. 1384)_
* Alpha Wire; Brand of Belden, Inc.
* Belden Inc.
* Cerro Wire LLC
@@ -52,10 +53,10 @@ Please confirm you have received this email and respond with any questions or co
* Southwire Company, LLC
* WESCO
-* **MC Cable:**
- * Application:
-
- * Acceptable Manufacturers:
+* **MC Cable:**
+ * Application: Concealed feeders and branch circuits _---Spec 260519 (p. 1389)_
+ %% Branch homeruns only; Not permitted %%
+ * Acceptable Manufacturers: _---Spec 260519 (p. 1385-1386)_
* AFC Cable Systems; Atkore International
* Alpha Wire; Brand of Belden, Inc.
* Belden Inc.
@@ -65,26 +66,29 @@ Please confirm you have received this email and respond with any questions or co
* Okonite Company
* Southwire Company, LLC
* WESCO
+ * ==Conductors: Copper _---Spec 260519 (p. 1386)_==
+ * ==Armor: Steel _---Spec 260519 (p. 1386)_==
+ * ==Jacket: PVC _---Spec 260519 (p. 1386)_==
-* **Steel Box Depth:**
+* **Steel Box Depth:**
* Telecom: 2-1/8" _---Spec 270500 (p. 1673)_
* Security: 2-1/8" _---Spec 280500 (p. 1753)_
* Other Applications: Not specified
-
+ %% 1-1/2", 2-1/8" %%
-* **Floor Boxes:**
- * Box Material:
-
- * Cover Material:
-
+* **Floor Boxes:** Sheet metal with brass or aluminum covers _---Spec 262719 (p. 1541)_
-* **Wiring Devices:**
+* **Wiring Devices:**
* Units:
-
+ * Current rating: Unspecified. Assuming 15A for takeoff.
+ * Standard/Decora: Unspecified. Assuming Toggle/Duplex for takeoff.
+ %% 15A Decora %%
* BOH/Common Areas:
-
+ * Current rating: Unspecified. Assuming 20A for takeoff.
+ * Standard/Decora: Unspecified. Assuming Toggle/Duplex for takeoff.
+ %% 20A Toggle/Duplex %%
-* **Switchboards:**
+* **Switchboards:**
* Acceptable Manufacturers: _---Spec 262413 (p. 1502)_
* ABB, Electrification Business
* Eaton
@@ -92,31 +96,38 @@ Please confirm you have received this email and respond with any questions or co
* Square D; Schneider Electric USA
* General Electric
* Bus Material: Aluminum _---Spec 262413 (p. 1503)_
- * Breaker Types:
-
- * AIC Ratings:
+ * Interrupting Current Rating: Not specified.
-* **Panelboards:**
+* **Distribution Panelboards:**
+ * Acceptable Manufacturers: _---Spec 262413 (p. 1514-1515)_
+ * Eaton
+ * Bus Material: Aluminum _---Spec 262413 (p. 1513)_
+ * Breaker Types: Bolt-on _---Spec 262413 (p. 1515)_
+ %% Snap-on, bolt on %%
+ * Interrupting Current Rating: Not specified.
+
+* **Load Centers:**
* Acceptable Manufacturers: _---Spec 262413 (p. 1514-1515)_
* ABB, Electrification Business
* Eaton
* Siemens Industry, Inc., Energy Management Division
* Square D; Schneider Electric USA
- * Bus Material:
- * Breaker Types:
-
- * ACI Ratings:
+ * Bus Material: Aluminum _---Spec 262413 (p. 1513)_
+ * Breaker Types: Plug-in _---Spec 262413 (p. 1515)_
+ %% Snap-on, bolt on %%
+ * Interrupting Current Rating: Not specified.
+ * ==Covers shall be factory-applied white paint.== _---Dwg. E401-E405 "ELECTRICAL DRAWING NOTES" (P)_
-* **Transformers:**
+* **Transformers:**
* Winding Material: Aluminum _---Spec 262213 (p. 1495)_
- * K-Rating: Not specified
-
+ * K-Rating: Not specified.
+ %% Windings AL or CU, K-rating %%
* **Generator:** (1) 600kW Diesel
- * Enclosure Specs: Level 2 Sound Attenuating Weatherproof Enclosure. _---Dwg. E014_
+ * Enclosure Specs: Level 2 Sound Attenuating Weatherproof Enclosure _---Dwg. E014_
* Remote Tank: None shown or specified.
- * Tank Size: 24hrs at 100% load. _---Spec 263213.13 (p. 1604)_
- * Load Banks: Internal, 50% load. _---Dwg. E014, Spec 263213.13 (p. 1608)_
+ * Tank Size: 24hrs at 100% load _---Spec 263213.13 (p. 1604)_
+ * Load Banks: Internal, 50% load _---Dwg. E014, Spec 263213.13 (p. 1608)_
* Acceptable Manufacturers: _---Spec 263213.13 (p. 1600)_
* Caterpillar, Inc.; Electric Power Division
* Cummins Power Generation
@@ -125,58 +136,91 @@ Please confirm you have received this email and respond with any questions or co
* Kohler Power Systems
* Rolls-Royce Solutions America Inc
-## Project Drawing/Detail Callouts
+### Project Drawing/Detail Callouts
-* **Describe conflicts between drawings / proposal:**
-
+Dwg. IDS-01A "OUTLET SPECIFICATIONS": Screwless Cover
-* **Cost drivers in details not shown elsewhere on plans:**
-*
+Dwg. IDS-01A "SWITCHING SPECIFICATIONS": Legrand Tru-Universal Rocker/Dimmers
+(Is this for Amenity/Common Areas?)
-## PDI System Execution Plan
+
+
+### PDI System Execution Plan
* **Primaries:** Conduit and wiring excluded. _---Proposal 2026-01-22, Ex. B, Exclusions, Line 27_
-
-* **Secondaries:** Wiring excluded. _---Proposal 2026-01-22, Ex. B, Exclusions, Line 28_
-
-* **Feeders:**
-
-* **Unit Subfeeds:** EMT-SS, MC OH; PVC UG
-
-* **Units:**
-
-* **Telecom:**
-
-* **EV Chargers:**
-
+ %% Installation only, (9) 6" PVC %%
+
+* **Secondaries:**
+ * Schedule 40 PVC UG; _---Proposal 2026-01-22, Ex. B, Inclusions Line 54-55_
+ * wiring excluded. _---Proposal 2026-01-22, Ex. B, Exclusions, Line 28_
+ %% PVC UG, GRC Stub-ups, AL %%
+
+* **Feeders:** PVC UG, EMT OH; AL 100A and larger; 2% voltage drop.
+ %% PVC UG, EMT OH, AL over 100A, 2% VD %%
+ %% Emergency Feeds MI Cable %%
+
+* **Unit Subfeeds:** MC OH; size per E025-E028 meter bank schedules; 3% voltage drop.
+ %% MC OH AL, VD per Chart on E5.01 %%
+
+* **Units:**
+ * DW/Disposal - Separate Circuit
+ * Range - \#6/3
+ * Kitchen Backsplash - Decora (Non-Combo Small Appliance Breakers)
+ * 120V Smokes
+ * EWH - \#8/2
+ * VRF HVAC
+ * 20A Toggle Switches
+ * 15A Duplex Receptacles
+ %% 15A Decora, Disposals, T-stat, Floor Boxes, Shade Control, Doorbells, Dimmer Switches, etc. %%
+
+* **Telecom:**
+ * 30" MSDE; _---T0.32/1 Note 3: "PRIMEX SOHOPRO P3000ND"_
+ * (1) 1" innerduct to IDF. _---Proposal 2026-01-22, Ex. B, General Requirements, Line 114_
+ %% 42" MSDE, No Cable Homeruns, (1) 1" Back to IDF, CAT6 with Stub-ups %%
+
+* **EV Chargers:** (2) dual circuit chargers with conduit, wire, data rough-in, and equipment.
+ %% (42) Conduit only, (56) Conduit & Wire, (20) Conduit, Wire & Equipment %%
+
* **Fire Alarm:** Devices PVC in-slab, Risers EMT.
-
-* **DAS:** System included
-
+ %% Free-air where allowed by code. EMT Risers. %%
+
+* **DAS:** System per PDI DAS Design.
+ %% Conduit only, Per PDI DAS Design %%
+
* **Low Voltage:** Free-air where allowed by code.
-
+ %% Free-air where allowed by code. Stub-ups to accessible ceilings. %%
-## Lighting Control
+### Lighting Control
-* **Scope:**
-
+* **Basis of Takeoff:** Design per Plans and Specs _---Christian Pereiro 2026-02-11_
+ %% Code Minimum per Energy Code Assigned, P&S, PDI Design %%
-* **Area:**
- * BOH:
- * Corridor:
- * Amenity:
- * Site/Landscape:
- * Garage Entry Point
- * Office:
+* **Area:** _---Dwg. E021 "AUTOMATED LIGHTING CONTROL - SEQUENCES OF OPERATIONS"_
+ * BOH: Line Voltage Control, no dimming
+ * Corridor: Digital Standalone Control, 0-10V dimming
+ * Amenity: Digital Standalone Control, 0-10V dimming
+ * Offices: Digital Standalone Control, 0-10V dimming, controlled receptacles as shown
+ * Site/Landscape: Line Voltage Control, no dimming
+ * Garage: Digital Standalone Control, 0-10V dimming
+ %% Assign Method to Areas: Line Voltage, Low-Voltage Stand Alone or Centralized System %%
-## Tasks/Quotes Needed for WBS
+Takeoff will utilize assemblies including
+conduit rough-in, Cat5e cable, and device labor.
-
+### Tasks/Quotes Needed for WBS
-
-* Electrical VDC
+%% Delete any completed %%
+
+%% * Electrical Constructability Review %%
+%% * Electrical VDC %%
* Coordination Study
-
+%% * DAS Public Safety Raceway Design %%