From 26c8e08ede0bb12b98ed54ab45b1e39db595c271 Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Thu, 30 Mar 2023 15:31:05 +0900 Subject: Dogfood for documentation --- doc/.gitignore | 3 + doc/base/karderio-Toy-baloon.svg | 161 +++++++++++++++++++++++++++++++++++ doc/base/pygments-dark.css | 83 ++++++++++++++++++ doc/base/pygments-light.css | 73 ++++++++++++++++ doc/base/style.css | 173 ++++++++++++++++++++++++++++++++++++++ doc/html.xslt | 63 ++++++++++++++ doc/pages/demo/katex/index.xml | 115 +++++++++++++++++++++++++ doc/pages/demo/pygments/index.xml | 66 +++++++++++++++ doc/pages/index.xml | 14 +++ doc/rss.xslt | 26 ++++++ doc/rub | 95 +++++++++++++++++++++ doc/shell.nix | 10 +++ 12 files changed, 882 insertions(+) create mode 100644 doc/.gitignore create mode 100644 doc/base/karderio-Toy-baloon.svg create mode 100644 doc/base/pygments-dark.css create mode 100644 doc/base/pygments-light.css create mode 100644 doc/base/style.css create mode 100644 doc/html.xslt create mode 100644 doc/pages/demo/katex/index.xml create mode 100644 doc/pages/demo/pygments/index.xml create mode 100644 doc/pages/index.xml create mode 100644 doc/rss.xslt create mode 100755 doc/rub create mode 100644 doc/shell.nix diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 0000000..e2c5f1f --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,3 @@ +cache/ +out/ +.doit.db diff --git a/doc/base/karderio-Toy-baloon.svg b/doc/base/karderio-Toy-baloon.svg new file mode 100644 index 0000000..5fd9325 --- /dev/null +++ b/doc/base/karderio-Toy-baloon.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + Toy baloon + 2006-10-21T06:10:16 + 2D orange party baloon + https://openclipart.org/detail/808/toy-baloon-by-karderio + + + karderio + + + + + line art + party baloon + toy baloon + + + + + + + + + + + diff --git a/doc/base/pygments-dark.css b/doc/base/pygments-dark.css new file mode 100644 index 0000000..2160c0b --- /dev/null +++ b/doc/base/pygments-dark.css @@ -0,0 +1,83 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.hll { background-color: #0000ff } +.c { color: #00ff00 } /* Comment */ +.err { color: #dddddd } /* Error */ +.esc { color: #dddddd } /* Escape */ +.g { color: #dddddd } /* Generic */ +.k { color: #ff0000 } /* Keyword */ +.l { color: #dddddd } /* Literal */ +.n { color: #dddddd } /* Name */ +.o { color: #dddddd } /* Operator */ +.x { color: #dddddd } /* Other */ +.p { color: #dddddd } /* Punctuation */ +.ch { color: #00ff00 } /* Comment.Hashbang */ +.cm { color: #00ff00 } /* Comment.Multiline */ +.cp { color: #e5e5e5 } /* Comment.Preproc */ +.cpf { color: #00ff00 } /* Comment.PreprocFile */ +.c1 { color: #00ff00 } /* Comment.Single */ +.cs { color: #00ff00 } /* Comment.Special */ +.gd { color: #dddddd } /* Generic.Deleted */ +.ge { color: #dddddd } /* Generic.Emph */ +.gr { color: #dddddd } /* Generic.Error */ +.gh { color: #dddddd } /* Generic.Heading */ +.gi { color: #dddddd } /* Generic.Inserted */ +.go { color: #dddddd } /* Generic.Output */ +.gp { color: #dddddd } /* Generic.Prompt */ +.gs { color: #dddddd } /* Generic.Strong */ +.gu { color: #dddddd } /* Generic.Subheading */ +.gt { color: #dddddd } /* Generic.Traceback */ +.kc { color: #ff0000 } /* Keyword.Constant */ +.kd { color: #ff0000 } /* Keyword.Declaration */ +.kn { color: #ff0000 } /* Keyword.Namespace */ +.kp { color: #ff0000 } /* Keyword.Pseudo */ +.kr { color: #ff0000 } /* Keyword.Reserved */ +.kt { color: #ee82ee } /* Keyword.Type */ +.ld { color: #dddddd } /* Literal.Date */ +.m { color: #dddddd } /* Literal.Number */ +.s { color: #87ceeb } /* Literal.String */ +.na { color: #dddddd } /* Name.Attribute */ +.nb { color: #dddddd } /* Name.Builtin */ +.nc { color: #dddddd } /* Name.Class */ +.no { color: #7fffd4 } /* Name.Constant */ +.nd { color: #dddddd } /* Name.Decorator */ +.ni { color: #dddddd } /* Name.Entity */ +.ne { color: #dddddd } /* Name.Exception */ +.nf { color: #ffff00 } /* Name.Function */ +.nl { color: #dddddd } /* Name.Label */ +.nn { color: #dddddd } /* Name.Namespace */ +.nx { color: #dddddd } /* Name.Other */ +.py { color: #dddddd } /* Name.Property */ +.nt { color: #dddddd } /* Name.Tag */ +.nv { color: #eedd82 } /* Name.Variable */ +.ow { color: #dddddd } /* Operator.Word */ +.pm { color: #dddddd } /* Punctuation.Marker */ +.w { color: #dddddd } /* Text.Whitespace */ +.mb { color: #dddddd } /* Literal.Number.Bin */ +.mf { color: #dddddd } /* Literal.Number.Float */ +.mh { color: #dddddd } /* Literal.Number.Hex */ +.mi { color: #dddddd } /* Literal.Number.Integer */ +.mo { color: #dddddd } /* Literal.Number.Oct */ +.sa { color: #87ceeb } /* Literal.String.Affix */ +.sb { color: #87ceeb } /* Literal.String.Backtick */ +.sc { color: #87ceeb } /* Literal.String.Char */ +.dl { color: #87ceeb } /* Literal.String.Delimiter */ +.sd { color: #87ceeb } /* Literal.String.Doc */ +.s2 { color: #87ceeb } /* Literal.String.Double */ +.se { color: #87ceeb } /* Literal.String.Escape */ +.sh { color: #87ceeb } /* Literal.String.Heredoc */ +.si { color: #87ceeb } /* Literal.String.Interpol */ +.sx { color: #87ceeb } /* Literal.String.Other */ +.sr { color: #87ceeb } /* Literal.String.Regex */ +.s1 { color: #87ceeb } /* Literal.String.Single */ +.ss { color: #87ceeb } /* Literal.String.Symbol */ +.bp { color: #dddddd } /* Name.Builtin.Pseudo */ +.fm { color: #ffff00 } /* Name.Function.Magic */ +.vc { color: #eedd82 } /* Name.Variable.Class */ +.vg { color: #eedd82 } /* Name.Variable.Global */ +.vi { color: #eedd82 } /* Name.Variable.Instance */ +.vm { color: #eedd82 } /* Name.Variable.Magic */ +.il { color: #dddddd } /* Literal.Number.Integer.Long */ diff --git a/doc/base/pygments-light.css b/doc/base/pygments-light.css new file mode 100644 index 0000000..e2cc7b8 --- /dev/null +++ b/doc/base/pygments-light.css @@ -0,0 +1,73 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.hll { background-color: #ffffcc } +.c { color: #3D7B7B; font-style: italic } /* Comment */ +.err { border: 1px solid #FF0000 } /* Error */ +.k { color: #008000; font-weight: bold } /* Keyword */ +.o { color: #666666 } /* Operator */ +.ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */ +.cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */ +.cp { color: #9C6500 } /* Comment.Preproc */ +.cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */ +.c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */ +.cs { color: #3D7B7B; font-style: italic } /* Comment.Special */ +.gd { color: #A00000 } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.gr { color: #E40000 } /* Generic.Error */ +.gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.gi { color: #008400 } /* Generic.Inserted */ +.go { color: #717171 } /* Generic.Output */ +.gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.gt { color: #0044DD } /* Generic.Traceback */ +.kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.kp { color: #008000 } /* Keyword.Pseudo */ +.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.kt { color: #B00040 } /* Keyword.Type */ +.m { color: #666666 } /* Literal.Number */ +.s { color: #BA2121 } /* Literal.String */ +.na { color: #687822 } /* Name.Attribute */ +.nb { color: #008000 } /* Name.Builtin */ +.nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.no { color: #880000 } /* Name.Constant */ +.nd { color: #AA22FF } /* Name.Decorator */ +.ni { color: #717171; font-weight: bold } /* Name.Entity */ +.ne { color: #CB3F38; font-weight: bold } /* Name.Exception */ +.nf { color: #0000FF } /* Name.Function */ +.nl { color: #767600 } /* Name.Label */ +.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.nt { color: #008000; font-weight: bold } /* Name.Tag */ +.nv { color: #19177C } /* Name.Variable */ +.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.w { color: #bbbbbb } /* Text.Whitespace */ +.mb { color: #666666 } /* Literal.Number.Bin */ +.mf { color: #666666 } /* Literal.Number.Float */ +.mh { color: #666666 } /* Literal.Number.Hex */ +.mi { color: #666666 } /* Literal.Number.Integer */ +.mo { color: #666666 } /* Literal.Number.Oct */ +.sa { color: #BA2121 } /* Literal.String.Affix */ +.sb { color: #BA2121 } /* Literal.String.Backtick */ +.sc { color: #BA2121 } /* Literal.String.Char */ +.dl { color: #BA2121 } /* Literal.String.Delimiter */ +.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.s2 { color: #BA2121 } /* Literal.String.Double */ +.se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */ +.sh { color: #BA2121 } /* Literal.String.Heredoc */ +.si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */ +.sx { color: #008000 } /* Literal.String.Other */ +.sr { color: #A45A77 } /* Literal.String.Regex */ +.s1 { color: #BA2121 } /* Literal.String.Single */ +.ss { color: #19177C } /* Literal.String.Symbol */ +.bp { color: #008000 } /* Name.Builtin.Pseudo */ +.fm { color: #0000FF } /* Name.Function.Magic */ +.vc { color: #19177C } /* Name.Variable.Class */ +.vg { color: #19177C } /* Name.Variable.Global */ +.vi { color: #19177C } /* Name.Variable.Instance */ +.vm { color: #19177C } /* Name.Variable.Magic */ +.il { color: #666666 } /* Literal.Number.Integer.Long */ diff --git a/doc/base/style.css b/doc/base/style.css new file mode 100644 index 0000000..66349cb --- /dev/null +++ b/doc/base/style.css @@ -0,0 +1,173 @@ +@import "/pygments-light.css" (prefers-color-scheme: light); +@import "/pygments-dark.css" (prefers-color-scheme: dark); +:root { + --overlay-bg: #8881; + --overlay-border: #8884; +} + +/* Default font and layout */ +html { + box-sizing: border-box; + font-size: clamp(100%, 2vw, 150%); + margin: auto; + max-width: 36rem; +} + +body { margin: 0 1rem } + +/* Text geometry */ +p, details { + hyphens: auto; + text-align: justify; +} + +/* Headings */ +h2 a, h3 a, h4 a, h5 a, h6 a { color: CanvasText } + +.toc ol ol { + list-style-type: lower-alpha; +} + +/* General formatting */ +li p { margin: 0 } +a { text-decoration: none } +p a:hover { text-decoration: underline } + +sup.footnote-ref > a::before { content: '[' } +sup.footnote-ref > a::after { content: ']' } +section.footnotes { + font-size: 80%; + border: none; + margin: 1ex 0; +} +section.footnotes > ol { + counter-reset: list; + list-style-position: inside; + padding-left: 0; +} +section.footnotes > ol > li { counter-increment: list } +section.footnotes > ol > li::marker { + content: "[" counter(list, digit) "]\a0"; +} + +/* Images */ +figure { + margin: 0; + text-align: center; +} +img { + display: block; + margin: auto; + max-width: 100%; +} + +/* Boxes */ +blockquote, .note { + margin: 1ex -1rem; + padding-bottom: 1ex; + padding-left: 0.75rem; + padding-right: 1rem; + padding-top: 1ex; +} +blockquote p, .note p { margin: 1ex 0 } +.note p:first-child { font-weight: bold } +blockquote { + background: var(--overlay-bg); + border-left: 0.25rem solid var(--overlay-border); +} +.note { + background-color: #2482; + border-left: 0.25rem solid #2484; +} + +/* Header */ +header { + margin: 1.5rem -0.5rem; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; +} + +header a { + border-bottom: solid; + font-weight: bold; + margin: 0 0.5rem; + text-decoration: none; +} + +nav, nav li { display: inline-block } +nav ul { margin: 0 } + +footer, .tags, .right { + color: GrayText; + font-size: 80%; +} + +footer { + margin-top: 1.5rem; + margin-bottom: 2rem; +} + +footer a, .tags a { + color: GrayText; + text-decoration: underline; +} + +.nowrap { display: inline-block } +.tags { float: left } +.right { + float: right; + margin-left: auto; +} + +/* Table */ +table { + border-bottom: 0.15em solid; + border-collapse: collapse; + border-top: 0.15em solid; + line-height: 1em; + margin-bottom: 1.5em; + margin-left: auto; + margin-right: auto; + text-align: center; +} + +tr:first-of-type > th { border-bottom: 0.08em solid } +tr, th, td { padding: 0.5em } + +/* highlight.js */ +code, .highlight { background-color: var(--overlay-bg) } +.highlight { + display: block; + padding: 0 1ch; + margin: 0 -1ch; + overflow-x: auto; +} +.highlight > pre { margin: 1ex 0 } +pre p { margin: 0 } + +.comment { + background-color: var(--overlay-bg); + clear: both; + margin: 1ex 0; + overflow: hidden; + padding: 0 1rem; +} + +.fead { + display: flex; + flex-wrap: wrap; + margin: -0.5rem; + margin-bottom: 0; +} +.fead h3 { margin: 0 0 1ex } +.fead article { + background: var(--overlay-bg); + display: flex; + flex-direction: column; + flex: 1 1 0; + margin: 1ex; + min-width: 12rem; + padding: 1ex; +} diff --git a/doc/html.xslt b/doc/html.xslt new file mode 100644 index 0000000..5ad48ad --- /dev/null +++ b/doc/html.xslt @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + <xsl:value-of select="rub:title"/> + + +
+ + +
+
+

+ +
+ + + Tags: + + + + + +
+
+
+ Copyright and stuff +
+ + +
+ + + + + + + + + + + + + + +
diff --git a/doc/pages/demo/katex/index.xml b/doc/pages/demo/katex/index.xml new file mode 100644 index 0000000..e7ecb02 --- /dev/null +++ b/doc/pages/demo/katex/index.xml @@ -0,0 +1,115 @@ + +KaTeX demo +Math formulae to demo LaTeX to MathML rendering +2020-04-15 +demo +math + +Given two discrete-time systems A and B connected in cascade +to form a new system C = x \mapsto B(A(x)), we examine +the following properties: + +## Linearity + +If A and B are linear, +i.e. for all signals x_i and scalars a_i, + + +\begin{aligned} + A\left(n \mapsto \sum_i a_i x_i[n]\right) = n \mapsto \sum_i a_i A(x_i)[n]\\ + B\left(n \mapsto \sum_i a_i x_i[n]\right) = n \mapsto \sum_i a_i B(x_i)[n] +\end{aligned} + + +then C is also linear + + +\begin{aligned} + C\left(n \mapsto \sum_i a_i x_i[n]\right) + &= B\left(A\left(n \mapsto \sum_i a_i x_i[n]\right)\right)\\ + &= B\left(n \mapsto \sum_i a_i A(x_i)[n]\right)\\ + &= n \mapsto \sum_i a_i B(A(x_i))[n]\\ + &= n \mapsto \sum_i a_i C(x_i)[n] +\end{aligned} + + +## Time Invariance + +If A and B are time invariant, +i.e. for all signals x and integers k, + + +\begin{aligned} + A(n \mapsto x[n - k]) &= n \mapsto A(x)[n - k]\\ + B(n \mapsto x[n - k]) &= n \mapsto B(x)[n - k] +\end{aligned} + + +then C is also time invariant + + +\begin{aligned} + C(n \mapsto x[n - k]) + &= B(A(n \mapsto x[n - k]))\\ + &= B(n \mapsto A(x)[n - k])\\ + &= n \mapsto B(A(x))[n - k]\\ + &= n \mapsto C(x)[n - k] +\end{aligned} + + +## LTI Ordering + +If A and B are linear and time-invariant, there exists +signals g and h such that for all signals x, +A = x \mapsto x * g and B = x \mapsto x * h, thus + + +B(A(x)) = B(x * g) = x * g * h = x * h * g = A(x * h) = A(B(x)) + + +or interchanging A and B order does not change C. + +## Causality + +If A and B are causal, +i.e. for all signals x, y and any choise of integer k, + + +\begin{aligned} + \forall n < k, x[n] = y[n]\quad + \Longrightarrow &\;\begin{cases} + \forall n < k, A(x)[n] = A(y)[n]\\ + \forall n < k, B(x)[n] = B(y)[n] + \end{cases}\\ + \Longrightarrow &\;\forall n < k, B(A(x))[n] = B(A(y))[n]\\ + \Longleftrightarrow &\;\forall n < k, C(x)[n] = C(y)[n] +\end{aligned} + + +then C is also causal. + +## BIBO Stability + +If A and B are stable, i.e. there exists a signal x +and scalars a and b that for all integers n, + + +\begin{aligned} + |x[n]| < a &\Longrightarrow |A(x)[n]| < b\\ + |x[n]| < a &\Longrightarrow |B(x)[n]| < b +\end{aligned} + + +then C is also stable, i.e. there exists a signal x +and scalars a, b and c that for all integers n, + + +\begin{aligned} + |x[n]| < a\quad + \Longrightarrow &\;|A(x)[n]| < b\\ + \Longrightarrow &\;|B(A(x))[n]| < c\\ + \Longleftrightarrow &\;|C(x)[n]| < c +\end{aligned} + + + diff --git a/doc/pages/demo/pygments/index.xml b/doc/pages/demo/pygments/index.xml new file mode 100644 index 0000000..361c6ab --- /dev/null +++ b/doc/pages/demo/pygments/index.xml @@ -0,0 +1,66 @@ + +Pygments demo +Code snippets to demonstrate syntax highlighting +2022-12-26 +demo +aoc + +Syntax highlighting for D using Pygments: + + + +The same but let Pygments guess the language: + + + + diff --git a/doc/pages/index.xml b/doc/pages/index.xml new file mode 100644 index 0000000..1a77965 --- /dev/null +++ b/doc/pages/index.xml @@ -0,0 +1,14 @@ + +Rub + +Rub is a static generator framework. + +## Demoes + +* [MathML rendering](/demo/katex) via [KaTeX] +* [Syntax highlighting](/demo/pygments) via [Pygments] + +[KaTeX]: https://katex.org +[Pygments]: https://pygments.org + + diff --git a/doc/rss.xslt b/doc/rss.xslt new file mode 100644 index 0000000..48f9203 --- /dev/null +++ b/doc/rss.xslt @@ -0,0 +1,26 @@ + + + + + + Demo RSS feed + https://rub.parody/ + Global feed + Rub + + + <xsl:value-of select="title"/> + + + + + + + + + + + + diff --git a/doc/rub b/doc/rub new file mode 100755 index 0000000..d1113a2 --- /dev/null +++ b/doc/rub @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +from contextlib import contextmanager +from functools import partial +from pathlib import Path +from shutil import which +from subprocess import PIPE, Popen +from urllib.request import Request, urlopen +from xml.sax.saxutils import unescape + +from lxml.etree import Element, XML +from lxml.html import (fragment_fromstring as from_html_fragment, + fragments_fromstring as from_html_fragments) +from mistune import html as from_md +from pygments import highlight +from pygments.formatters import HtmlFormatter +from pygments.lexers import get_lexer_by_name, guess_lexer +from rub import rub, xml + +PYGMENTS_FORMATTER = HtmlFormatter(lineseparator='
') +KATEX_SERVER = ''' +var http = require('http'); +var katex = require('katex'); + +let server = http.createServer((request, response) => { + if (request.method === 'POST') { + response.writeHead(200, 'OK'); + var body = ''; + request.on('data', (chunk) => body += chunk); + request.on('end', () => { + response.write(katex.renderToString(body, { + displayMode: request.headers['x-katex-mode'] === 'display', + output: 'mathml', + })); + response.end(); + }); + } else { + response.writeHead(405, 'Method Not Allowed'); + response.end(); + } +}); +server.listen(() => { + console.log('http://localhost:' + server.address().port); +}); +''' + + +def mistune(extension, context, input_node, output_parent): + """Render Markdown to HTML.""" + tmp = Element('tmp') + xml.recurse(extension, context, input_node, tmp) + tmp[0].text = input_node.text + text = xml.serialize_content(tmp[0]).decode() + for i in from_html_fragments(from_md(unescape(text))): + extension.apply_templates(context, i, output_parent) + + +def pygments(extension, context, input_node, output_parent): + """Highlight code syntax in HTML.""" + code = input_node.text + lang = input_node.get('lang') + lexer = guess_lexer(code) if lang is None else get_lexer_by_name(lang) + output = from_html_fragment(highlight(code, lexer, PYGMENTS_FORMATTER)) + output.tail = input_node.tail + output_parent.append(output) + + +def katex(extension, context, input_node, output_parent, url, display=False): + """Render LaTeX to content MathML.""" + with urlopen(Request(url, xml.serialize_content(input_node), + {'X-KaTeX-Mode': 'display'} if display else {})) as r: + output = XML(r.read())[0] # remove span[@class='katex'] + output.tail = input_node.tail + output_parent.append(output) + + +@contextmanager +def katex_server(): + server = Popen(which('node'), stdin=PIPE, stdout=PIPE, text=True) + try: + server.stdin.write(KATEX_SERVER) + server.stdin.close() + yield partial(katex, url=server.stdout.readline().strip()) + finally: + server.kill() + + +with katex_server() as mathml: + wd = Path(__file__).parent + rub(xml.Processor(wd/'html.xslt', + partial(Path.with_suffix, suffix='.html'), + markdown=mistune, highlight=pygments, + math=partial(mathml, display=True), m=mathml), + xml.Processor(wd/'rss.xslt', + partial(Path.with_name, name='index.xml')), + wd/'base', wd/'pages', wd/'cache', wd/'out') diff --git a/doc/shell.nix b/doc/shell.nix new file mode 100644 index 0000000..453398c --- /dev/null +++ b/doc/shell.nix @@ -0,0 +1,10 @@ +with import {}; +mkShell { + packages = (with python3Packages; [ + doit lxml mistune pygments + ]) ++ [ nodejs nodePackages.katex ]; + + shellHook = '' + PYTHONPATH=../src:$PYTHONPATH + ''; +} -- cgit 1.4.1