commit 4a9cfda0bdae45494fc9e1ce3f680e194a43c7aa Author: Henk Kalkwater Date: Wed Jun 24 10:08:28 2020 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b00a98c --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +.dub +docs.json +__dummy.html +docs/ +/mijnblog +mijnblog.so +mijnblog.dylib +mijnblog.dll +mijnblog.a +mijnblog.lib +mijnblog-test-* +*.exe +*.o +*.obj +*.lst diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..f5e21b4 --- /dev/null +++ b/default.nix @@ -0,0 +1,2 @@ +{ pkgs ? import {} }: +pkgs.callPackage ./mijnblog.nix {} diff --git a/dub.json b/dub.json new file mode 100644 index 0000000..9c4a598 --- /dev/null +++ b/dub.json @@ -0,0 +1,13 @@ +{ + "authors": [ + "Chris Josten" + ], + "copyright": "Copyright © 2019, Chris Josten", + "dependencies": { + "dyaml": "~>0.8.0", + "vibe-d": "~>0.8.6" + }, + "description": "A blog based on Markdown and JSON", + "license": "AGPLv3", + "name": "mijnblog" +} diff --git a/dub.selections.json b/dub.selections.json new file mode 100644 index 0000000..a285e5c --- /dev/null +++ b/dub.selections.json @@ -0,0 +1,21 @@ +{ + "fileVersion": 1, + "versions": { + "botan": "1.12.10", + "botan-math": "1.0.3", + "diet-ng": "1.6.0", + "dyaml": "0.8.0", + "eventcore": "0.8.48", + "fswatch": "0.5.0", + "libasync": "0.8.4", + "libevent": "2.0.2+2.0.16", + "memutils": "0.4.13", + "mir-linux-kernel": "1.0.1", + "openssl": "1.1.6+1.0.1g", + "stdx-allocator": "2.77.5", + "taggedalgebraic": "0.11.7", + "tinyendian": "0.2.0", + "vibe-core": "1.7.0", + "vibe-d": "0.8.6" + } +} diff --git a/dub.selections.json.bak b/dub.selections.json.bak new file mode 100644 index 0000000..25a798d --- /dev/null +++ b/dub.selections.json.bak @@ -0,0 +1,20 @@ +{ + "fileVersion": 1, + "versions": { + "botan": "1.12.10", + "botan-math": "1.0.3", + "diet-ng": "1.5.0", + "dyaml": "0.8.0", + "eventcore": "0.8.43", + "libasync": "0.8.4", + "libevent": "2.0.2+2.0.16", + "memutils": "0.4.13", + "mir-linux-kernel": "1.0.1", + "openssl": "1.1.6+1.0.1g", + "stdx-allocator": "2.77.5", + "taggedalgebraic": "0.11.4", + "tinyendian": "0.2.0", + "vibe-core": "1.6.2", + "vibe-d": "0.8.6" + } +} diff --git a/dub.selections.nix b/dub.selections.nix new file mode 100644 index 0000000..0f29e20 --- /dev/null +++ b/dub.selections.nix @@ -0,0 +1,194 @@ +# This file was generated by https://github.com/lionello/dub2nix v0.2.1 +[ { + fetch = { + type = "git"; + url = "https://github.com/D-Programming-Deimos/libevent.git"; + rev = "v2.0.2+2.0.16"; + sha256 = "1axv0pv5w26i61m191570ydfxb3gghgn8yh654qjyxi0cxvn92bf"; + fetchSubmodules = false; + date = "2016-11-29T18:50:57-08:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/hyv33akqdvhk978p1inmy0r64vimhrdl-libevent"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/kiith-sa/tinyendian.git"; + rev = "v0.2.0"; + sha256 = "086gf5aga52wr5rj2paq54daj8lafn980x77b706vvvqaz2mlis8"; + fetchSubmodules = false; + date = "2018-06-10T11:04:28+02:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/9c7fsmi5am84j6dq2mp3va306x3ay291-tinyendian"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/libmir/mir-linux-kernel.git"; + rev = "v1.0.1"; + sha256 = "1gcaavsni47352nvw9s41zkaswd582cafq3931i0zinhd9s3clag"; + fetchSubmodules = false; + date = "2018-08-04T16:03:31+07:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/qz6axwci8kb1477j9dzgq85nscjfyvj1-mir-linux-kernel"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/etcimon/botan-math.git"; + rev = "v1.0.3"; + sha256 = "0jbpgpd1sjkp5075xh0k7m4m2d3yahi5scx3ql35fj4yns2mn2fq"; + fetchSubmodules = false; + date = "2016-08-23T10:45:25-04:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/dic7r8jab936cgqc9fck032r49nvgv07-botan-math"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/etcimon/memutils.git"; + rev = "v0.4.13"; + sha256 = "12mssymhimfsw6flkchqg0ql3qrs91dlh88xjdw5il8rb4h4ddfz"; + fetchSubmodules = false; + date = "2018-10-09T11:51:45-04:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/hszwaxwm26bqp3h761j3kq1hsbs3hpra-memutils"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/s-ludwig/taggedalgebraic.git"; + rev = "v0.11.7"; + sha256 = "1q8pg3r1zw72114y76kgr73iylp77m4wrl180r6d632vc0x8r58f"; + fetchSubmodules = false; + date = "2019-11-01T09:00:47+01:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/x1qwbzxp7nx0fpwvr4v30j0nnwf6pjcx-taggedalgebraic"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/vibe-d/vibe-core.git"; + rev = "v1.7.0"; + sha256 = "0mp8daspzn0ww9jr6nf0zwdj6ff6j7l4j5h6h450z18zn7kjkd8x"; + fetchSubmodules = false; + date = "2019-09-17T23:40:53+02:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/g46p3lfzkcsrdcvxv25a2g2vhcfghdgr-vibe-core"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/vibe-d/vibe.d.git"; + rev = "v0.8.6"; + sha256 = "1zqan3rsjmkxnq8wxnzrj4vw912lnnp2fphzfz1sriyysj59b28f"; + fetchSubmodules = false; + date = "2019-10-03T17:14:48+02:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/wsskmj5cs3p6nlkfc80z8bm90nxxvy0n-vibe.d"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/wilzbach/stdx-allocator.git"; + rev = "v2.77.5"; + sha256 = "03av8zp5p6vf6fg005xbmwnjfw96jyrr4dcj4m56c4a3vx7v72pk"; + fetchSubmodules = false; + date = "2018-12-23T13:54:22+01:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/b3h25asfh205wzwjfzjf2k2kkccpp96k-stdx-allocator"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/etcimon/botan.git"; + rev = "v1.12.10"; + sha256 = "02zrq9wcb1hhsl9psgkvi65g6c7g990yy9d75gjgbz4b1wb61nwf"; + fetchSubmodules = false; + date = "2018-06-22T15:33:04-04:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/a1431sfkpz8dk0jlix5zn90g19av1lnc-botan"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/rejectedsoftware/diet-ng.git"; + rev = "v1.6.0"; + sha256 = "02pj2rf2qfi0acnw496nr480hj47ggy4isfhsvdajd6al4h03a6x"; + fetchSubmodules = false; + date = "2019-08-16T19:55:02+02:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/jld9bk9vr9k2pfb3li1zcvhilka8gdzl-diet-ng"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/WebFreak001/FSWatch.git"; + rev = "v0.5.0"; + sha256 = "1msv98hvxg1nr44yp8pm1as3byx0ibxfpr662564zdq5afci49fc"; + fetchSubmodules = false; + date = "2019-06-13T21:48:00+02:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/88dmp1a4cygp3phm1xb7m663jpqhih42-FSWatch"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/D-Programming-Deimos/openssl.git"; + rev = "v1.1.6+1.0.1g"; + sha256 = "0ramqjyq4v7xpqwf4nf4ddmsg6yk2fbzn2d1yj4b6dla3q5lv9i3"; + fetchSubmodules = false; + date = "2017-11-05T20:15:26+01:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/jbfb5in6gzqs2byn1hdc1625yh8sx6j2-openssl"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/vibe-d/eventcore.git"; + rev = "v0.8.48"; + sha256 = "1ifx4sr04x7mvw1w9g3n72szy83q487ya0yi212czys4bgwdvkiz"; + fetchSubmodules = false; + date = "2019-10-25T22:46:08+02:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/65g2z4y29z49cfjvan2dz01nyd4x5mdp-eventcore"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/kiith-sa/D-YAML.git"; + rev = "v0.8.0"; + sha256 = "1my9yck316q0kqalxkhfpffgvrfskin4qw3171md4iz3qbhwb799"; + fetchSubmodules = false; + date = "2019-05-26T20:26:26+02:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/v30av8a9fqrvhqz09qqiljbcr88dbx0z-D-YAML"; + }; +} { + fetch = { + type = "git"; + url = "https://github.com/etcimon/libasync.git"; + rev = "v0.8.4"; + sha256 = "13v3dg0838j9h377cs9bq2nk71nrchx6kix9mwiy0fhw7sf7nxb4"; + fetchSubmodules = false; + date = "2019-02-28T10:02:56-05:00"; + deepClone = false; + leaveDotGit = false; + path = "/nix/store/6b552a8zdl8z99gc11xgj95k52vwvlcw-libasync"; + }; +} ] \ No newline at end of file diff --git a/mijnblog.nix b/mijnblog.nix new file mode 100644 index 0000000..710b373 --- /dev/null +++ b/mijnblog.nix @@ -0,0 +1,12 @@ +{pkgs}: +with (import ./mkDub.nix { + inherit pkgs; +}); +mkDubDerivation { + src = ./.; + dubJSON = ./dub.json; + selections = ./dub.selections.nix; + version = "0.0.1"; + buildInputs = [ pkgs.openssl ]; + propagatedBuildInputs = [ pkgs.nix-prefetch-git ]; +} diff --git a/mkDub.nix b/mkDub.nix new file mode 100644 index 0000000..2600d30 --- /dev/null +++ b/mkDub.nix @@ -0,0 +1,121 @@ +{ pkgs ? import {}, + stdenv ? pkgs.stdenv, + rdmd ? pkgs.rdmd, + dmd ? pkgs.dmd, + dub ? pkgs.dub }: + +with stdenv; +let + # Filter function to remove the .dub package folder from src + filterDub = name: type: let baseName = baseNameOf (toString name); in ! ( + type == "directory" && baseName == ".dub" + ); + + # Convert a GIT rev string (tag) to a simple semver version + rev-to-version = builtins.replaceStrings ["v" "refs/tags/v"] ["" ""]; + + dep2src = dubDep: pkgs.fetchgit { inherit (dubDep.fetch) url rev sha256 fetchSubmodules; }; + + # Fetch a dependency (source only for now) + fromDub = dubDep: mkDerivation rec { + name = "${src.name}-${version}"; + version = rev-to-version dubDep.fetch.rev; + nativeBuildInputs = [ rdmd dmd dub ]; + src = dep2src dubDep; + + buildPhase = '' + runHook preBuild + export HOME=$PWD + dub build -b=release + runHook postBuild + ''; + + # outputs = [ "lib" ]; + + # installPhase = '' + # runHook preInstall + # mkdir -p $out/bin + # runHook postInstall + # ''; + }; + + # Adds a local package directory (e.g. a git repository) to Dub + dub-add-local = dubDep: "dub add-local ${(fromDub dubDep).src.outPath} ${rev-to-version dubDep.fetch.rev}"; + + # The target output of the Dub package + targetOf = package: "${package.targetPath or "."}/${package.targetName or package.name}"; + + # Remove reference to build tools and library sources + disallowedReferences = deps: [ dmd rdmd dub ] ++ builtins.map dep2src deps; + + removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}''; + +in { + inherit fromDub; + + mkDubDerivation = lib.makeOverridable ({ + src, + nativeBuildInputs ? [], + dubJSON ? src + "/dub.json", + selections ? src + "/dub.selections.nix", + deps ? import selections, + passthru ? {}, + package ? lib.importJSON dubJSON, + ... + } @ attrs: stdenv.mkDerivation (attrs // { + + pname = package.name; + + nativeBuildInputs = [ rdmd dmd dub pkgs.removeReferencesTo ] ++ nativeBuildInputs; + disallowedReferences = disallowedReferences deps; + + passthru = passthru // { + inherit dub dmd rdmd pkgs; + }; + + src = lib.cleanSourceWith { + filter = filterDub; + src = lib.cleanSource src; + }; + + preFixup = '' + find $out/bin -type f -exec ${removeExpr (disallowedReferences deps)} '{}' + || true + ''; + + buildPhase = '' + runHook preBuild + + export HOME=$PWD + ${lib.concatMapStringsSep "\n" dub-add-local deps} + dub build -b release --combined --skip-registry=all + + runHook postBuild + ''; + + checkPhase = '' + runHook preCheck + + export HOME=$PWD + ${lib.concatMapStringsSep "\n" dub-add-local deps} + dub test --combined --skip-registry=all + + runHook postCheck + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin + cp -r "${targetOf package}" $out/bin + + runHook postInstall + ''; + + meta = lib.optionalAttrs (package ? description) { + description = package.description; + } // attrs.meta or {}; + } // lib.optionalAttrs (!(attrs ? version)) { + # Use name from dub.json, unless pname and version are specified + name = package.name; + })); +} diff --git a/public/static/img/256x256 b/public/static/img/256x256 new file mode 100644 index 0000000..7a4bb2c Binary files /dev/null and b/public/static/img/256x256 differ diff --git a/public/static/img/chris-icoon.png b/public/static/img/chris-icoon.png new file mode 100644 index 0000000..b0b39da Binary files /dev/null and b/public/static/img/chris-icoon.png differ diff --git a/public/static/img/logo.gif b/public/static/img/logo.gif new file mode 100644 index 0000000..d732f65 Binary files /dev/null and b/public/static/img/logo.gif differ diff --git a/public/static/img/logo.png b/public/static/img/logo.png new file mode 100644 index 0000000..f54657c Binary files /dev/null and b/public/static/img/logo.png differ diff --git a/public/static/img/logo.png.bak b/public/static/img/logo.png.bak new file mode 100644 index 0000000..c2255b1 Binary files /dev/null and b/public/static/img/logo.png.bak differ diff --git a/public/static/script/prism.js b/public/static/script/prism.js new file mode 100644 index 0000000..66ca98c --- /dev/null +++ b/public/static/script/prism.js @@ -0,0 +1,1238 @@ +/* PrismJS 1.17.1 +https://prismjs.com/download.html#themes=prism-solarizedlight&languages=markup+css+clike+javascript+c+cpp+d+java+json&plugins=line-numbers */ +var _self = (typeof window !== 'undefined') + ? window // if in browser + : ( + (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) + ? self // if in worker + : {} // if in node js + ); + +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * MIT license http://www.opensource.org/licenses/mit-license.php/ + * @author Lea Verou http://lea.verou.me + */ + +var Prism = (function (_self){ + +// Private helper vars +var lang = /\blang(?:uage)?-([\w-]+)\b/i; +var uniqueId = 0; + +/** + * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class. + * + * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned. + * + * @param {Element} element + * @returns {string} + */ +function getLanguage(element) { + while (element && !lang.test(element.className)) { + element = element.parentNode; + } + if (element) { + return (element.className.match(lang) || [, 'none'])[1].toLowerCase(); + } + return 'none'; +} + + +var _ = { + manual: _self.Prism && _self.Prism.manual, + disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler, + util: { + encode: function (tokens) { + if (tokens instanceof Token) { + return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); + } else if (Array.isArray(tokens)) { + return tokens.map(_.util.encode); + } else { + return tokens.replace(/&/g, '&').replace(/ text.length) { + // Something went terribly wrong, ABORT, ABORT! + return; + } + + if (str instanceof Token) { + continue; + } + + if (greedy && i != strarr.length - 1) { + pattern.lastIndex = pos; + var match = pattern.exec(text); + if (!match) { + break; + } + + var from = match.index + (lookbehind && match[1] ? match[1].length : 0), + to = match.index + match[0].length, + k = i, + p = pos; + + for (var len = strarr.length; k < len && (p < to || (!strarr[k].type && !strarr[k - 1].greedy)); ++k) { + p += strarr[k].length; + // Move the index i to the element in strarr that is closest to from + if (from >= p) { + ++i; + pos = p; + } + } + + // If strarr[i] is a Token, then the match starts inside another Token, which is invalid + if (strarr[i] instanceof Token) { + continue; + } + + // Number of tokens to delete and replace with the new match + delNum = k - i; + str = text.slice(pos, p); + match.index -= pos; + } else { + pattern.lastIndex = 0; + + var match = pattern.exec(str), + delNum = 1; + } + + if (!match) { + if (oneshot) { + break; + } + + continue; + } + + if(lookbehind) { + lookbehindLength = match[1] ? match[1].length : 0; + } + + var from = match.index + lookbehindLength, + match = match[0].slice(lookbehindLength), + to = from + match.length, + before = str.slice(0, from), + after = str.slice(to); + + var args = [i, delNum]; + + if (before) { + ++i; + pos += before.length; + args.push(before); + } + + var wrapped = new Token(token, inside? _.tokenize(match, inside) : match, alias, match, greedy); + + args.push(wrapped); + + if (after) { + args.push(after); + } + + Array.prototype.splice.apply(strarr, args); + + if (delNum != 1) + _.matchGrammar(text, strarr, grammar, i, pos, true, token + ',' + j); + + if (oneshot) + break; + } + } + } + }, + + tokenize: function(text, grammar) { + var strarr = [text]; + + var rest = grammar.rest; + + if (rest) { + for (var token in rest) { + grammar[token] = rest[token]; + } + + delete grammar.rest; + } + + _.matchGrammar(text, strarr, grammar, 0, 0, false); + + return strarr; + }, + + hooks: { + all: {}, + + add: function (name, callback) { + var hooks = _.hooks.all; + + hooks[name] = hooks[name] || []; + + hooks[name].push(callback); + }, + + run: function (name, env) { + var callbacks = _.hooks.all[name]; + + if (!callbacks || !callbacks.length) { + return; + } + + for (var i=0, callback; callback = callbacks[i++];) { + callback(env); + } + } + }, + + Token: Token +}; + +_self.Prism = _; + +function Token(type, content, alias, matchedStr, greedy) { + this.type = type; + this.content = content; + this.alias = alias; + // Copy of the full string this token was created from + this.length = (matchedStr || '').length|0; + this.greedy = !!greedy; +} + +Token.stringify = function(o, language) { + if (typeof o == 'string') { + return o; + } + + if (Array.isArray(o)) { + return o.map(function(element) { + return Token.stringify(element, language); + }).join(''); + } + + var env = { + type: o.type, + content: Token.stringify(o.content, language), + tag: 'span', + classes: ['token', o.type], + attributes: {}, + language: language + }; + + if (o.alias) { + var aliases = Array.isArray(o.alias) ? o.alias : [o.alias]; + Array.prototype.push.apply(env.classes, aliases); + } + + _.hooks.run('wrap', env); + + var attributes = Object.keys(env.attributes).map(function(name) { + return name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; + }).join(' '); + + return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + (attributes ? ' ' + attributes : '') + '>' + env.content + ''; +}; + +if (!_self.document) { + if (!_self.addEventListener) { + // in Node.js + return _; + } + + if (!_.disableWorkerMessageHandler) { + // In worker + _self.addEventListener('message', function (evt) { + var message = JSON.parse(evt.data), + lang = message.language, + code = message.code, + immediateClose = message.immediateClose; + + _self.postMessage(_.highlight(code, _.languages[lang], lang)); + if (immediateClose) { + _self.close(); + } + }, false); + } + + return _; +} + +//Get current script and highlight +var script = document.currentScript || [].slice.call(document.getElementsByTagName('script')).pop(); + +if (script) { + _.filename = script.src; + + if (script.hasAttribute('data-manual')) { + _.manual = true; + } +} + +if (!_.manual) { + function highlightAutomaticallyCallback() { + if (!_.manual) { + _.highlightAll(); + } + } + + if(document.readyState !== 'loading') { + if (window.requestAnimationFrame) { + window.requestAnimationFrame(highlightAutomaticallyCallback); + } else { + window.setTimeout(highlightAutomaticallyCallback, 16); + } + } + else { + document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); + } +} + +return _; + +})(_self); + +if (typeof module !== 'undefined' && module.exports) { + module.exports = Prism; +} + +// hack for components to work correctly in node.js +if (typeof global !== 'undefined') { + global.Prism = Prism; +} +; +Prism.languages.markup = { + 'comment': //, + 'prolog': /<\?[\s\S]+?\?>/, + 'doctype': //i, + 'cdata': //i, + 'tag': { + pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/i, + greedy: true, + inside: { + 'tag': { + pattern: /^<\/?[^\s>\/]+/i, + inside: { + 'punctuation': /^<\/?/, + 'namespace': /^[^\s>\/:]+:/ + } + }, + 'attr-value': { + pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/i, + inside: { + 'punctuation': [ + /^=/, + { + pattern: /^(\s*)["']|["']$/, + lookbehind: true + } + ] + } + }, + 'punctuation': /\/?>/, + 'attr-name': { + pattern: /[^\s>\/]+/, + inside: { + 'namespace': /^[^\s>\/:]+:/ + } + } + + } + }, + 'entity': /&#?[\da-z]{1,8};/i +}; + +Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = + Prism.languages.markup['entity']; + +// Plugin to make entity title show the real entity, idea by Roman Komarov +Prism.hooks.add('wrap', function(env) { + + if (env.type === 'entity') { + env.attributes['title'] = env.content.replace(/&/, '&'); + } +}); + +Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { + /** + * Adds an inlined language to markup. + * + * An example of an inlined language is CSS with `