summaryrefslogtreecommitdiffstats
path: root/external
diff options
context:
space:
mode:
Diffstat (limited to 'external')
-rwxr-xr-xexternal/autopygmentize145
-rwxr-xr-xexternal/lasso-builtins-generator-9.lasso162
-rw-r--r--external/lilypond-builtins-generator.ly391
-rw-r--r--external/markdown-processor.py66
-rw-r--r--external/moin-parser.py111
-rw-r--r--external/pygments.bashcomp38
-rw-r--r--external/rst-directive.py81
-rw-r--r--external/scheme-builtins-generator.scm116
8 files changed, 1110 insertions, 0 deletions
diff --git a/external/autopygmentize b/external/autopygmentize
new file mode 100755
index 0000000..85d2366
--- /dev/null
+++ b/external/autopygmentize
@@ -0,0 +1,145 @@
+#!/bin/bash
+# Best effort auto-pygmentization with transparent decompression
+# by Reuben Thomas 2008-2022
+# This program is in the public domain.
+
+# Strategy: first see if pygmentize can find a lexer; if not, ask file; if that finds nothing, fail
+# Set the environment variable PYGMENTIZE_OPTS or pass options before the file path to configure pygments.
+
+# This program can be used as a .lessfilter for the less pager to auto-color less's output
+
+file="${!#}" # last argument
+options=${@:1:$(($#-1))} # handle others args as options to pass to pygmentize
+
+file_common_opts="--brief --dereference"
+
+case $(file --mime-type --uncompress $file_common_opts "$file") in
+ application/xml|image/svg+xml) lexer=xml;;
+ application/javascript) lexer=javascript;;
+ application/json) lexer=json;;
+ text/html) lexer=html;;
+ text/troff) lexer=nroff;;
+ text/x-asm) lexer=nasm;;
+ text/x-awk) lexer=awk;;
+ text/x-c) lexer=c;;
+ text/x-c++) lexer=cpp;;
+ text/x-clojure) lexer=clojure;;
+ text/x-crystal) lexer=crystal;;
+ text/x-diff) lexer=diff;;
+ text/x-execline) lexer=execline;;
+ text/x-forth) lexer=forth;;
+ text/x-fortran) lexer=fortran;;
+ text/x-gawk) lexer=gawk;;
+ text/x-java) lexer=java;;
+ text/x-lisp) lexer=common-lisp;;
+ text/x-lua|text/x-luatex) lexer=lua;;
+ text/x-makefile) lexer=make;;
+ text/x-msdos-batch) lexer=bat;;
+ text/x-nawk) lexer=nawk;;
+ text/x-objective-c) lexer=objective-c;;
+ text/x-pascal) lexer=pascal;;
+ text/x-perl) lexer=perl;;
+ text/x-php) lexer=php;;
+ text/x-po) lexer=po;;
+ text/x-python) lexer=python;;
+ text/x-ruby) lexer=ruby;;
+ text/x-script.python) lexer=python;;
+ text/x-shellscript) lexer=sh;;
+ text/x-tcl) lexer=tcl;;
+ text/x-tex|text/x-texinfo) lexer=latex;; # FIXME: texinfo really needs its own lexer
+ text/xml) lexer=xml;;
+ text/vnd.graphviz) lexer=graphviz;;
+
+ # Types that file outputs which pygmentize didn't support as of file 5.41, pygments 2.11.2
+ # text/binary
+ # text/calendar
+ # text/PGP
+ # text/prs.lines.tag
+ # text/rtf
+ # text/spreadsheet
+ # text/texmacs
+ # text/vcard
+ # text/vnd.sosi
+ # text/x-Algol68
+ # text/x-bcpl
+ # text/x-dmtf-mif
+ # text/x-gimp-curve
+ # text/x-gimp-ggr
+ # text/x-gimp-gpl
+ # text/x-info
+ # text/x-installshield-lid
+ # text/x-m4
+ # text/x-modulefile
+ # text/x-ms-adm
+ # text/x-ms-cpx
+ # text/x-ms-regedirt
+ # text/x-ms-tag
+ # text/x-systemtap
+ # text/x-vcard
+ # text/x-wine-extension-reg
+ # text/x-xmcd
+
+ text/plain) # special filenames. TODO: insert more
+ case $(basename "$file") in
+ .zshrc) lexer=sh;;
+ esac
+ # pygmentize -N is much cheaper than file, but makes some bad guesses (e.g.
+ # it guesses ".pl" is Prolog, not Perl)
+ lexer=$(pygmentize -N "$file")
+ ;;
+esac
+
+# Find a concatenator for compressed files
+concat=
+concat_opts=
+case $(file $file_common_opts --mime-type "$file") in
+ # TODO: add support
+ # application/x-rzip (does not decompress to stdout)
+ # application/x-dzip (Windows only)
+ application/gzip|application/x-gzip) concat=zcat;;
+ application/x-bzip) concat=bzip; concat_opts=-dc;;
+ application/x-bzip2) concat=bzcat;;
+ application/x-lz4) concat=lz4; concat_opts=-dc;;
+ application/x-lzh-compressed) concat=p7zip; concat_opts=-dc;;
+ application/x-lzma) concat=lzcat;;
+ application/x-lzip) concat=lzip; concat_opts=-dc;;
+ application/x-xz) concat=xzcat;;
+ application/x-zoo) concat=zoo; concat_opts=fu;;
+esac
+# If concat is unset or doesn't exist, use cat instead
+if [[ "$concat" == "" ]] || ! command -v "$concat"; then
+ concat=cat
+ concat_opts=
+fi
+
+# Find a suitable reader, preceded by a hex dump for binary files,
+# or fmt for text with very long lines
+prereader=""
+reader=cat
+encoding=$(file --mime-encoding --uncompress $file_common_opts "$file")
+# FIXME: need a way to switch between hex and text view, as file often
+# misdiagnoses files when they contain a few control characters
+# if [[ $encoding == "binary" ]]; then
+# prereader="od -x" # POSIX fallback
+# if [[ -n $(which hd) ]]; then
+# prereader=hd # preferred
+# fi
+# lexer=hexdump
+# encoding=latin1
+#el
+# FIXME: Using fmt does not work well for system logs
+# if [[ "$lexer" == "text" ]]; then
+# if file "$file" | grep -ql "text, with very long lines"; then
+# reader=fmt
+# fi
+# fi
+if [[ "$lexer" != "text" ]]; then
+ reader="pygmentize -O inencoding=$encoding $PYGMENTIZE_OPTS $options -l $lexer"
+fi
+
+# Run the reader
+if [[ -n "$prereader" ]]; then
+ exec $concat "$file" | $prereader | $reader
+else
+ exec $concat "$file" | $reader
+fi
diff --git a/external/lasso-builtins-generator-9.lasso b/external/lasso-builtins-generator-9.lasso
new file mode 100755
index 0000000..0156299
--- /dev/null
+++ b/external/lasso-builtins-generator-9.lasso
@@ -0,0 +1,162 @@
+#!/usr/bin/lasso9
+
+/*
+ Builtins Generator for Lasso 9
+
+ This is the shell script that was used to extract Lasso 9's built-in keywords
+ and generate most of the _lasso_builtins.py file. When run, it creates a file
+ containing the types, traits, methods, and members of the currently-installed
+ version of Lasso 9.
+
+ A list of tags in Lasso 8 can be generated with this code:
+
+ <?LassoScript
+ local('l8tags' = list,
+ 'l8libs' = array('Cache','ChartFX','Client','Database','File','HTTP',
+ 'iCal','Lasso','Link','List','PDF','Response','Stock','String',
+ 'Thread','Valid','WAP','XML'));
+ iterate(#l8libs, local('library'));
+ local('result' = namespace_load(#library));
+ /iterate;
+ iterate(tags_list, local('i'));
+ #l8tags->insert(string_removeleading(#i, -pattern='_global_'));
+ /iterate;
+ #l8tags->sort;
+ iterate(#l8tags, local('i'));
+ string_lowercase(#i)+"<br>";
+ /iterate;
+
+*/
+
+output("This output statement is required for a complete list of methods.")
+local(f) = file("_lasso_builtins-9.py")
+#f->doWithClose => {
+
+#f->openTruncate
+#f->writeString('# -*- coding: utf-8 -*-
+"""
+ pygments.lexers._lasso_builtins
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Built-in Lasso types, traits, methods, and members.
+
+ :copyright: Copyright 2006-'+date->year+' by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+')
+
+// Load and register contents of $LASSO9_MASTER_HOME/LassoModules/
+database_initialize
+
+// Load all of the libraries from builtins and lassoserver
+// This forces all possible available types and methods to be registered
+local(srcs =
+ (:
+ dir(sys_masterHomePath + '/LassoLibraries/builtins/')->eachFilePath,
+ dir(sys_masterHomePath + '/LassoLibraries/lassoserver/')->eachFilePath
+ )
+)
+
+with topLevelDir in delve(#srcs)
+where not #topLevelDir->lastComponent->beginsWith('.')
+do protect => {
+ handle_error => {
+ stdoutnl('Unable to load: ' + #topLevelDir + ' ' + error_msg)
+ }
+ library_thread_loader->loadLibrary(#topLevelDir)
+ stdoutnl('Loaded: ' + #topLevelDir)
+}
+
+email_initialize
+log_initialize
+session_initialize
+
+local(
+ typesList = set(),
+ traitsList = set(),
+ unboundMethodsList = set(),
+ memberMethodsList = set()
+)
+
+// types
+with type in sys_listTypes
+where not #type->asString->endsWith('$') // skip threads
+do {
+ #typesList->insert(#type)
+}
+
+// traits
+with trait in sys_listTraits
+where not #trait->asString->beginsWith('$') // skip combined traits
+do {
+ #traitsList->insert(#trait)
+}
+
+// member methods
+with type in #typesList
+do {
+ with method in #type->getType->listMethods
+ where #method->typeName == #type // skip inherited methods
+ let name = #method->methodName
+ where not #name->asString->endsWith('=') // skip setter methods
+ where #name->asString->isAlpha(1) // skip unpublished methods
+ do {
+ #memberMethodsList->insert(#name)
+ }
+}
+with trait in #traitsList
+do {
+ with method in #trait->getType->provides
+ where #method->typeName == #trait // skip inherited methods
+ let name = #method->methodName
+ where not #name->asString->endsWith('=') // skip setter methods
+ where #name->asString->isAlpha(1) // skip unpublished methods
+ do {
+ #memberMethodsList->insert(#name)
+ }
+}
+
+// unbound methods
+with method in sys_listUnboundMethods
+let name = #method->methodName
+where not #name->asString->endsWith('=') // skip setter methods
+where #name->asString->isAlpha(1) // skip unpublished methods
+where #typesList !>> #name
+where #traitsList !>> #name
+do {
+ #unboundMethodsList->insert(#name)
+}
+
+// write to file
+with i in (:
+ pair(#typesList, "BUILTINS = {
+ 'Types': (
+"),
+ pair(#traitsList, " ),
+ 'Traits': (
+"),
+ pair(#unboundMethodsList, " ),
+ 'Unbound Methods': (
+"),
+ pair(#memberMethodsList, " )
+}
+MEMBERS = {
+ 'Member Methods': (
+")
+)
+do {
+ #f->writeString(#i->second)
+ with t in (#i->first)
+ let ts = #t->asString
+ order by #ts
+ do {
+ #f->writeString(" '"+#ts->lowercase&asString+"',\n")
+ }
+}
+
+#f->writeString(" )
+}
+")
+
+}
diff --git a/external/lilypond-builtins-generator.ly b/external/lilypond-builtins-generator.ly
new file mode 100644
index 0000000..983b4c3
--- /dev/null
+++ b/external/lilypond-builtins-generator.ly
@@ -0,0 +1,391 @@
+%% Autogenerate a list of LilyPond keywords
+
+\version "2.23.6"
+
+#(use-modules (ice-9 receive)
+ (ice-9 regex))
+
+#(define port (open-output-file "../pygments/lexers/_lilypond_builtins.py"))
+
+#(define output-preamble
+ "\"\"\"
+ pygments.lexers._lilypond_builtins
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ LilyPond builtins.
+
+ :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+\"\"\"
+
+# Contents generated by the script lilypond-builtins-generator.ly
+# found in the external/ directory of the source tree.
+
+")
+
+#(format port "~a" output-preamble)
+
+#(define (dump-py-list name vals)
+ (let* ((string-vals
+ (map symbol->string vals))
+ (fixed-vals
+ (filter-map
+ (lambda (str)
+ ; To avoid conflicts with Scheme builtins,
+ ; a leading backslash is prepended to \<,
+ ; \= and a few others. The lexer finds it
+ ; itself, so remove it here.
+ (cond
+ ((equal? str "\\\\")
+ #f)
+ ((string-startswith str "\\")
+ (string-drop str 1))
+ (else
+ str)))
+ string-vals))
+ (sorted-vals ; reproducibility
+ ; Avoid duplicates (e.g., identical pitches
+ ; in different languages)
+ (uniq-list
+ (sort fixed-vals string<?)))
+ (formatted-vals
+ (map
+ (lambda (val)
+ (format #f " \"~a\"," val name))
+ sorted-vals))
+ (joint-vals
+ (string-join formatted-vals "\n")))
+ (format port
+ "~a = [
+~a
+]
+
+"
+ name
+ joint-vals)))
+
+
+%% KEYWORDS
+
+#(define keywords
+ '(
+ ; Lexical modes.
+ notemode
+ lyricmode
+ lyricsto
+ addlyrics
+ chordmode
+ chords
+ figuremode
+ figures
+ drummode
+ drums
+ ; Output definitions.
+ header
+ layout
+ midi
+ paper
+ ; Context definitions.
+ ;; \context is also used in music. We take it as
+ ;; a keyword in both cases.
+ context
+ with
+ name
+ type
+ accepts
+ denies
+ alias
+ defaultchild
+ consists
+ remove
+ description
+ ;; Not strictly a keyword, but can be viewed so.
+ inherit-acceptability
+ ; Blocks.
+ book
+ bookpart
+ score
+ ; Other.
+ new
+ etc
+ include
+ language
+ version))
+
+#(dump-py-list 'keywords keywords)
+
+%% CLEFS
+
+#(define all-clefs
+ (map string->symbol (map car supported-clefs)))
+
+#(dump-py-list 'clefs all-clefs)
+
+%% SCALES
+
+#(define all-scales
+ '(major
+ minor
+ ionian
+ locrian
+ aeolian
+ mixolydian
+ lydian
+ phrygian
+ dorian))
+
+#(dump-py-list 'scales all-scales)
+
+%% REPEAT TYPES
+
+#(define all-repeat-types
+ '(volta percent unfold segno))
+
+#(dump-py-list 'repeat_types all-repeat-types)
+
+%% UNITS
+
+#(define all-units
+ '(mm cm in pt staff-space))
+
+#(dump-py-list 'units all-units)
+
+%% CHORD MODIFIERS
+
+#(define all-chord-modifiers
+ '(m dim aug maj))
+
+#(dump-py-list 'chord_modifiers all-chord-modifiers)
+
+%% PITCHES
+
+#(define all-pitch-language-names
+ (map car language-pitch-names))
+
+#(dump-py-list 'pitch_language_names all-pitch-language-names)
+
+#(define all-pitch-names
+ (append
+ ; We highlight rests just like pitches.
+ '(r R)
+ (map car (append-map cdr language-pitch-names))
+ ; Drum note names.
+ (map car drumPitchNames)))
+
+#(dump-py-list 'pitches all-pitch-names)
+
+%% MUSIC FUNCTIONS AND SHORTCUTS
+
+% View these as music functions.
+#(define extra-music-functions
+ '(set
+ unset
+ override
+ revert
+ tweak
+ once
+ undo
+ temporary
+ repeat
+ alternative
+ tempo
+ change))
+
+#(let* ((module (current-module))
+ (module-alist (ly:module->alist module))
+ (all-music-functions
+ (filter
+ (lambda (entry)
+ (ly:music-function? (cdr entry)))
+ module-alist))
+ (all-predefined-music-objects
+ (filter
+ (lambda (entry)
+ (ly:music? (cdr entry)))
+ module-alist)))
+ (receive (articulations non-articulations)
+ (partition
+ (lambda (entry)
+ (ly:event? (cdr entry)))
+ all-predefined-music-objects)
+ (receive (dynamics non-dynamic-articulations)
+ (partition
+ (lambda (entry)
+ (any
+ (lambda (type)
+ (music-is-of-type? (cdr entry)
+ type))
+ '(dynamic-event crescendo-event decrescendo-event)))
+ articulations)
+ (dump-py-list 'music_functions
+ (append extra-music-functions
+ (map car all-music-functions)))
+ (dump-py-list 'dynamics (map car dynamics))
+ (dump-py-list 'articulations (map car non-dynamic-articulations))
+ (dump-py-list 'music_commands (map car non-articulations)))))
+
+%% MARKUP COMMANDS
+
+#(let* ((markup-name-regexp
+ (make-regexp "(.*)-markup(-list)?"))
+ (modules
+ (cons (current-module)
+ (map resolve-module '((lily) (lily accreg)))))
+ (alist
+ (apply append
+ (map ly:module->alist modules)))
+ (markup-commands
+ (filter
+ (lambda (entry)
+ (or (markup-function? (cdr entry))
+ (markup-list-function? (cdr entry))))
+ alist))
+ (markup-command-names
+ (map
+ (lambda (entry)
+ (let* ((string-name (symbol->string (car entry)))
+ (match (regexp-exec markup-name-regexp string-name)))
+ (string->symbol (match:substring match 1))))
+ markup-commands))
+ (markup-words
+ (append '(markup markuplist)
+ markup-command-names)))
+ (dump-py-list 'markup_commands markup-words))
+
+%% GROBS
+
+#(let ((grob-names (map car all-grob-descriptions)))
+ (dump-py-list 'grobs grob-names))
+
+%% CONTEXTS
+
+#(let* ((layout-module
+ (ly:output-def-scope $defaultlayout))
+ (layout-alist
+ (ly:module->alist layout-module))
+ (all-context-defs
+ (filter
+ (lambda (entry)
+ (ly:context-def? (cdr entry)))
+ layout-alist))
+ (context-def-names
+ (map car all-context-defs)))
+ (dump-py-list 'contexts context-def-names))
+
+%% TRANSLATORS
+
+#(let* ((all-translators
+ (ly:get-all-translators))
+ (translator-names
+ (map ly:translator-name all-translators)))
+ (dump-py-list 'translators translator-names))
+
+%% SCHEME FUNCTIONS
+
+#(let* ((module (resolve-module '(lily)))
+ (module-alist (ly:module->alist module))
+ (all-functions
+ (filter
+ (lambda (entry)
+ (or (procedure? (cdr entry))
+ (macro? (cdr entry))))
+ module-alist))
+ (all-function-names
+ (map car all-functions)))
+ (dump-py-list 'scheme_functions all-function-names))
+
+%% PROPERTIES
+
+#(dump-py-list 'context_properties all-translation-properties)
+#(dump-py-list 'grob_properties all-backend-properties)
+
+%% PAPER VARIABLES
+
+% Reference: https://lilypond.org/doc/v2.22/Documentation/notation/page-layout
+#(define all-paper-variables
+ '(paper-height
+ top-margin
+ bottom-margin
+ ragged-bottom
+ ragged-last-bottom
+ markup-system-spacing
+ score-markup-spacing
+ score-system-spacing
+ system-system-spacing
+ markup-markup-spacing
+ last-bottom-spacing
+ top-system-spacing
+ top-markup-spacing
+ paper-width
+ line-width
+ left-margin
+ right-margin
+ check-consistency
+ ragged-right
+ ragged-last
+ two-sided
+ inner-margin
+ outer-margin
+ binding-offset
+ horizontal-shift
+ indent
+ short-indent
+ max-systems-per-page
+ min-systems-per-page
+ systems-per-page
+ system-count
+ page-breaking
+ page-breaking-system-system-spacing
+ page-count
+ blank-page-penalty
+ blank-last-page-penalty
+ auto-first-page-number
+ first-page-number
+ print-first-page-number
+ page-number-type
+ page-spacing-weight
+ print-all-headers
+ system-separator-markup
+ footnote-separator-markup
+ ;; Let's view these four as \paper variables.
+ basic-distance
+ minimum-distance
+ padding
+ stretchability
+ ;; These were forgotten in the documentation.
+ evenHeaderMarkup
+ oddHeaderMarkup
+ evenFooterMarkup
+ oddFooterMarkup
+ bookTitleMarkup
+ scoreTitleMarkup
+ ))
+
+#(dump-py-list 'paper_variables all-paper-variables)
+
+%% HEADER VARIABLES
+
+% Reference: https://lilypond.org/doc/v2.22/Documentation/notation/creating-titles-headers-and-footers.html#default-layout-of-bookpart-and-score-titles
+#(define all-header-variables
+ '(dedication
+ title
+ subtitle
+ subsubtitle
+ instrument
+ poet
+ composer
+ meter
+ arranger
+ tagline
+ copyright
+ piece
+ opus
+ ; The following are used in LSR snippets and regression tests.
+ lsrtags
+ doctitle
+ texidoc))
+
+#(dump-py-list 'header_variables all-header-variables)
+
+
+#(close-port port)
diff --git a/external/markdown-processor.py b/external/markdown-processor.py
new file mode 100644
index 0000000..d72012f
--- /dev/null
+++ b/external/markdown-processor.py
@@ -0,0 +1,66 @@
+"""
+ The Pygments Markdown Preprocessor
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This fragment is a Markdown_ preprocessor that renders source code
+ to HTML via Pygments. To use it, invoke Markdown like so::
+
+ import markdown
+
+ html = markdown.markdown(someText, extensions=[CodeBlockExtension()])
+
+ This uses CSS classes by default, so use
+ ``pygmentize -S <some style> -f html > pygments.css``
+ to create a stylesheet to be added to the website.
+
+ You can then highlight source code in your markdown markup::
+
+ [sourcecode:lexer]
+ some code
+ [/sourcecode]
+
+ .. _Markdown: https://pypi.python.org/pypi/Markdown
+
+ :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+# Options
+# ~~~~~~~
+
+# Set to True if you want inline CSS styles instead of classes
+INLINESTYLES = False
+
+
+import re
+
+from markdown.preprocessors import Preprocessor
+from markdown.extensions import Extension
+
+from pygments import highlight
+from pygments.formatters import HtmlFormatter
+from pygments.lexers import get_lexer_by_name, TextLexer
+
+
+class CodeBlockPreprocessor(Preprocessor):
+
+ pattern = re.compile(r'\[sourcecode:(.+?)\](.+?)\[/sourcecode\]', re.S)
+
+ formatter = HtmlFormatter(noclasses=INLINESTYLES)
+
+ def run(self, lines):
+ def repl(m):
+ try:
+ lexer = get_lexer_by_name(m.group(1))
+ except ValueError:
+ lexer = TextLexer()
+ code = highlight(m.group(2), lexer, self.formatter)
+ code = code.replace('\n\n', '\n&nbsp;\n').replace('\n', '<br />')
+ return '\n\n<div class="code">%s</div>\n\n' % code
+ joined_lines = "\n".join(lines)
+ joined_lines = self.pattern.sub(repl, joined_lines)
+ return joined_lines.split("\n")
+
+class CodeBlockExtension(Extension):
+ def extendMarkdown(self, md, md_globals):
+ md.preprocessors.add('CodeBlockPreprocessor', CodeBlockPreprocessor(), '_begin')
diff --git a/external/moin-parser.py b/external/moin-parser.py
new file mode 100644
index 0000000..562b76f
--- /dev/null
+++ b/external/moin-parser.py
@@ -0,0 +1,111 @@
+"""
+ The Pygments MoinMoin Parser
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This is a MoinMoin parser plugin that renders source code to HTML via
+ Pygments; you need Pygments 0.7 or newer for this parser to work.
+
+ To use it, set the options below to match your setup and put this file in
+ the data/plugin/parser subdirectory of your Moin instance, and give it the
+ name that the parser directive should have. For example, if you name the
+ file ``code.py``, you can get a highlighted Python code sample with this
+ Wiki markup::
+
+ {{{
+ #!code python
+ [...]
+ }}}
+
+ Additionally, if you set ATTACHMENTS below to True, Pygments will also be
+ called for all attachments for whose filenames there is no other parser
+ registered.
+
+ You are responsible for including CSS rules that will map the Pygments CSS
+ classes to colors. You can output a stylesheet file with `pygmentize`, put
+ it into the `htdocs` directory of your Moin instance and then include it in
+ the `stylesheets` configuration option in the Moin config, e.g.::
+
+ stylesheets = [('screen', '/htdocs/pygments.css')]
+
+ If you do not want to do that and are willing to accept larger HTML
+ output, you can set the INLINESTYLES option below to True.
+
+ :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+# Options
+# ~~~~~~~
+
+# Set to True if you want to highlight attachments, in addition to
+# {{{ }}} blocks.
+ATTACHMENTS = True
+
+# Set to True if you want inline CSS styles instead of classes
+INLINESTYLES = False
+
+
+import sys
+
+from pygments import highlight
+from pygments.lexers import get_lexer_by_name, get_lexer_for_filename, TextLexer
+from pygments.formatters import HtmlFormatter
+from pygments.util import ClassNotFound
+
+
+# wrap lines in <span>s so that the Moin-generated line numbers work
+class MoinHtmlFormatter(HtmlFormatter):
+ def wrap(self, source, outfile):
+ for line in source:
+ yield 1, '<span class="line">' + line[1] + '</span>'
+
+htmlformatter = MoinHtmlFormatter(noclasses=INLINESTYLES)
+textlexer = TextLexer()
+codeid = [0]
+
+
+class Parser:
+ """
+ MoinMoin Pygments parser.
+ """
+ if ATTACHMENTS:
+ extensions = '*'
+ else:
+ extensions = []
+
+ Dependencies = []
+
+ def __init__(self, raw, request, **kw):
+ self.raw = raw
+ self.req = request
+ if "format_args" in kw:
+ # called from a {{{ }}} block
+ try:
+ self.lexer = get_lexer_by_name(kw['format_args'].strip())
+ except ClassNotFound:
+ self.lexer = textlexer
+ return
+ if "filename" in kw:
+ # called for an attachment
+ filename = kw['filename']
+ else:
+ # called for an attachment by an older moin
+ # HACK: find out the filename by peeking into the execution
+ # frame which might not always work
+ try:
+ frame = sys._getframe(1)
+ filename = frame.f_locals['filename']
+ except:
+ filename = 'x.txt'
+ try:
+ self.lexer = get_lexer_for_filename(filename)
+ except ClassNotFound:
+ self.lexer = textlexer
+
+ def format(self, formatter):
+ codeid[0] += 1
+ id = "pygments_%s" % codeid[0]
+ w = self.req.write
+ w(formatter.code_area(1, id, start=1, step=1))
+ w(formatter.rawHTML(highlight(self.raw, self.lexer, htmlformatter)))
+ w(formatter.code_area(0, id))
diff --git a/external/pygments.bashcomp b/external/pygments.bashcomp
new file mode 100644
index 0000000..1299fdb
--- /dev/null
+++ b/external/pygments.bashcomp
@@ -0,0 +1,38 @@
+#!bash
+#
+# Bash completion support for Pygments (the 'pygmentize' command).
+#
+
+_pygmentize()
+{
+ local cur prev
+
+ COMPREPLY=()
+ cur=`_get_cword`
+ prev=${COMP_WORDS[COMP_CWORD-1]}
+
+ case "$prev" in
+ -f)
+ FORMATTERS=`pygmentize -L formatters | grep '* ' | cut -c3- | sed -e 's/,//g' -e 's/:$//'`
+ COMPREPLY=( $( compgen -W '$FORMATTERS' -- "$cur" ) )
+ return 0
+ ;;
+ -l)
+ LEXERS=`pygmentize -L lexers | grep '* ' | cut -c3- | sed -e 's/,//g' -e 's/:$//'`
+ COMPREPLY=( $( compgen -W '$LEXERS' -- "$cur" ) )
+ return 0
+ ;;
+ -S)
+ STYLES=`pygmentize -L styles | grep '* ' | cut -c3- | sed s/:$//`
+ COMPREPLY=( $( compgen -W '$STYLES' -- "$cur" ) )
+ return 0
+ ;;
+ esac
+
+ if [[ "$cur" == -* ]]; then
+ COMPREPLY=( $( compgen -W '-f -l -S -L -g -O -P -F \
+ -N -H -h -V -o' -- "$cur" ) )
+ return 0
+ fi
+}
+complete -F _pygmentize -o default pygmentize
diff --git a/external/rst-directive.py b/external/rst-directive.py
new file mode 100644
index 0000000..5872185
--- /dev/null
+++ b/external/rst-directive.py
@@ -0,0 +1,81 @@
+"""
+ The Pygments reStructuredText directive
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ This fragment is a Docutils_ 0.5 directive that renders source code
+ (to HTML only, currently) via Pygments.
+
+ To use it, adjust the options below and copy the code into a module
+ that you import on initialization. The code then automatically
+ registers a ``sourcecode`` directive that you can use instead of
+ normal code blocks like this::
+
+ .. sourcecode:: python
+
+ My code goes here.
+
+ If you want to have different code styles, e.g. one with line numbers
+ and one without, add formatters with their names in the VARIANTS dict
+ below. You can invoke them instead of the DEFAULT one by using a
+ directive option::
+
+ .. sourcecode:: python
+ :linenos:
+
+ My code goes here.
+
+ Look at the `directive documentation`_ to get all the gory details.
+
+ .. _Docutils: https://docutils.sourceforge.io/
+ .. _directive documentation:
+ https://docutils.sourceforge.io/docs/howto/rst-directives.html
+
+ :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+"""
+
+# Options
+# ~~~~~~~
+
+# Set to True if you want inline CSS styles instead of classes
+INLINESTYLES = False
+
+from pygments.formatters import HtmlFormatter
+
+# The default formatter
+DEFAULT = HtmlFormatter(noclasses=INLINESTYLES)
+
+# Add name -> formatter pairs for every variant you want to use
+VARIANTS = {
+ # 'linenos': HtmlFormatter(noclasses=INLINESTYLES, linenos=True),
+}
+
+
+from docutils import nodes
+from docutils.parsers.rst import directives, Directive
+
+from pygments import highlight
+from pygments.lexers import get_lexer_by_name, TextLexer
+
+class Pygments(Directive):
+ """ Source code syntax highlighting.
+ """
+ required_arguments = 1
+ optional_arguments = 0
+ final_argument_whitespace = True
+ option_spec = {key: directives.flag for key in VARIANTS}
+ has_content = True
+
+ def run(self):
+ self.assert_has_content()
+ try:
+ lexer = get_lexer_by_name(self.arguments[0])
+ except ValueError:
+ # no lexer found - use the text one instead of an exception
+ lexer = TextLexer()
+ # take an arbitrary option if more than one is given
+ formatter = self.options and VARIANTS[list(self.options)[0]] or DEFAULT
+ parsed = highlight('\n'.join(self.content), lexer, formatter)
+ return [nodes.raw('', parsed, format='html')]
+
+directives.register_directive('sourcecode', Pygments)
diff --git a/external/scheme-builtins-generator.scm b/external/scheme-builtins-generator.scm
new file mode 100644
index 0000000..5c260b8
--- /dev/null
+++ b/external/scheme-builtins-generator.scm
@@ -0,0 +1,116 @@
+;; Autogenerate a list of Scheme keywords (i.e., macros) and built-in
+;; functions. This is written for the Guile implementation. The
+;; principle of autogenerating this has the advantage of catching many
+;; builtins that would be tedious to maintain by hand, and the
+;; disadvantage that some builtins very specific to Guile and not
+;; relevant to other implementations are caught as well. However,
+;; since Scheme builtin function names tend to be rather specific,
+;; this should not be a significant problem.
+
+(define port (open-output-file "../pygments/lexers/_scheme_builtins.py"))
+
+(display
+ "\"\"\"
+ pygments.lexers._scheme_builtins
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Scheme builtins.
+
+ :copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+\"\"\"
+"
+ port)
+
+(format port
+"\n# Autogenerated by external/scheme-builtins-generator.scm\n\
+# using Guile ~a.\n\n"
+ (version))
+
+(use-modules (srfi srfi-1)
+ (ice-9 match))
+
+(define relevant-modules
+ ;; This is a nightmare. Scheme builtins are split in
+ ;; gazillions of standards, SRFIs and implementation
+ ;; extensions. With so many sources, it's hard to define
+ ;; what is really a Scheme builtin. This is a rather
+ ;; conservative list of Guile modules that might be used
+ ;; the most frequently (somewhat subjective, admittedly).
+ '(
+ ;; The real builtins.
+ (guile)
+ ;; Let's include the fundamental list library.
+ (srfi srfi-1)
+ ;; define-record-type
+ (srfi srfi-9)
+ ;; let-values, let*-values
+ (srfi srfi-11)
+ ;; case-lambda
+ (srfi srfi-16)
+ ;; Pattern matching
+ (ice-9 match)
+ ;; Included for compatibility with files written for R5RS
+ (rnrs r5rs)))
+
+(define (get-all-bindings module)
+ ;; Need to recurse to find all public bindings. module-map
+ ;; only considers the module's own bindings.
+ (let* ((own (module-map cons module))
+ (uses (module-uses module)))
+ (append own (append-map get-all-bindings uses))))
+
+(define all-bindings
+ (append-map
+ ;; Need to use module-public-interface to restrict to
+ ;; public bindings. Note that module-uses already
+ ;; returns public interfaces.
+ (lambda (mod-path)
+ (let* ((mod-object (resolve-module mod-path))
+ (iface (module-public-interface mod-object)))
+ (get-all-bindings iface)))
+ relevant-modules))
+
+(define (filter-for pred)
+ (filter-map
+ (match-lambda
+ ((key . variable)
+ (and (variable-bound? variable)
+ (let ((value (variable-ref variable)))
+ (and (pred value)
+ key)))))
+ all-bindings))
+
+(define (sort-and-uniq lst pred)
+ (let loop ((lst (sort lst pred))
+ (acc '()))
+ (match lst
+ (() (reverse! acc))
+ ((one . rest)
+ (loop (drop-while (lambda (elt)
+ (equal? elt one))
+ rest)
+ (cons one acc))))))
+
+(define (dump-py-list lst)
+ (string-join
+ (map
+ (lambda (name)
+ (format #f " \"~a\"," name))
+ (sort-and-uniq
+ (map symbol->string lst)
+ string<?))
+ "\n"))
+
+(define (dump-builtins name pred extra)
+ (format port
+ "~a = {\n~a\n}\n\n"
+ name
+ (dump-py-list (append extra (filter-for pred)))))
+
+(define extra-procedures
+ ;; These are found in RnRS but not implemented by Guile.
+ '(load transcript-off transcript-on))
+
+(dump-builtins 'scheme_keywords macro? '())
+(dump-builtins 'scheme_builtins procedure? extra-procedures)