{"id":13426263,"url":"https://github.com/susam/texme","last_synced_at":"2025-05-14T23:07:21.148Z","repository":{"id":32684049,"uuid":"139605222","full_name":"susam/texme","owner":"susam","description":"Self-rendering Markdown + LaTeX documents","archived":false,"fork":false,"pushed_at":"2023-07-20T14:42:01.000Z","size":4107,"stargazers_count":2370,"open_issues_count":3,"forks_count":75,"subscribers_count":37,"default_branch":"main","last_synced_at":"2025-05-14T23:07:11.674Z","etag":null,"topics":["commonmark","html5","javascript","latex","markdown","markdown-latex","math","mathematics","mathjax","npm-package"],"latest_commit_sha":null,"homepage":"https://susam.github.io/texme/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/susam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"custom":["https://www.buymeacoffee.com/susam"]}},"created_at":"2018-07-03T15:42:28.000Z","updated_at":"2025-05-10T18:06:49.000Z","dependencies_parsed_at":"2023-01-14T21:55:29.409Z","dependency_job_id":"1b2bca13-3a46-4284-982e-2846545bfcfa","html_url":"https://github.com/susam/texme","commit_stats":{"total_commits":128,"total_committers":5,"mean_commits":25.6,"dds":0.203125,"last_synced_commit":"b97870404a6e3ba28c3b4491a339b57e0adc62b6"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ftexme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ftexme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ftexme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/susam%2Ftexme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/susam","download_url":"https://codeload.github.com/susam/texme/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243362,"owners_count":22038046,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["commonmark","html5","javascript","latex","markdown","markdown-latex","math","mathematics","mathjax","npm-package"],"created_at":"2024-07-31T00:01:30.370Z","updated_at":"2025-05-14T23:07:16.125Z","avatar_url":"https://github.com/susam.png","language":"JavaScript","readme":"TeXMe\n=====\n\nTeXMe is a lightweight JavaScript utility to create self-rendering\nMarkdown + LaTeX documents.\n\n[![View Demo][Demo SVG]][Demo URL]\n[![NPM Version][Version SVG]][NPM URL]\n[![JSDelivr Hits][JSDelivr SVG]][JSDelivr URL]\n[![MIT License][License SVG]][L]\n[![Twitter][Twitter SVG]][Twitter URL]\n[![Mastodon][Mastodon SVG]][Mastodon URL]\n\n[Demo SVG]: https://img.shields.io/badge/view-demo-brightgreen\n[Demo URL]: https://susam.github.io/texme/\n[Version SVG]: https://img.shields.io/npm/v/texme\n[NPM URL]: https://www.npmjs.com/package/texme\n[License SVG]: https://img.shields.io/badge/license-MIT-%233ea639\n[JSDelivr SVG]: https://data.jsdelivr.com/v1/package/npm/texme/badge?style=rounded\n[JSDelivr URL]: https://www.jsdelivr.com/package/npm/texme\n[Twitter SVG]: https://img.shields.io/badge/twitter-%40susam-%231d9bf0\n[Twitter URL]: https://twitter.com/susam\n[Mastodon SVG]: https://img.shields.io/badge/mastodon-%40susam-%236364ff\n[Mastodon URL]: https://mastodon.social/@susam\n\n\nContents\n--------\n\n* [Get Started](#get-started)\n* [CDN URLs](#cdn-urls)\n* [Valid HTML5](#valid-html5)\n* [Use TeXMe in Web Pages](#use-texme-in-web-pages)\n  * [Style](#style)\n  * [Render Markdown Without MathJax](#render-markdown-without-mathjax)\n  * [Skip Automatic Rendering on Load](#skip-automatic-rendering-on-load)\n  * [Set Options After Loading](#set-options-after-loading)\n  * [Content in Body](#content-in-body)\n* [Use TeXMe as a Library](#use-texme-as-a-library)\n  * [Install TeXMe](#install-texme)\n  * [Render Markdown and LaTeX](#render-markdown-and-latex)\n* [TeXMe API Documentation](#texme-api-documentation)\n* [Configuration Options](#configuration-options)\n* [Self-Hosting TeXMe](#self-hosting-texme)\n* [Markdown Priority Environment](#markdown-priority-environment)\n  * [Protect Dollar Sign in Code](#protect-dollar-sign-in-code)\n  * [Protect Dollar Sign in Image Description](#protect-dollar-sign-in-image-description)\n  * [Parsing Precedence](#parsing-precedence)\n  * [Unlimited Variants](#unlimited-variants)\n* [License](#license)\n* [Support](#support)\n* [Channels](#channels)\n* [More](#more)\n\n\nGet Started\n-----------\n\nCopy and paste the code below into an HTML file with `.html` as the\nextension name:\n\n```html\n\u003c!DOCTYPE html\u003e\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Euler's Identity\n\nIn mathematics, **Euler's identity** is the equality\n$$ e^{i \\pi} + 1 = 0. $$\n\n## Explanation\n\nEuler's identity is a special case of Euler's formula from complex\nanalysis, which states that for any real number $ x $,\n$$ e^{ix} = \\cos x + i \\sin x. $$\n```\n\nThis file contains one line of HTML code followed by Markdown + LaTeX\ncontent.\n\nOpen this HTML file with a web browser. It renders itself to look like this:\n[get-started.html](https://susam.github.io/texme/examples/get-started.html).\nHere is a screenshot of the output:\n\n![TeXMe Screenshot](https://i.imgur.com/hgKoyHJ.png)\n\nThere are three simple rules to remember while using TeXMe:\n\n  - TeXMe removes any leading and trailing whitespace in the content\n    before rendering the content to HTML.\n\n  - TeXMe uses the first non-empty line of the content to set the page\n    title if no explicit `\u003ctitle\u003e` element is specified. Any leading and\n    trailing whitespace and hash (`#`) characters are removed while\n    setting the page title.\n\n  - If there is a Markdown element such as code span/block or image with\n    LaTeX delimiters in it (e.g., `$`, `$$`, etc.), TeXMe may interpret\n    it as LaTeX which may lead to incorrect rendering of the document.\n    To prevent this issue, put such Markdown element within a special\n    purpose `md` environment supported by TeXMe, for example,\n    ``\\begin{md}`echo $foo`\\end{md}``. If you do not have such Markdown\n    elements with LaTeX delimiters, you may ignore this rule. See the\n    [Markdown Priority Environment](#markdown-priority-environment)\n    section to see more details about this. Note: For most documents,\n    you don't have to worry about this point.\n\nIf you do not like to start your document with HTML tags, you can write\nyour content first and add the `\u003cscript\u003e` tag in the end but this\napproach has some limitations. See the [Content in\nBody](#content-in-body) section for more details about it.\n\n\nCDN URLs\n--------\n\nUse the following URL in the `\u003cscript\u003e` tag to load version 1.2.2 (the\ncurrent version at this time) of TeXMe:\n\n```\nhttps://cdn.jsdelivr.net/npm/texme@1.2.2\n```\n\nUse the following URL in the `\u003cscript\u003e` tag to always load the latest\nversion of TeXMe:\n\n```\nhttps://cdn.jsdelivr.net/npm/texme\n```\n\nIf you need something really easy to remember, use this URL to load the\nlatest version of TeXMe:\n\n```\nhttps://unpkg.com/texme\n```\n\n\nValid HTML5\n-----------\n\nThe [Get Started](#get-started) section earlier shows how we can create\na self-rendering document with a single line of HTML code but this\nbrevity comes at the cost of standard conformance. For example, the\nrequired `\u003ctitle\u003e` element is missing from the code. Further the\n`\u003ctextarea\u003e` element is not closed.\n\nFor the sake of completeness and correctness, here is a minimal but\ncomplete and valid HTML5 example:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003ctitle\u003eNotes on Euler's Identity\u003c/title\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\n\u003ctextarea\u003e\n\n# Euler's Identity\n\nIn mathematics, **Euler's identity** is the equality\n$$ e^{i \\pi} + 1 = 0. $$\n\n## Explanation\n\nEuler's identity is a special case of Euler's formula from complex\nanalysis, which states that for any real number $ x $,\n$$ e^{ix} = \\cos x + i \\sin x. $$\n\n\u003c/textarea\u003e\n```\n\nHere is the output:\n[valid-html5.html](https://susam.github.io/texme/examples/valid-html5.html).\n\nIt has a few more lines of code to ensure that this HTML5 code validates\nsuccessfully at [validator.w3.org][VALIDATOR]. As a result, this example\ndoes not look as concise as the one in the previous section.\n\nIn case you are wondering, a valid HTML5 document does not require\nexplicit `\u003chead\u003e`, `\u003cbody\u003e`, or the closing `\u003c/html\u003e` tags, so they have\nbeen omitted for the sake of brevity while maintaining completeness and\ncorrectness.\n\nIn practice though, it is not necessary to write verbose code like this.\nAll browsers follow the [robustness principle][ROBUSTNESS], so they\ncan render the shorter example in the [Get Started](#get-started)\nsection just fine.\n\n[VALIDATOR]: https://validator.w3.org/#validate_by_input\n[ROBUSTNESS]: https://en.wikipedia.org/wiki/Robustness_principle\n\n\nUse TeXMe in Web Pages\n----------------------\n\n### Style\n\nTeXMe renders the document on a white pane against a gray background by\ndefault. This is due to a configuration option named `style` that is set\nto `'viewer'` by default.\n\nTo render the document with a minimal style on a completely plain white\nbackground, set the `style` configuration option to `'plain'`. Here is\nan example:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003cscript\u003ewindow.texme = { style: 'plain' }\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Euler's Identity\n\nIn mathematics, **Euler's identity** is the equality\n$$ e^{i \\pi} + 1 = 0. $$\n\n## Explanation\n\nEuler's identity is a special case of Euler's formula from complex\nanalysis, which states that for any real number $ x $,\n$$ e^{ix} = \\cos x + i \\sin x. $$\n```\n\nHere is the output:\n[style-plain.html](https://susam.github.io/texme/examples/style-plain.html).\n\nTo render the document with absolutely no style, set `style` to\n`'none'`. The `'none'` style option is useful to disable the default\n`'viewer'` style set by TeXMe before defining a custom style with\nregular CSS code. Here is an example:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003cscript\u003ewindow.texme = { style: 'none' }\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\n\u003cstyle\u003e\nbody {\n  background: lightcyan;\n}\nmain {\n  max-width: 20em;\n  padding: 1em;\n  border: medium double gray;\n  margin: 2em auto;\n  background: lightyellow;\n}\n\u003c/style\u003e\n\u003ctextarea\u003e\n\n# Euler's Identity\n\nIn mathematics, **Euler's identity** is the equality\n$$ e^{i \\pi} + 1 = 0. $$\n\n## Explanation\n\nEuler's identity is a special case of Euler's formula from complex\nanalysis, which states that for any real number $ x $,\n$$ e^{ix} = \\cos x + i \\sin x. $$\n```\n\nHere is the output:\n[style-custom.html](https://susam.github.io/texme/examples/style-custom.html).\n\nNote that the rendered content is displayed within a `\u003cmain\u003e` element\ninside the `\u003cbody\u003e`. That is why these elements are being styled in the\nabove example.\n\n\n### Render Markdown Without MathJax\n\nTo render Markdown-only content without any mathematical content at all,\nset `useMathJax` and `protectMath` options to `false`:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003cscript\u003ewindow.texme = { useMathJax: false, protectMath: false }\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Atomic Theory\n\n**Atomic theory** is a scientific theory of the nature of matter, which\nstates that matter is composed of discrete units called *atoms*. It\nbegan as a philosophical concept in ancient Greece and entered the\nscientific mainstream in the early 19th century when discoveries in the\nfield of chemistry showed that matter did indeed behave as if it were\nmade up of atoms.\n```\n\nHere is the output:\n[markdown-only.html](https://susam.github.io/texme/examples/markdown-only.html).\n\n\n### Skip Automatic Rendering on Load\n\nWhen TeXMe loads, it begins rendering the document automatically. This\nautomatic rendering may be skipped by setting `renderOnLoad` option to\n`false`. Here is an example that disables automatic rendering and then\ninvokes rendering later on the click of a button by using the\n`texme.renderPage()` function from the TeXMe API:\n```html\n\u003c!DOCTYPE html\u003e\n\u003cscript\u003ewindow.texme = { renderOnLoad: false }\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\n\u003cscript\u003e\nwindow.onload = function () {\n  var button = document.getElementById('button')\n  button.onclick = function () {\n    button.remove()\n    texme.renderPage()\n  }\n}\n\u003c/script\u003e\n\u003ctextarea\u003e\n\n# Euler's Identity\n\nIn mathematics, **Euler's identity** is the equality\n$$ e^{i \\pi} + 1 = 0. $$\n\n## Explanation\n\nEuler's identity is a special case of Euler's formula from complex\nanalysis, which states that for any real number $ x $,\n$$ e^{ix} = \\cos x + i \\sin x. $$\n\n\u003c/textarea\u003e\n\u003cdiv\u003e\u003cbutton id=\"button\"\u003eRender\u003c/button\u003e\u003c/div\u003e\n```\n\nHere is the output:\n[skip-render.html](https://susam.github.io/texme/examples/skip-render.html).\n\n\n### Set Options After Loading\n\nWhen we load TeXMe with the `\u003cscript\u003e` tag, it begins rendering the\ndocument as soon as it loads. Therefore in the above examples, we define\nthe configuration options prior to loading TeXMe. We do this by defining\nan object named `window.texme` with the configuration options defined as\nproperties in this project.\n\nHowever if we set the `renderOnLoad` option to `false`, we prevent TeXMe\nfrom rendering the document after it loads. We now have the control to\ninvoke the rendering at a later time, e.g., on the click of a button. In\nthis case, it is possible to set configuration options after loading\nTeXMe with the `texme.setOption()` function. This function takes two\nparameters: option name as a string and option value.\n\nHere is an example that skips automatic rendering on load and sets the\nstyle to `'plain'` using this function:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003cscript\u003ewindow.texme = { renderOnLoad: false }\u003c/script\u003e\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\n\u003cscript\u003e\nwindow.onload = function () {\n  var button = document.getElementById('button')\n  button.onclick = function () {\n    button.remove()\n    texme.setOption('style', 'plain')\n    texme.renderPage()\n  }\n}\n\u003c/script\u003e\n\u003ctextarea\u003e\n\n# Euler's Identity\n\nIn mathematics, **Euler's identity** is the equality\n$$ e^{i \\pi} + 1 = 0. $$\n\n## Explanation\n\nEuler's identity is a special case of Euler's formula from complex\nanalysis, which states that for any real number $ x $,\n$$ e^{ix} = \\cos x + i \\sin x. $$\n\n\u003c/textarea\u003e\n\u003cdiv\u003e\u003cbutton id=\"button\"\u003eRender\u003c/button\u003e\u003c/div\u003e\n```\n\nHere is the output:\n[set-options.html](https://susam.github.io/texme/examples/set-options.html).\n\n\n### Content in Body\n\nIf you do not like to start your document with HTML tags, you can\nwrite your content first and add the `\u003cscript\u003e` tag in the end like\nthis:\n\n```html\n# Euler's Identity\n\nIn mathematics, **Euler's identity** is the equality\n$$ e^{i \\pi} + 1 = 0. $$\n\n## Explanation\n\nEuler's identity is a special case of Euler's formula from complex\nanalysis, which states that for any real number $ x $,\n$$ e^{ix} = \\cos x + i \\sin x. $$\n\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\n```\n\nHere is the output:\n[content-in-body.html](https://susam.github.io/texme/examples/content-in-body.html).\n\nAlthough, the code looks neater in this example, there is a limitation\nassociated with this form of writing content: Since the content is part\nof the HTML `\u003cbody\u003e` element (there is no `\u003ctextarea\u003e` element in this\ncode), the content should be written carefully, so that it does not have\nany HTML syntax error.\n\n\n#### Caveats\n\nWhile using the content-in-body method of using TeXMe, an HTML syntax\nerror in the content can produced mangled output. For example, the\nfollowing input is not rendered as expected because the content is in\nthe `\u003cbody\u003e` element, so the browser interprets this content as HTML and\nencounters the beginning of a start tag that is not closed properly:\n\n````html\nHere is some unusual code:\n\n```\nprint('unusual \u003cstring')\n```\n\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\n````\n\nHere is the broken output:\n[unusual-code-body.html](https://susam.github.io/texme/examples/unusual-code-body.html).\n\nThe `\u003cstring` part of the code is interpreted as the opening of a start\ntag by the browser. What looks like a fragment of Python code to a human\nends up being parsed as an HTML tag by the browser that looks like this:\n\n\n````html\n\u003cstring') ```=\"\" \u003cscript=\"\" src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\n````\n\nThis mangled form of the input is then rendered leading to unexpected\nresults. To resolve this, put the content within a `\u003ctextarea\u003e` element\n(as shown in the very first example in this document). The following\ninput is fine because the content is put inside a `\u003ctextarea\u003e` element.\n\n````html\n\u003c!DOCTYPE html\u003e\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\nHere is some unusual code:\n\n```\nprint('unusual \u003cstring')\n```\n````\n\nHere is the output:\n[unusual-code-textarea.html](https://susam.github.io/texme/examples/unusual-code-textarea.html).\n\nSince the content occurs within the `\u003ctextarea\u003e` element, the browser\ndoes not parse it as HTML and therefore does not mangle it.\n\n\nUse TeXMe as a Library\n----------------------\n\nThe examples so far use TeXMe as a utility. The previous examples load\nTeXMe in a web page and then TeXMe automatically picks the `\u003ctextarea\u003e`\nelement containing Markdown + LaTeX code and renders it as HTML.\n\nIn this section, we see how to use TeXMe as a library and invoke its\nfunctions. These examples would run as is on Node.js.\n\n\n### Install TeXMe\n\nEnter the following command to install TeXMe:\n\n```shell\nnpm install texme\n```\n\n\n### Render Markdown and LaTeX\n\nMarkdown + LaTeX content can be rendered to HTML by simply invoking the\n`texme.render()` function. It accepts the Markdown + LaTeX content as\na string and returns the rendered HTML as a string. Here is an example:\n\n```javascript\nvar texme = require('texme')\nvar input = '**Foo** $$ {a}_{1} {a}_{2} $$'\nvar output = texme.render(input)\nconsole.log(output)\n```\n\nThe above example produces the following output:\n\n```html\n\u003cp\u003e\u003cstrong\u003eFoo\u003c/strong\u003e $$ {a}_{1} {a}_{2} $$\u003c/p\u003e\n```\n\n\nTeXMe API Documentation\n-----------------------\n\nThe previous two sections introduced a few TeXMe API functions such as\n`texme.render()`, `texme.renderPage()`, and `texme.setOptions()`.\nTeXMe exposes several more functions that could be useful to invoke\nparts of TeXMe's rendering operations in your code. Visit [TeXMe module\ndocumentation][API Doc] to see the documentation of TeXMe API.\n\n[API Doc]: https://susam.github.io/texme/doc/module-texme.html\n\n\nConfiguration Options\n---------------------\n\nHere is a quick reference for all the supported configuration options:\n\n  - `useMathJax` (`true` by default): Load MathJax and run it to render\n    LaTeX when set to `true`. Do not load or run MathJax when set to\n    `false`.\n\n  - `protectMath` (`true` by default): Prevent Markdown renderer from\n    seeing LaTeX code when set to `true`. Therefore LaTeX content\n    that may contain text that could be interpreted as Markdown\n    (e.g., `$$ {a}_{1} {a}_{2} $$`) remains intact as LaTeX when set to\n    `true`. Let Markdown renderer look for Markdown text within LaTeX\n    code and render it when set to `false`. For example,\n    `$$ {a}_{1} {a}_{2} $$` is rendered as\n    `\u003cp\u003e$$ {a}\u003cem\u003e{1} {a}\u003c/em\u003e{2} $$\u003c/p\u003e` when this option is set to\n    `false`.\n\n  - `style` (`'viewer'` by default): Three values are supported:\n    `'viewer'`, `'plain'`, and `'none'`. The viewer style displays\n    the rendered document on a white pane against a gray background. The\n    plain style displays the content with a very minimal style that does\n    not change the background style. If set to `'none'`, no style\n    whatsoever is applied and the document is displayed with the\n    browser's default style.\n\n  - `renderOnLoad` (`true` by default): Begins rendering the document\n    automatically on load when set to `true`. Skips rendering\n    automatically when set to `false`.\n\n  - `onRenderPage` (`undefined` by default): A callback function that is\n    automatically invoked after TeXMe completes rendering the page. It\n    is guaranteed that TeXMe has completed rendering the page before\n    invoking this callback. If `useMathJax` option is `true`, it is also\n    guaranteed that TeXMe has invoked typesetting LaTeX with MathJax\n    before invoking this callback. However it is not guaranteed that\n    MathJax has completed typesetting the page before this callback is\n    invoked. MathJax typesetting occurs asynchronously and may complete\n    after this callback is invoked. This callback runs only when the\n    `texme.renderPage()` function runs in web browser either due to\n    automatic rendering on load or due to explicit call to this\n    function.\n\n  - `markdownURL` (CDN URL of minified marked.js by default): URL to\n    load marked.js while running in a web browser.\n\n  - `MathJaxURL` (CDN URL of MathJax by default): URL to load MathJax\n    while running in a web browser.\n\n\nSelf-Hosting TeXMe\n------------------\n\nTeXMe can be saved on a local disk or hosted on one's own web server\nsuch that TeXMe does not load resources from any other web server\nwhile rendering a document. Here are the steps to set up TeXMe on a\nlocal disk or on one's own web server:\n\n 1. Clone copies of TeXMe and its dependencies to your own system or\n    server at a location from where you want to serve the files:\n\n    ```sh\n    git clone https://github.com/susam/texme.git\n    git clone https://github.com/markedjs/marked.git\n    git clone https://github.com/mathjax/mathjax.git\n    ```\n\n 2. Then create a self-rendering document, say, `euler.html` like\n    this:\n\n    ```html\n    \u003c!DOCTYPE html\u003e\n    \u003cscript\u003e\n    window.texme = {\n      markdownURL: 'marked/marked.min.js',\n      MathJaxURL: 'mathjax/es5/tex-mml-chtml.js'\n    }\n    \u003c/script\u003e\n    \u003cscript src=\"texme/texme.min.js\"\u003e\u003c/script\u003e\n    \u003ctextarea\u003e\n\n    # Euler's Identity\n\n    In mathematics, **Euler's identity** is the equality\n    $$ e^{i \\pi} + 1 = 0. $$\n\n    ## Explanation\n\n    Euler's identity is a special case of Euler's formula from complex\n    analysis, which states that for any real number $ x $,\n    $$ e^{ix} = \\cos x + i \\sin x. $$\n\n    \u003c/textarea\u003e\n    ```\n\n 3. Now open `euler.html` with a web browser and it should self-render\n    fine. All resources will be loaded from the local disk.\n\n 4. Now test `euler.html` by serving it via a web server. Assuming\n    Python 3 is installed, here is one really easy way to test it:\n\n    ```sh\n    python3 -m http.server\n    ```\n\n    Then open `https://localhost:8000/euler.html` using a web server.\n    The network tab in the browser's developer tools should show that\n    all resources are loaded from the same web server and no requests\n    to any other server are made.\n\n\nMarkdown Priority Environment\n-----------------------------\n\nTeXMe provides a special LaTeX-like environment named `md`. This is the\n*markdown priority environment*. We will see what this term means in the\nnext section. Let us first see what this environment does by looking at\na few examples of when this special environment can be useful.\n\nTeXMe introduces the special purpose `md` environment to protect\nportions of Markdown content from being interpreted as LaTeX. In most\ndocuments, the use of this environment is *not required*. This\nenvironment is useful only in a handful of scenarios where a Markdown\nelement like code span, code block, link, image, etc. may contain\ncontent with LaTeX delimiters that may get interpreted as LaTeX by TeXMe\nthereby leading to a broken rendering of the Markdown element. This\nenvironment protects the content of one or more Markdown elements from\nbeing interpreted as LaTeX. Let us see a few examples in the next two\nsubsections.\n\n\n### Protect Dollar Sign in Code\n\nThe `md` environment is useful when Markdown code spans or code blocks\ncontain LaTeX delimiters. This environment prevents the content of\nMarkdown code spans and code blocks from being interpreted as LaTeX.\nHere is an example:\n\n````html\n\u003c!DOCTYPE html\u003e\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Using Variables\n\nTo expand a variable in shell script, prefix the variable name with a\ndollar sign. For example:\n\n```\nfoo=hello\necho $foo\n```\n\nThe variable `$foo` is substituted with its value, if any, after the\nexpansion. In the above example, `$foo` expands to the string `hello`,\nso the output looks like this:\n\n```\nhello\n```\n````\n\nThe above code fails to render as expected because the TeXMe tokenizer\nparses out everything between `$foo` and `` `$ `` (inclusive)\nand interprets it as possible LaTeX code and prevents the Markdown\nparser from seeing it. As a result, the Markdown parser does not see the\ntriple backticks (```` ``` ````) just after `echo $foo` and the document\ngets rendered in an unexpected manner. Here is how the output looks:\n[shell-script-unprotected.html](https://susam.github.io/texme/examples/shell-script-unprotected.html).\n\nA rendering issue like this can be prevented with the use of the\nmarkdown priority environment like this:\n\n````html\n\u003c!DOCTYPE html\u003e\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Using Variables\n\nTo expand a variable in shell script, prefix the variable name with a\ndollar sign. For example:\n\n\\begin{md}\n```\nfoo=hello\necho $foo\n```\n\\end{md}\n\nThe variable \\begin{md}`$foo`\\end{md} is substituted with its value, if\nany, after the expansion. In the above example, \\begin{md}`$foo`\\end{md}\nexpands to `hello`, so the output looks like this:\n\n```\nhello\n```\n````\n\nThe `\\begin{md}` and `\\end{md}` delimiters create a markdown priority\nenvironment that prevents TeXMe from interpreting anything within it as\nLaTeX. Here is how the output looks now:\n[shell-script-protected.html](https://susam.github.io/texme/examples/shell-script-protected.html).\n\n\n### Protect Dollar Sign in Image Description\n\nHere is another example that shows how rendering can break when LaTeX\ndelimiter is found in a Markdown element such as within image\ndescription and how the usage of the `md` environment can fix it. Here\nis an example:\n\n```html\n\u003c!DOCTYPE html\u003e\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Metasyntactic Variable\n\n![Screenshot of variable $foo assigned and echoed in shell][1]\n\nThe screenshot above shows an example usage of a metasyntactic variable\n`$foo` in an interactive shell session.\n\n[1]: https://i.imgur.com/iQx46hd.png\n```\n\nThe above input fails to render as expected because the TeXMe tokenizer\nparses out everything between the first occurrence of `$foo` within the\nimage description and the next occurrence of `` `$ `` (inclusive). As a\nresult, the Markdown parser does not see the closing bracket of the\nimage description and does not recognize the image element. This leads\nto a broken rendering of the document. Here is how the output looks:\n[img-alt-unprotected.html](https://susam.github.io/texme/examples/img-alt-unprotected.html).\n\nThe `md` environment can be used to fix the rendering like this:\n\n```html\n\u003c!DOCTYPE html\u003e\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Metasyntactic Variable\n\n\\begin{md}\n![Screenshot of variable $foo assigned and echoed in shell][1]\n\\end{md}\n\nThe screenshot above shows an example usage of a metasyntactic variable\n\\begin{md}`$foo`\\end{md} in an interactive shell session.\n\n[1]: https://i.imgur.com/iQx46hd.png\n```\n\nHere is how the output looks now:\n[img-alt-protected.html](https://susam.github.io/texme/examples/img-alt-protected.html).\n\n\n### Parsing Precedence\n\nIn this subsection, we dive a little deeper into what the `md`\nenvironment is. First, we need to understand how TeXMe renders a\ndocument. TeXMe performs the following steps while rendering a document:\n\n 1. At first, the tokenizer looks for anything that looks like LaTeX and\n    masks them, that is, it substitutes all LaTeX snippets in the\n    content with mask literal. In case you are curious, the mask literal\n    is `::MASK::` but this detail should not matter to you while using\n    TeXMe.\n\n 2. Then it feeds the masked input to Markdown parser. The Markdown\n    parser cannot see any LaTeX code anymore because they are all\n    masked, so it cannot accidentally render any portion of the LaTeX\n    code as Markdown. The Markdown parser returns a rendered HTML.\n\n 3. The rendered HTML is then unmasked, that is, all mask literals in\n    the rendered HTML are substituted with the original LaTeX\n    snippets.\n\n 4. At this point, TeXMe rendering is complete. Now TeXMe invokes\n    MathJax to render all LaTeX content in the HTML obtained from\n    the previous step.\n\nIt is important to note that TeXMe does not implement a Markdown\nparser of its own. It relies on an existing popular and stable\nMarkdown parser that conforms to the GitHub Flavored Markdown (GFM)\nspecification and has stood the test of time. Note that GFM is a\nstrict superset of CommonMark. TeXMe only parses out content within\nLaTeX delimiters and masks it, so that the Markdown parser cannot see\nsuch content. As a result of this, step 1 can be a problem when there\nare LaTeX delimiters like `$`, `$$`, etc. within a Markdown code\nspan/block. The TeXMe tokenizer interprets the delimiter and the\ncontent after it as LaTeX if it finds the corresponding closing\ndelimiter too later in the document.  This can break the Markdown\nrendering of the code span/block. An example of this was discussed in\nthe previous section. This issue occurs because TeXMe parses out and\nmasks the LaTeX snippet before invoking the Markdown parser. The `md`\nenvironment prevents TeXMe from looking for LaTeX content within the\nenvironment.\n\nThe `md` environment ensures that anything within `\\begin{md}` and\n`\\end{md}` is not searched for LaTeX delimiters. Anything within this\nenvironment is fed to the Markdown parser intact. This is why this\nenvironment is known as the Markdown priority environment.\n\n\n### Unlimited Variants\n\nIn the previous two subsections we saw how the Markdown priority\nenvironment, that is, the `md` environment is used and what it does but\nthat is not the entire story. TeXMe provides an unlimited number of\nvariants of the `md` environment. In fact, any environment name that\nstarts with the string `md` is a Markdown priority environment, that is,\nall of `\\begin{md*}`, `\\begin{md**}`, `\\begin{mdfoo}`, `\\begin{mdbar}`,\netc. start Markdown priority environments provided the corresponding\n`\\end` commands also exist. The `\\end` command for a Markdown priority\nenvironment must use the exact same environment name as the `\\begin`\ndelimiter.\n\nThe availability of unlimited variants of the Markdown priority\nenvironment is useful when we have a Markdown code span/block that\nitself contains code with Markdown priority environment in it such as\nperhaps a code example that explains how TeXMe works. Consider the\nfollowing example:\n\n`````html\n\u003c!DOCTYPE html\u003e\u003cscript src=\"https://cdn.jsdelivr.net/npm/texme@1.2.2\"\u003e\u003c/script\u003e\u003ctextarea\u003e\n\n# Markdown Priority Environment\n\nHere is an example usage of Markdown priority environment:\n\n\\begin{md*}\n````\n\\begin{md}\n```\nfoo=hello\necho $foo\n```\n\\end{md}\n````\n\\end{md*}\n\nThe above example shows how to protect \\begin{md}`$`\\end{md},\n\\begin{md*}`\\begin{md}`\\end{md*}, and \\begin{md*}`\\end{md}`\\end{md*} in\na Markdown code block.\n`````\n\nHere is the output:\n[texme-code-protected.html](https://susam.github.io/texme/examples/texme-code-protected.html).\n\nIf we start the Markdown priority environment with `\\begin{md}`, then we\ncannot have `\\end{md}` anywhere within the environment because the first\noccurrence of it would end the environment. That is why we use\n`\\begin{md*}` and `\\end{md*}` to create a Markdown priority environment.\nNow we can safely write `\\end{md}` within it.\n\nIn case you are wondering what the quadruple backticks are doing in the\nabove code example, it is a feature defined in the CommonMark\nspecification. It creates a code block within which we can safely use\ntriple backticks. CommonMark allows us to start a code span/block with\nan arbitrary number of backticks such the code span/block may safely\ncontain consecutive backticks. To be precise a code span that starts\nwith M backticks can safely contain N consecutive backticks as long as M\n\u0026ne; N. Similarly, a code block that starts with M backticks (M \u0026ge; 3)\ncan safely contain N consecutive backticks as long as M \u003e N. All of this\nis standard CommonMark and not something introduced by TeXMe. TeXMe only\nintroduces the special purpose `md` environment and its unlimited\nvariants.\n\n\nLicense\n-------\n\nThis is free and open source software. You can use, copy, modify,\nmerge, publish, distribute, sublicense, and/or sell copies of it,\nunder the terms of the MIT License. See [LICENSE.md][L] for details.\n\nThis software is provided \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nexpress or implied. See [LICENSE.md][L] for details.\n\n[L]: LICENSE.md\n\n\nSupport\n-------\n\nTo report bugs, suggest improvements, or ask questions,\n[create issues][ISSUES].\n\n[ISSUES]: https://github.com/susam/texme/issues\n\n\nChannels\n--------\n\nThe author of this project hangs out at the following places online:\n\n- Website: [susam.net](https://susam.net)\n- Twitter: [@susam](https://twitter.com/susam)\n- Mastodon: [@susam@mastodon.social](https://mastodon.social/@susam)\n- GitHub: [@susam](https://github.com/susam)\n- Matrix: [#susam:matrix.org](https://app.element.io/#/room/#susam:matrix.org)\n- IRC: [#susam:libera.chat](https://web.libera.chat/#susam)\n\nYou are welcome to subscribe to, follow, or join one or more of the\nabove channels to receive updates from the author or ask questions\nabout this project.\n\n\nMore\n----\n\nSee [MathB](https://github.com/susam/mathb), a mathematics pastebin\nbuilt using TeXMe. This is the oldest mathematics pastebin that is\nstill alive on the web and serving its community of users.\n\nSee [Muboard](https://github.com/susam/muboard), a self-rendering and\ndistributable chalkboard built using TeXMe.\n","funding_links":["https://www.buymeacoffee.com/susam"],"categories":["JavaScript","Markdown parser"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Ftexme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsusam%2Ftexme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsusam%2Ftexme/lists"}