aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Hörnquist <hugo@lysator.liu.se>2023-07-01 09:41:03 +0200
committerHugo Hörnquist <hugo@lysator.liu.se>2023-07-01 13:50:13 +0200
commit5f05951e9ba1ff51f4f6542bf1cddff7c9efa7ef (patch)
tree2072d7a3c693884af59fd61d0dcc779d42538b13
parentSwitch to scss. (diff)
downloadmuppet-strings-5f05951e9ba1ff51f4f6542bf1cddff7c9efa7ef.tar.gz
muppet-strings-5f05951e9ba1ff51f4f6542bf1cddff7c9efa7ef.tar.xz
Rework how highlighting works.
See static-src/README.rst for details about how it works.
-rw-r--r--Makefile8
-rw-r--r--muppet/__main__.py3
-rw-r--r--muppet/format.py9
-rw-r--r--muppet/output.py12
-rw-r--r--muppet/syntax_highlight/__init__.py39
-rw-r--r--muppet/syntax_highlight/andre_simon.py36
-rw-r--r--muppet/syntax_highlight/plain.py14
-rw-r--r--muppet/syntax_highlight/pygments.py24
-rw-r--r--static-src/.gitignore3
-rw-r--r--static-src/Makefile58
-rw-r--r--static-src/README.rst109
-rw-r--r--static-src/_breadcrumb.scss155
-rw-r--r--static-src/_breadcrumb.scss.map7
-rw-r--r--static-src/_highlight.scss49
-rwxr-xr-xstatic-src/build_css.py146
-rw-r--r--static-src/colorscheme/default.yaml23
-rw-r--r--static-src/highlight/andre_simon.yaml26
-rw-r--r--static-src/highlight/muppet.yaml25
-rw-r--r--static-src/highlight/pygments.yaml61
-rw-r--r--static-src/style.scss20
-rw-r--r--static/.gitignore1
-rw-r--r--templates/code_page.html4
22 files changed, 614 insertions, 218 deletions
diff --git a/Makefile b/Makefile
index 3000cef..b8cf57a 100644
--- a/Makefile
+++ b/Makefile
@@ -7,9 +7,9 @@ DOC_OUTPUT = doc.rendered
OUTPUT_FLAGS = --path-base /code/muppet-strings/output \
--env ~/puppet/generated-environments/production/modules/
-SCSS = sass
+SCSS = scss
-output: static/style.css
+output: static-src/style.css
python -m muppet $(OUTPUT_FLAGS)
check_style:
@@ -37,5 +37,5 @@ documentation: $(DOC_OUTPUT)/index.html
clean:
-rm -r output
-static/%.css: static-src/style.scss $(wildcard static-src/_*.scss)
- $(SCSS) --sourcemap=auto -Istatic-src $< $@
+static-src/style.css:
+ $(MAKE) -C $(dir $@) $(notdir $@)
diff --git a/muppet/__main__.py b/muppet/__main__.py
index 943f9ae..b064cf1 100644
--- a/muppet/__main__.py
+++ b/muppet/__main__.py
@@ -47,7 +47,8 @@ def __main() -> None:
# print(module)
setup_module('output', module, path_base=args.path_base)
- os.system("cp -r static output")
+ os.system('make -C static-src --silent install-full PREFIX=$PWD/output')
+ os.system("cp -r static/* output/static/")
if __name__ == '__main__':
diff --git a/muppet/format.py b/muppet/format.py
index 97c38d1..870dfd3 100644
--- a/muppet/format.py
+++ b/muppet/format.py
@@ -1117,7 +1117,7 @@ def format_class(d_type: dict[str, Any]) -> str:
# print(name, file=sys.stderr)
out += print_docstring(name, d_type['docstring'])
- out += '<pre><code class="puppet">'
+ out += '<pre class="highlight-muppet"><code class="puppet">'
out += render(renderer, data)
out += '</code></pre>'
return out
@@ -1136,7 +1136,7 @@ def format_type_alias(d_type: dict[str, Any]) -> str:
# print(name, file=sys.stderr)
out += print_docstring(name, d_type['docstring'])
out += '\n'
- out += '<pre><code class="puppet">'
+ out += '<pre class="highlight-muppet"><code class="puppet">'
t = parse_puppet(d_type['alias_of'])
data = parse(t, 0, ['root'])
out += render(renderer, data)
@@ -1152,7 +1152,7 @@ def format_defined_type(d_type: dict[str, Any]) -> str:
# print(name, file=sys.stderr)
out += print_docstring(name, d_type['docstring'])
- out += '<pre><code class="puppet">'
+ out += '<pre class="highlight-muppet"><code class="puppet">'
t = parse_puppet(d_type['source'])
out += render(renderer, parse(t, 0, ['root']))
out += '</code></pre>\n'
@@ -1201,9 +1201,10 @@ def format_puppet_function(function: dict[str, Any]) -> str:
signature['signature']
signature['docstring']
if t in ['ruby3x', 'ruby4x']:
+ # TODO manual highlight here
out += f'<pre><code class="ruby">{function["source"]}</code></pre>\n'
elif t == 'puppet':
- out += '<pre><code class="puppet">'
+ out += '<pre class="highlight-muppet"><code class="puppet">'
try:
t = parse_puppet(function['source'])
out += str(parse(t, 0, ['root']))
diff --git a/muppet/output.py b/muppet/output.py
index 0e83c58..7e2266b 100644
--- a/muppet/output.py
+++ b/muppet/output.py
@@ -30,6 +30,7 @@ from collections.abc import (
from .util import group_by
from .puppet.strings import isprivate
from .breadcrumbs import breadcrumbs
+from .syntax_highlight import highlight
# TODO replace 'output' with base, or put this somewhere else
@@ -291,8 +292,15 @@ def setup_module(base: str, module: ModuleEntry, *, path_base: str) -> None:
# TODO option to add .txt extension (for web serverse which
# treat .pp as application/binary)
- with open(os.path.join(dir, 'source.pp.txt'), 'w') as f:
- f.write(puppet_class['source'])
+ with open(os.path.join(dir, 'source.pp.txt'), 'wb') as f:
+ with open(module.file(puppet_class['file']), 'rb') as g:
+ f.write(g.read())
+
+ with open(os.path.join(dir, 'source.pp.html'), 'w') as f:
+ template = jinja.get_template('code_page.html')
+ with open(module.file(puppet_class['file']), 'r') as g:
+ f.write(template.render(content=highlight(g.read(), 'puppet'),
+ path_base=path_base))
with open(os.path.join(dir, 'source.json'), 'w') as f:
json.dump(puppet_class, f, indent=2)
diff --git a/muppet/syntax_highlight/__init__.py b/muppet/syntax_highlight/__init__.py
new file mode 100644
index 0000000..bcadf81
--- /dev/null
+++ b/muppet/syntax_highlight/__init__.py
@@ -0,0 +1,39 @@
+"""
+Syntax highlight with the best available backend.
+
+Syntax highlight the given code by the best, available, syntax
+highlighter, returning the result as HTML. The default highlighter
+simply wraps the output in
+``<pre><code class={language}>{code}</code></pre>``
+(with escaping). This means that it can still be handled by JavaScript if so desired.
+"""
+
+from . import pygments
+from . import andre_simon
+from . import plain
+
+from typing import cast
+
+
+for module in [pygments, andre_simon, plain]:
+ if module.available:
+ backend = module
+ break
+else:
+ # This should never happen, since ``plain`` should always be
+ # available.
+ raise ValueError("No applicable highlight module")
+
+
+def highlight(source: str, language: str) -> str:
+ """
+ Highlight the given source as language, retuning HTML.
+
+ :param source:
+ Source code to highlight.
+ :param language:
+ Language of the source code.
+ :returns:
+ An HTML string.
+ """
+ return cast(str, backend.highlight(source, language))
diff --git a/muppet/syntax_highlight/andre_simon.py b/muppet/syntax_highlight/andre_simon.py
new file mode 100644
index 0000000..7bbcd43
--- /dev/null
+++ b/muppet/syntax_highlight/andre_simon.py
@@ -0,0 +1,36 @@
+"""
+Syntax highlighting through the highlight(1) command.
+
+The name "Andre Simon" is choosen based of the author, and that
+"highlight" by itself it really non-descriptive.
+"""
+
+import subprocess
+
+try:
+ subprocess.run(['highlight', '--version'], stdout=subprocess.DEVNULL)
+ available = True
+except FileNotFoundError:
+ available = False
+
+
+def highlight(code: str, language: str) -> str:
+ """Highlight code through the ``highlight`` command."""
+ # TODO line- vs pygments line_
+ cmd = subprocess.run(['highlight',
+ '--out-format', 'html',
+ '--fragment',
+ '--line-numbers',
+ '--anchors',
+ '--anchors-prefix=line',
+ '--class-name=NONE',
+ '--syntax', language,
+ '--enclose-pre'],
+ capture_output=True,
+ text=True,
+ input=code,
+ check=True)
+ return f"""
+ <!-- Generated through highlight(1), as language {language} -->
+ <div class="highlight-andre-simon">{cmd.stdout}</div>
+ """
diff --git a/muppet/syntax_highlight/plain.py b/muppet/syntax_highlight/plain.py
new file mode 100644
index 0000000..0d1234f
--- /dev/null
+++ b/muppet/syntax_highlight/plain.py
@@ -0,0 +1,14 @@
+"""Non-highlighter useful as a backup."""
+
+import html
+
+available = True
+
+
+def highlight(code: str, language: str) -> str:
+ """Return the code "highlighted" by wrapping it in <pre> tags."""
+ out = f'<pre><code class="{language}">{html.escape(code)}</code></pre>'
+ return f"""
+ <!-- "Genererated" as plain output -->
+ <div class"highlight-plain">{out}</div>
+ """
diff --git a/muppet/syntax_highlight/pygments.py b/muppet/syntax_highlight/pygments.py
new file mode 100644
index 0000000..05e8562
--- /dev/null
+++ b/muppet/syntax_highlight/pygments.py
@@ -0,0 +1,24 @@
+"""Syntax highlighting through pygments."""
+
+try:
+ from pygments.formatters import HtmlFormatter
+ from pygments.lexers import get_lexer_by_name
+ import pygments
+ available = True
+except ModuleNotFoundError:
+ available = False
+
+
+def highlight(code: str, language: str) -> str:
+ """Highlight code through pygments."""
+ out = pygments.highlight(code, get_lexer_by_name(language),
+ HtmlFormatter(cssclass='highlight-pygments',
+ lineanchors='line',
+ linenos='table',
+ # linenos='inline'
+ anchorlinenos=True,
+ ))
+ return f"""
+ <!-- Generated through pygments, as {language} -->
+ {out}
+ """
diff --git a/static-src/.gitignore b/static-src/.gitignore
new file mode 100644
index 0000000..6de9d50
--- /dev/null
+++ b/static-src/.gitignore
@@ -0,0 +1,3 @@
+out/
+style.css
+*.map
diff --git a/static-src/Makefile b/static-src/Makefile
new file mode 100644
index 0000000..e01aded
--- /dev/null
+++ b/static-src/Makefile
@@ -0,0 +1,58 @@
+.PHONY: all clean install install-full install-bare
+
+SCSS = scss
+OUT_DIR = out
+TARGET = style.css
+
+DESTDIR =
+PREFIX = /usr/local/share/muppet/
+# Path relative install root where the static files should end up
+LOCAL_PATH = static
+
+# Highlighting files
+highlights = $(wildcard highlight/*.yaml)
+# Colorscheme files
+colorschemes = $(wildcard colorscheme/*.yaml)
+# Generated highlighting and colorscheme files
+outputs = $(patsubst colorscheme/%.yaml,$(OUT_DIR)/_colorscheme_%.scss,$(colorschemes)) \
+ $(patsubst highlight/%.yaml,$(OUT_DIR)/_highlight_%.scss,$(highlights))
+
+# Included scss files
+SCSS_FILES = $(wildcard _*.scss)
+
+all: style.css
+
+clean:
+ -rm $(outputs)
+ -rmdir $(OUT_DIR)
+ -rm $(TARGET)
+ -rm $(TARGET).map
+
+$(TARGET): style.scss $(SCSS_FILES) $(outputs)
+ $(SCSS) --sourcemap=auto -I. -Iout $< $@
+
+$(OUT_DIR)/_highlight_%.scss: highlight/%.yaml $(OUT_DIR)
+ ./build_css.py highlight $< > $@
+
+$(OUT_DIR)/_colorscheme_%.scss: colorscheme/%.yaml $(OUT_DIR)
+ ./build_css.py colorscheme $< > $@
+
+$(OUT_DIR):
+ mkdir -p $@
+
+
+dest=$(abspath $(DESTDIR)/$(PREFIX)/$(LOCAL_PATH))
+
+# Install generated files, along with most source files and the map
+# file, to aid in debugging
+install-full: $(TARGET)
+ install -d "$(dest)"
+ install -d "$(dest)/$(OUT_DIR)"
+ install -m644 $(outputs) "$(dest)/$(OUT_DIR)"
+ install -m644 "$(TARGET)" "$(TARGET).map" style.scss $(SCSS_FILES) "$(dest)"
+
+# Only install the generated files
+install-bare: $(TARGET)
+ install -D -m644 -t "$(dest)" $(TARGET)
+
+install: install-full
diff --git a/static-src/README.rst b/static-src/README.rst
new file mode 100644
index 0000000..3d8b52f
--- /dev/null
+++ b/static-src/README.rst
@@ -0,0 +1,109 @@
+.. _highlight-readme:
+
+.. Introduction
+
+Syntax highlighting in the HTML output is handled in a way to allow
+easy changing of highlighting engine, and of colorschemes.
+All syntax objects are grouped into one of the Abstract highlight
+groups (see :ref:`abstract-highlight-groups`). Highlighting files maps
+these groups onto distinct CSS classes depending on the highlighting
+engine, and colorscheme files maps these into CSS styles.
+
+
+
+Colorschemes
+============
+
+Colorscheme files should be placed in ``colorscheme/*.yaml``, and
+should contain a mapping for all (wanted) abstract highlight groups,
+onto mappings containing (any of) the following keys:
+
+- ``color``
+- ``background``
+- ``font-style``
+- ``font-weight``
+
+These will be mapped directly into the CSS.
+
+The special key *raw-append* also exists, which, if present, should
+contain raw CSS code which will be appended to this colorscheme.
+This is mainly useful to target highlighting specific classes not
+exposed by the abstract highlight groups.
+
+.. TODO useful raw selectors
+ - ``:root``
+ - ``.highlight-pygments``
+ - ``.highlight-andre-simon``
+ - ``.highlight-muppet``
+
+Sample CSS
+----------
+
+The generated CSS code will have the following form detailed in
+:ref:`sample-css`. Note that the selector (``.comment``) will depend
+on the highlight file, while the variable names (``--hl-comment-*``)
+depend on the abstract highlight group.
+
+.. code-block:: css
+ :name: sample-css
+ :caption: fragment of generated CSS for a colorscheme.
+
+ .comment {
+ color: var(--hl-comment-color);
+ background-color: var(--hl-comment-background);
+ font-style: var(--hl-comment-font-style);
+ font-weight: var(--hl-comment-font-weight);
+ }
+
+
+Highlight files
+===============
+
+Highlight files map ref:`abstract-highlight_group` to concrete CSS
+classes. Each Yaml file (located in ``highlight/*.yaml``) should
+contain a mapping from abstract highlight groups, to lists of css
+classes.
+
+
+.. _abstract-highlight-group:
+
+Abstract highlight groups
+=========================
+
+The available Abstract highlight groups are as follows:
+
+``comment``
+ Comments
+
+``error``
+ TODO
+
+``escape``
+ Escape sequences embedded in strings
+
+``interpolate``
+ Variables interpolated in strings
+
+``keyword``
+ Language reserved words (like ``class``, ...)
+
+``line``
+ Line numbers (not part of the actual code)
+
+``number``
+ Numeric literals
+
+``operator``
+ operators (``+``, ``in``, ...)
+
+``regex``
+ Regex literals
+
+``special``
+ TODO
+
+``string``
+ String literals
+
+``variable``
+ Variables
diff --git a/static-src/_breadcrumb.scss b/static-src/_breadcrumb.scss
index 63534d6..6918af0 100644
--- a/static-src/_breadcrumb.scss
+++ b/static-src/_breadcrumb.scss
@@ -1,148 +1,11 @@
-@charset "UTF-8";
-/* -------------------------------------------------- */
-.parse-error {
- background: red;
- color: yellow; }
-
-/* -------------------------------------------------- */
-h2 {
- position: sticky;
- top: 0;
- background: white;
- display: block;
- z-index: 100; }
-
-/* -------------------------------------------------- */
-.documentation {
- display: none; }
-
-/*
-.var {
- position: relative;
-}
-
-.var .documentation {
- display: none;
- position: absolute;
- top: 2ch;
- left: 0;
- border: 1px solid black;
- background: lightblue;
- z-index: 10;
-}
-
-.var:hover .documentation {
- display: block;
-}
-*/
-.noscript {
- display: none; }
-
-code.json {
- font-size: 80%; }
-
-:target {
- background-color: yellow; }
-
-.overview-list p {
- display: inline; }
-
-.example {
- background: lightgray;
- padding: 1em;
- border-radius: 1ex; }
-
-.comment {
- border-left: 1ex;
- border-left-style: dotted;
- display: inline-block;
- padding-left: 1em;
- font-family: sans;
- font-size: 80%; }
- .comment p:first-child {
- margin-top: 0; }
- .comment p:last-child {
- margin-bottom: 0; }
-
-/* -------------------------------------------------- */
.breadcrumb {
- padding: 0; }
- .breadcrumb li {
- display: inline-block;
- padding: 0; }
- .breadcrumb li:not(:first-child)::before {
- content: "»";
- padding: 1ex; }
-
-/*
-.case { color: ; }
-.splat { color: ; }
-.array { color: ; }
-.parse-error { color: ; }
-.parameter { color: ; }
-.string { color: ; }
-.regex { color: ; }
-.invoke { color: ; }
-.default { color: ; }
-.call { color: ; }
-.qr { color: ; }
-.lambda { color: ; }
-.number { color: ; }
-.regex-body { color: ; }
-.call-method { color: ; }
-*/
-.literal {
- color: green; }
-
-.keyword {
- color: orange; }
-
-.type {
- color: darkgreen; }
-
-.qn {
- color: darkgreen; }
-
-.var {
- color: blue; }
-
-.str-var {
- color: blue; }
-
-.name {
- color: red; }
-
-.string {
- color: olive; }
-
-.comment {
- color: grey; }
-
-/* Style for tabgroups */
-.tabs {
- display: grid;
- grid-template-columns: 1fr;
- grid-template-rows: auto 1fr;
- border: 1px solid red; }
- .tabs menu {
- display: flex;
- flex-direction: row;
- padding: 0;
- margin: 0; }
- .tabs menu li {
- display: block; }
-
-/*
-.tabs menu li {
- display: block;
- background-color: lightgray;
- border: 1px solid gray;
+ padding: 0;
+ li {
+ display: inline-block;
+ padding: 0;
+ &:not(:first-child)::before {
+ content: "»";
+ padding: 1ex;
+ }
+ }
}
-*/
-.tab {
- display: none;
- border: 1px solid green; }
- .tab.selected {
- display: block !important; }
-
-/*# sourceMappingURL=_breadcrumb.scss.map */
diff --git a/static-src/_breadcrumb.scss.map b/static-src/_breadcrumb.scss.map
deleted file mode 100644
index 5770a45..0000000
--- a/static-src/_breadcrumb.scss.map
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-"version": 3,
-"mappings": ";AACA,wDAAwD;AAExD,YAAa;EACZ,UAAU,EAAE,GAAG;EACf,KAAK,EAAE,MAAM;;AAGd,wDAAwD;AAExD,EAAG;EACF,QAAQ,EAAE,MAAM;EAChB,GAAG,EAAE,CAAC;EACN,UAAU,EAAE,KAAK;EACjB,OAAO,EAAE,KAAK;EACd,OAAO,EAAE,GAAG;;AAGb,wDAAwD;AAExD,cAAe;EACd,OAAO,EAAE,IAAI;;AAGd;;;;;;;;;;;;;;;;;;EAkBE;AAEF,SAAU;EACT,OAAO,EAAE,IAAI;;AAGd,SAAU;EACT,SAAS,EAAE,GAAG;;AAGf,OAAQ;EACP,gBAAgB,EAAE,MAAM;;AAGzB,gBAAiB;EAChB,OAAO,EAAE,MAAM;;AAGhB,QAAS;EACR,UAAU,EAAE,SAAS;EACrB,OAAO,EAAE,GAAG;EACZ,aAAa,EAAE,GAAG;;AAGnB,QAAS;EACR,WAAW,EAAE,GAAG;EAChB,iBAAiB,EAAE,MAAM;EACzB,OAAO,EAAE,YAAY;EACrB,YAAY,EAAE,GAAG;EACjB,WAAW,EAAE,IAAI;EACjB,SAAS,EAAE,GAAG;EAEd,sBAAc;IACb,UAAU,EAAE,CAAC;EAGd,qBAAa;IACZ,aAAa,EAAE,CAAC;;AAIlB,wDAAwD;ACnFxD,WAAY;EACX,OAAO,EAAE,CAAC;EAEV,cAAG;IACF,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,CAAC;EAGX,wCAA6B;IAC5B,OAAO,EAAE,GAAG;IACZ,OAAO,EAAE,GAAG;;ACVd;;;;;;;;;;;;;;;;EAgBE;AAEF,QAAS;EAAE,KAAK,EAAE,KAAK;;AAKvB,QAAS;EAAE,KAAK,EAAE,MAAM;;AAWxB,KAAM;EAAE,KAAK,EAAE,SAAS;;AACxB,GAAI;EAAE,KAAK,EAAE,SAAS;;AAEtB,IAAK;EAAE,KAAK,EAAE,IAAI;;AAClB,QAAS;EAAE,KAAK,EAAE,IAAI;;AAEtB,KAAM;EAAE,KAAK,EAAE,GAAG;;AAElB,OAAQ;EACP,KAAK,EAAE,KAAK;;AAGb,QAAS;EACR,KAAK,EAAE,IAAI;;AC/CZ,yBAAyB;AACzB,KAAM;EACL,OAAO,EAAE,IAAI;EACb,qBAAqB,EAAE,GAAG;EAC1B,kBAAkB,EAAE,QAAQ;EAC5B,MAAM,EAAE,aAAa;EAErB,UAAK;IACJ,OAAO,EAAE,IAAI;IACb,cAAc,EAAE,GAAG;IACnB,OAAO,EAAE,CAAC;IACV,MAAM,EAAE,CAAC;EAGV,aAAQ;IACP,OAAO,EAAE,KAAK;;AAKhB;;;;;;EAME;AAEF,IAAK;EACJ,OAAO,EAAE,IAAI;EACb,MAAM,EAAE,eAAe;EAEvB,aAAW;IACV,OAAO,EAAE,gBAAgB;;ACjC3B,EAAG;EAAE,KAAK,EAAE,OAAO;;AACnB,EAAG;EAAE,KAAK,EAAE,OAAO;;AACnB,EAAG;EAAE,KAAK,EAAE,OAAO;;AACnB,EAAG;EAAE,KAAK,EAAE,OAAO;;AACnB,EAAG;EAAE,KAAK,EAAE,OAAO;;AACnB,EAAG;EAAE,KAAK,EAAE,OAAO",
-"sources": ["style.scss","_breadcrumb.scss","_highlight.scss","_tabset.scss","_color-headers.scss"],
-"names": [],
-"file": "_breadcrumb.scss"
-}
diff --git a/static-src/_highlight.scss b/static-src/_highlight.scss
deleted file mode 100644
index b3aa5d0..0000000
--- a/static-src/_highlight.scss
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-.case { color: ; }
-.splat { color: ; }
-.array { color: ; }
-.parse-error { color: ; }
-.parameter { color: ; }
-.string { color: ; }
-.regex { color: ; }
-.invoke { color: ; }
-.default { color: ; }
-.call { color: ; }
-.qr { color: ; }
-.lambda { color: ; }
-.number { color: ; }
-.regex-body { color: ; }
-.call-method { color: ; }
-*/
-
-.literal { color: green; }
-.true {}
-.false {}
-.undef {}
-
-.keyword { color: orange; }
-.class {}
-.or {}
-.define {}
-.unless {}
-.if {}
-.else {}
-.function {}
-.and {}
-.in {}
-
-.type { color: darkgreen; }
-.qn { color: darkgreen; }
-
-.var { color: blue; }
-.str-var { color: blue; }
-
-.name { color: red; }
-
-.string {
- color: olive;
-}
-
-.comment {
- color: grey;
-}
diff --git a/static-src/build_css.py b/static-src/build_css.py
new file mode 100755
index 0000000..38cb2c6
--- /dev/null
+++ b/static-src/build_css.py
@@ -0,0 +1,146 @@
+#!/usr/bin/env python3
+
+"""
+(S)CSS generators for help with highlighting.
+
+:ref:`highlight-readme`.
+"""
+
+import yaml
+from datetime import datetime
+import argparse
+
+CSS_RULES = '''
+ color: var(--hl-{name}-color);
+ background-color: var(--hl-{name}-background);
+ font-style: var(--hl-{name}-font-style);
+ font-weight: var(--hl-{name}-font-weight);
+'''
+
+HEADER = '''/*
+* File autogenerated from {source}.
+* Generated at {time}
+*/
+'''
+
+HIGHLIGHT_GROUPS = [
+ "comment",
+ "error",
+ "escape",
+ "interpolate",
+ "keyword",
+ "line",
+ "number",
+ "operator",
+ "regex",
+ "special",
+ "string",
+ "variable",
+]
+
+HIGHLIGHT_VARIABLES = [
+ 'color',
+ 'background',
+ 'font-style',
+ 'font-weight',
+]
+
+
+def build_highlight_map(source_file: str) -> str:
+ """
+ Generate CSS rules from source file.
+
+ :param source_file:
+ A yaml file containing mappings from our abstract highlight
+ groups, to concrete CSS classes.
+ :returns:
+ Generated CSS code, applicable to be written directly to a
+ file.
+ """
+ with open(source_file) as f:
+ data = yaml.full_load(f)
+ result = ''
+ result += HEADER.format(source=source_file,
+ time=datetime.now())
+ for name, classes in data.items():
+ output: str = '\n'
+ output += ', '.join(f'.{c}' for c in classes)
+ output += ' {'
+ output += CSS_RULES.format(name=name)
+ output += '}'
+
+ result += output + '\n'
+
+ return result
+
+
+def build_colorscheme(source_file: str,
+ selector: str = ':root') -> str:
+ """
+ Build CSS colorscheme from source file.
+
+ :param selector:
+ CSS selector to use for this group.
+ :param source_file:
+ Yaml file containing mapping from abrtract highlighting groups,
+ to CSS attributes.
+ :returns:
+ Generated CSS code, applicable to be written directly to a
+ file.
+ """
+ with open(source_file) as f:
+ data = yaml.full_load(f)
+
+ result = ''
+ result += HEADER.format(source=source_file,
+ time=datetime.now())
+ result += f'{selector} {{\n'
+ for group_key in HIGHLIGHT_GROUPS:
+ if group := data.get(group_key):
+ for value_key in HIGHLIGHT_VARIABLES:
+ if value := group.get(value_key):
+ result += f' --hl-{group_key}-{value_key}: {value};\n'
+ if raw := group.get('raw-append'):
+ result += raw + '\n'
+ # Raw CSS rules, useful to capture something not handled by
+ # the abstract groups.
+ if raw := data.get('raw-append'):
+ result += raw + '\n'
+
+ result += '}\n'
+ return result
+
+
+def run_colorscheme(args: argparse.Namespace) -> None:
+ """Entry point when using the colorscheme mode."""
+ print(build_colorscheme(selector=args.selector,
+ source_file=args.source))
+
+
+def run_highlight(args: argparse.Namespace) -> None:
+ """Entry point when using the highlight mode."""
+ print(build_highlight_map(source_file=args.source))
+
+
+def main() -> None:
+ """Primary entry point of program."""
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers()
+
+ parser_hl = subparsers.add_parser('highlight')
+ parser_hl.set_defaults(func=run_highlight)
+ parser_hl.add_argument('source')
+
+ parser_cs = subparsers.add_parser('colorscheme')
+ parser_cs.set_defaults(func=run_colorscheme)
+ parser_cs.add_argument('--selector',
+ default=':root')
+ parser_cs.add_argument('source')
+
+ args = parser.parse_args()
+
+ args.func(args)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/static-src/colorscheme/default.yaml b/static-src/colorscheme/default.yaml
new file mode 100644
index 0000000..5fa61d3
--- /dev/null
+++ b/static-src/colorscheme/default.yaml
@@ -0,0 +1,23 @@
+comment:
+ color: '#3D7B7B'
+ font-style: italic
+error:
+escape:
+ color: red
+interpolate:
+keyword:
+ color: green
+ font-weight: bold
+line:
+number:
+ color: green
+operator:
+ color: '#666666'
+regex:
+ color: green
+special:
+ color: olive
+string:
+ color: '#BA2121'
+variable:
+ color: darkblue
diff --git a/static-src/highlight/andre_simon.yaml b/static-src/highlight/andre_simon.yaml
new file mode 100644
index 0000000..84dd00d
--- /dev/null
+++ b/static-src/highlight/andre_simon.yaml
@@ -0,0 +1,26 @@
+# highlight(1)
+comment:
+ - mlc
+escape:
+ - esc
+interpolate:
+ - ipl
+keyword:
+ - kwa
+line:
+ - lin
+number:
+ - num
+operator:
+ - sym
+regex:
+ - kwc
+string:
+ - sng
+variable:
+ - kwb
+error:
+ - err
+ - erm
+special:
+ - kwd
diff --git a/static-src/highlight/muppet.yaml b/static-src/highlight/muppet.yaml
new file mode 100644
index 0000000..93491ad
--- /dev/null
+++ b/static-src/highlight/muppet.yaml
@@ -0,0 +1,25 @@
+# Muppet's built in output
+comment:
+ - comment
+error:
+ - parse-error
+interpolate:
+ - str-var
+keyword:
+ - keyword
+ - literal
+operator:
+ - and
+ - or
+regex:
+ - regex
+special:
+ - parameter
+ - qr
+number:
+ - number
+string:
+ - string
+variable:
+ - qn
+ - var
diff --git a/static-src/highlight/pygments.yaml b/static-src/highlight/pygments.yaml
new file mode 100644
index 0000000..1f57a7a
--- /dev/null
+++ b/static-src/highlight/pygments.yaml
@@ -0,0 +1,61 @@
+# Pygmentize(1)
+comment:
+ - c
+ - ch
+ - cm
+ - cp
+ - cpf
+ - c1
+ - cs
+error:
+ - err
+escape:
+ - se
+interpolate:
+ - si
+keyword:
+ - k
+ - kc
+ - kd
+ - kn
+ - kp
+ - kr
+ - kt
+number:
+ - m
+ - mb
+ - mf
+ - mh
+ - mi
+ - mo
+operator:
+ - o
+regex:
+ - sr
+string:
+ - s
+ - sa
+ - sb
+ - sc
+ - dl
+ - sd
+ - s2
+ - sh
+ - sx
+ - sr
+ - s1
+variable:
+ - n
+ - nb
+ - nc
+ - 'no'
+ - nd
+ - ni
+ - ne
+ - nf
+ - nl
+ - nn
+ - nt
+ - nv
+special:
+ - na
diff --git a/static-src/style.scss b/static-src/style.scss
index b5c4407..2f0fba2 100644
--- a/static-src/style.scss
+++ b/static-src/style.scss
@@ -1,4 +1,3 @@
-
/* -------------------------------------------------- */
.parse-error {
@@ -28,9 +27,11 @@ h3 {
/* -------------------------------------------------- */
+/*
.documentation {
display: none;
}
+*/
/*
.var {
@@ -79,6 +80,7 @@ code.json {
border-left-style: dotted;
display: inline-block;
padding-left: 1em;
+
font-family: sans;
font-size: 80%;
@@ -93,8 +95,20 @@ code.json {
/* -------------------------------------------------- */
+@import "colorscheme_default";
+
+.highlight-pygments {
+ @import "highlight_pygments";
+}
+
+.highlight-andre-simon {
+ @import "highlight_andre_simon";
+}
+
+.highlight-muppet {
+ @import "highlight_muppet";
+}
+
@import "breadcrumb";
-@import "highlight";
@import "tabset";
-
@import "color-headers";
diff --git a/static/.gitignore b/static/.gitignore
deleted file mode 100644
index b3a5267..0000000
--- a/static/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.css
diff --git a/templates/code_page.html b/templates/code_page.html
index 80ad037..0b588cc 100644
--- a/templates/code_page.html
+++ b/templates/code_page.html
@@ -8,7 +8,9 @@ Parameters:
{% extends "base.html" %}
{% block content %}
<ul>
- <li><a href="source.pp.txt">Raw Source code</a></li>
+ <li><a href="index.html">Rendered</a></li>
+ <li><a href="source.pp.html">Source</a></li>
+ <li><a href="source.pp.txt">Raw Source</a></li>
<li><a href="source.json">JSON blob</a></li>
</ul>
{{ content }}