diff options
Diffstat (limited to 'tools')
| -rwxr-xr-x | tools/makespec.py | 165 | ||||
| -rwxr-xr-x[-rw-r--r--] | tools/mkcasefold.pl | 0 | ||||
| -rw-r--r-- | tools/template.html | 110 | ||||
| -rw-r--r-- | tools/template.tex | 229 | 
4 files changed, 504 insertions, 0 deletions
diff --git a/tools/makespec.py b/tools/makespec.py new file mode 100755 index 0000000..84663f2 --- /dev/null +++ b/tools/makespec.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 +import re +import sys +from subprocess import * +from string import Template + +if len(sys.argv) == 2: +    specformat = sys.argv[1] +    if not (specformat in ["html", "markdown"]): +        sys.stderr.write("Format must be html or markdown\n") +        exit(1) +else: +    sys.stderr.write("Usage:  makespec.py [html|markdown]\n") +    exit(1) + +def toIdentifier(s): +   return re.sub(r'\s+', '-', re.sub(r'\W+', ' ', s.strip().lower())) + +def parseYaml(yaml): +    metadata = {} +    def parseField(match): +        key = match.group(1) +        val = match.group(2).strip() +        if re.match(r'^\'', val): +            val = val[1:len(val) - 1] +        metadata[key] = val +    fieldre = re.compile('^(\w+):(.*)$', re.MULTILINE) +    re.sub(fieldre, parseField, yaml) +    return metadata + +def pipe_through_prog(prog, text): +    p1 = Popen(prog.split(), stdout=PIPE, stdin=PIPE, stderr=PIPE) +    [result, err] = p1.communicate(input=text.encode('utf-8')) +    return [p1.returncode, result.decode('utf-8'), err] + +def replaceAnchor(match): +    refs.append("[{0}]: #{1}".format(match.group(1), match.group(2))) +    if specformat == "html": +        return '<a id="{1}" href="#{1}" class="definition">{0}</a>'.format(match.group(1), match.group(2)) +    else: +        return match.group(0) + +stage = 0 +example = 0 +section = "" +sections = [] +mdlines = [] +refs = [] +lastnum = [] +finishedMeta = False +yamllines = [] + +with open('spec.txt', 'r', encoding='utf-8') as spec: +    for ln in spec: +        if not finishedMeta: +            yamllines.append(ln) +            if re.match(r'^\.\.\.$', ln): +                finishedMeta = True +        elif re.match(r'^\.$', ln): +            if stage == 0: +                example += 1 +                mdlines.append("\n<div class=\"example\" id=\"example-{0}\" data-section=\"{1}\">\n".format(example, section)) +                mdlines.append("<div class=\"examplenum\"><a href=\"#example-{0}\">Example {0}</a>  <a class=\"dingus\" title=\"open in interactive dingus\">(interact)</a></div>\n\n".format(example)) +                mdlines.append("````````````````````````````````````````````````````````` markdown\n") +                stage = 1 +            elif stage == 1: +                mdlines.append("`````````````````````````````````````````````````````````\n\n") +                mdlines.append("````````````````````````````````````````````````````````` html\n") +                stage = 2 +            elif stage == 2: +                mdlines.append("`````````````````````````````````````````````````````````\n\n") +                mdlines.append("</div>\n") +                stage = 0 +            else: +                sys.stderr.out("Encountered unknown stage {0}\n".format(stage)) +                sys.exit(1) +        else: +            if stage == 0: +                match = re.match(r'^(#{1,6}) *(.*)', ln) +                if match: +                    section = match.group(2) +                    lastlevel = len(lastnum) +                    level = len(match.group(1)) +                    if re.search(r'{-}$', section): +                        section = re.sub(r' *{-} *$', '', section) +                        if specformat == 'html': +                            ln = re.sub(r' *{-} *$', '', ln) +                        number = '' +                    else: +                        if lastlevel == level: +                            lastnum[level - 1] = lastnum[level - 1] + 1 +                        elif lastlevel < level: +                            while len(lastnum) < level: +                                lastnum.append(1) +                        else: # lastlevel > level +                            lastnum = lastnum[0:level] +                            lastnum[level - 1] = lastnum[level - 1] + 1 +                        number = '.'.join([str(x) for x in lastnum]) +                    ident = toIdentifier(section) +                    ln = re.sub(r' ', ' ' + number + ' ', ln, count=1) +                    sections.append(dict(level=level, +                                         contents=section, +                                         ident=ident, +                                         number=number)) +                    refs.append("[{0}]: #{1}".format(section, ident)) +                    ln = re.sub(r'# +', '# <a id="{0}"></a> '.format(ident), +                                ln, count=1) +                else: +                    ln = re.sub(r'\[([^]]*)\]\(@([^)]*)\)', replaceAnchor, ln) +            else: +                ln = re.sub(r' ', '␣', ln) +            mdlines.append(ln) + +mdtext = ''.join(mdlines) + '\n\n' + '\n'.join(refs) + '\n' +yaml = ''.join(yamllines) +metadata = parseYaml(yaml) + +if specformat == "markdown": +    sys.stdout.write(yaml + '\n\n' + mdtext) +elif specformat == "html": +    with open("template.html", "r", encoding="utf-8") as templatefile: +        template = Template(templatefile.read()) +    toclines = [] +    for section in sections: +        indent = '    ' * (section['level'] - 1) +        toclines.append(indent + '* [' + section['number'] + ' ' + +                        section['contents'] + '](#' + section['ident'] + ')') +    toc = '<div id="TOC">\n\n' + '\n'.join(toclines) + '\n\n</div>\n\n' +    prog = "build/src/cmark" +    [retcode, result, err] = pipe_through_prog(prog, toc + mdtext) +    if retcode == 0: +        result = re.sub(r'␣', '<span class="space"> </span>', result) +        result = re.sub(r'<h([1-6])><a id="([^\"]*)"><\/a> ', +                        "<h\\1 id=\"\\2\">", result) +        # put plural s inside links for better visuals: +        result = re.sub(r'<\/a>s', "s</a>", result) +        sys.stdout.write(template.substitute(metadata, body=result)) + +        # check for errors: +        idents = [] +        for ident in re.findall(r'id="([^"]*)"', result): +            if ident in idents: +                sys.stderr.write("WARNING: duplicate identifier '" + ident + +                                 "'\n") +            else: +                idents.append(ident) +        for href in re.findall(r'href="#([^"]*)"', result): +            if not (href in idents): +                sys.stderr.write("WARNING: internal link with no anchor '" + +                                 href + "'\n") +        reftexts = [] +        for ref in refs: +            ref = re.sub('].*',']',ref).upper() +            if ref in reftexts: +                sys.stderr.write("WARNING: duplicate reference link '" + +                                 ref + "'\n") +            else: +                reftexts.append(ref) + +    else: +        sys.stderr.write("Error converting markdown version of spec:\n") +        sys.stderr.write(err) +        exit(1) + +exit(0) diff --git a/tools/mkcasefold.pl b/tools/mkcasefold.pl index 740ce77..740ce77 100644..100755 --- a/tools/mkcasefold.pl +++ b/tools/mkcasefold.pl diff --git a/tools/template.html b/tools/template.html new file mode 100644 index 0000000..a5cc081 --- /dev/null +++ b/tools/template.html @@ -0,0 +1,110 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="UTF-8"> +<title>${title}</title> +<style type="text/css"> +  body { font-family: Helvetica, arial, freesans, clean, sans-serif; +    line-height: 1.4; +    max-width: 48em; +    margin: auto; +    color: #333333; +    background-color: #fff; +    font-size: 13pt; +  } +div#TOC ul { list-style: none; } +h1 { font-size: 140%; font-weight: bold; border-top: 1px solid gray; padding-top: 0.5em; } +h2 { font-size: 120%; font-weight: bold; } +h3 { font-size: 110%; font-weight: bold; } +h4 { font-size: 100%; font-weight: bold; } +a.definition { font-weight: bold; } +span.space { position: relative; } +span.space:after { +  content: "·"; +  position: absolute; +  /* create a mark that indicates a space (trick from D. Greenspan) */ +  top: 0px; bottom: 7px; left: 1px; right: 1px; +  color: #AAA; +} +div.example { overflow: hidden; } +p { text-align: justify; } +pre { padding: 0.5em; margin-left: 0; margin-right: 0; margin-top: 0.2em; +  margin-bottom: 0.5em; font-size: 88%; } +pre { + white-space: pre-wrap;       /* css-3 */ + white-space: -moz-pre-wrap;  /* Mozilla, since 1999 */ + white-space: -pre-wrap;      /* Opera 4-6 */ + white-space: -o-pre-wrap;    /* Opera 7 */ + word-wrap: break-word;       /* Internet Explorer 5.5+ */ +} +code { font-family: monospace; background-color: #D3E1E4; } +pre > code { background-color: transparent; } +div.example > pre { float:left; width: 48%; } +div.example > pre:nth-child(2) { clear:left; background-color: #D3E1E4; } +div.example > pre:nth-child(3) { clear:right; background-color: #C9CaCE; } +#watermark { + position:fixed; + bottom:0px; + left:0px; + padding: 1em; + width: 100%; + font-size: 120%; + opacity:0.7; + z-index:99; + color: white; +} +#watermark a { color: white; } +div.examplenum { font-size: 82%; text-align: left; } +a.dingus { color: red; cursor: pointer; } +a.footnoteRef > sup:before { +  content: "["; +} +a.footnoteRef > sup:after { +  content: "]"; +} +a.footnoteRef > sup { +  vertical-align: baseline; +  font-size: 100%; +} +</style> +<script src="//code.jquery.com/jquery-1.11.0.min.js"></script> +<script type="text/javascript"> +$$(document).ready(function() { +  $$("div.example").each(function(e) { +    var t = $$(this).find('code.markdown').text(); +    $$(this).find('a.dingus').click(function(f) { +      window.open('/dingus.html?text=' + +        encodeURIComponent(t.replace(/→/g,"\t"))); +    }); +  }); +  $$("code.markdown").dblclick(function(e) { window.open('/dingus.html?text=' + +      encodeURIComponent($$(this).find('code').text())); +  }); +}); +</script> +</head> +<body> +<h1 class="title">${title}</h1> +<div class="version">Version ${version} (${date})</div> +<div class="authors"> +    <span class="author">${author}</span> +</div> +<div class="license"> +<a rel="license" +   href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative +   Commons BY-SA" style="border-width:0" +   src="https://i.creativecommons.org/l/by-sa/4.0/80x15.png" +   /></a><br/><span style="display:none"><span xmlns:dct="http://purl.org/dc/terms/" +   href="http://purl.org/dc/dcmitype/Text" property="dct:title" +   rel="dct:type">CommonMark Spec</span> by +   <a xmlns:cc="http://creativecommons.org/ns#" +   href="http://spec.commonmark.org" property="cc:attributionName" +   rel="cc:attributionURL">John MacFarlane</a> is licensed under a +   <a rel="license" +   href="http://creativecommons.org/licenses/by-sa/4.0/">Creative +   Commons Attribution-ShareAlike 4.0 International License</a>.</span> +</div> +<div id="watermark"></div> +${body} +</body> +</html> diff --git a/tools/template.tex b/tools/template.tex new file mode 100644 index 0000000..d083b72 --- /dev/null +++ b/tools/template.tex @@ -0,0 +1,229 @@ +\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$lang$,$endif$$if(papersize)$$papersize$,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$} +$if(fontfamily)$ +\usepackage{$fontfamily$} +$else$ +\usepackage{lmodern} +$endif$ +$if(linestretch)$ +\usepackage{setspace} +\setstretch{$linestretch$} +$endif$ +\usepackage{amssymb,amsmath} +\usepackage{ifxetex,ifluatex} +\usepackage{fixltx2e} % provides \textsubscript +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex +  \usepackage[T1]{fontenc} +  \usepackage[utf8]{inputenc} +$if(euro)$ +  \usepackage{eurosym} +$endif$ +\else % if luatex or xelatex +  \ifxetex +    \usepackage{mathspec} +    \usepackage{xltxtra,xunicode} +  \else +    \usepackage{fontspec} +  \fi +  \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase} +  \newcommand{\euro}{€} +$if(mainfont)$ +    \setmainfont{$mainfont$} +$endif$ +$if(sansfont)$ +    \setsansfont{$sansfont$} +$endif$ +$if(monofont)$ +    \setmonofont[Mapping=tex-ansi]{$monofont$} +$endif$ +$if(mathfont)$ +    \setmathfont(Digits,Latin,Greek){$mathfont$} +$endif$ +\fi +% use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +% use microtype if available +\IfFileExists{microtype.sty}{\usepackage{microtype}}{} +\usepackage[margin=1in]{geometry} +$if(natbib)$ +\usepackage{natbib} +\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} +$endif$ +$if(biblatex)$ +\usepackage{biblatex} +$if(biblio-files)$ +\bibliography{$biblio-files$} +$endif$ +$endif$ +$if(listings)$ +\usepackage{listings} +$endif$ +$if(lhs)$ +\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} +$endif$ +\usepackage{fancyvrb} +\usepackage{color,framed} +\newcommand{\VerbBar}{|} +\newcommand{\VERB}{\Verb[commandchars=\\\{\}]} +\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\},fontsize=\small} +% Add ',fontsize=\small' for more characters per line +\definecolor{shadecolor}{gray}{1} +\newenvironment{Shaded}{\begin{snugshade}}{\end{snugshade}} +\newcommand{\NormalTok}[1]{{#1}} +\let\KeywordTok\NormalTok +\let\DataTypeTok\NormalTok +\let\DecValTok\NormalTok +\let\BaseNTok\NormalTok +\let\FloatTok\NormalTok +\let\CharTok\NormalTok +\let\StringTok\NormalTok +\let\CommentTok\NormalTok +\let\OtherTok\NormalTok +\let\AlertTok\NormalTok +\let\FunctionTok\NormalTok +\let\RegionMarkerTok\NormalTok +\let\ErrorTok\NormalTok +%\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} +%\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}} +%\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} +%\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} +%\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} +%\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} +%\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} +%\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}} +%\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} +%\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} +%\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}} +%\newcommand{\RegionMarkerTok}[1]{{#1}} +%\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} +$if(verbatim-in-note)$ +\usepackage{fancyvrb} +$endif$ +$if(tables)$ +\usepackage{longtable,booktabs} +$endif$ +$if(graphics)$ +\usepackage{graphicx} +\makeatletter +\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} +\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} +\makeatother +% Scale images if necessary, so that they will not overflow the page +% margins by default, and it is still possible to overwrite the defaults +% using explicit options in \includegraphics[width, height, ...]{} +\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} +$endif$ +\ifxetex +  \usepackage[setpagesize=false, % page size defined by xetex +              unicode=false, % unicode breaks when used with xetex +              xetex]{hyperref} +\else +  \usepackage[unicode=true]{hyperref} +\fi +\hypersetup{breaklinks=true, +            bookmarks=true, +            pdfauthor={$author-meta$}, +            pdftitle={$title-meta$}, +            colorlinks=true, +            citecolor=$if(citecolor)$$citecolor$$else$blue$endif$, +            urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$, +            linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$, +            pdfborder={0 0 0}} +\urlstyle{same}  % don't use monospace font for urls +$if(links-as-notes)$ +% Make links footnotes instead of hotlinks: +\renewcommand{\href}[2]{#2\footnote{\url{#1}}} +$endif$ +$if(strikeout)$ +\usepackage[normalem]{ulem} +% avoid problems with \sout in headers with hyperref: +\pdfstringdefDisableCommands{\renewcommand{\sout}{}} +$endif$ +\setlength{\parindent}{0pt} +\setlength{\parskip}{6pt plus 2pt minus 1pt} +\setlength{\emergencystretch}{3em}  % prevent overfull lines +$if(numbersections)$ +\setcounter{secnumdepth}{5} +$else$ +\setcounter{secnumdepth}{0} +$endif$ +$if(verbatim-in-note)$ +\VerbatimFootnotes % allows verbatim text in footnotes +$endif$ +$if(lang)$ +\ifxetex +  \usepackage{polyglossia} +  \setmainlanguage{$mainlang$} +\else +  \usepackage[$lang$]{babel} +\fi +$endif$ + +\usepackage{titlesec} +\titleformat{\chapter}[hang]{\Huge\bfseries}{\thechapter\ }{0pt}{\Huge\bfseries} + +\usepackage{fancyhdr} +\pagestyle{fancy} +\pagenumbering{arabic} +\lhead{\itshape $title$} +\chead{} +\rhead{\itshape{\nouppercase{\rightmark}}} +\lfoot{v$version$ ($date$)} +\cfoot{} +\rfoot{\thepage} + +$if(title)$ +\title{$title$$if(subtitle)$\\\vspace{0.5em}{\large $subtitle$}$endif$} +$endif$ +$if(author)$ +\author{$for(author)$$author$$sep$ \and $endfor$} +$endif$ +\date{$date$} +$for(header-includes)$ +$header-includes$ +$endfor$ + +\begin{document} +$if(title)$ +\maketitle +$endif$ +$if(abstract)$ +\begin{abstract} +$abstract$ +\end{abstract} +$endif$ + +$for(include-before)$ +$include-before$ + +$endfor$ +$if(toc)$ +{ +\hypersetup{linkcolor=black} +\setcounter{tocdepth}{$toc-depth$} +\tableofcontents +} +$endif$ +$body$ + +$if(natbib)$ +$if(biblio-files)$ +$if(biblio-title)$ +$if(book-class)$ +\renewcommand\bibname{$biblio-title$} +$else$ +\renewcommand\refname{$biblio-title$} +$endif$ +$endif$ +\bibliography{$biblio-files$} + +$endif$ +$endif$ +$if(biblatex)$ +\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ + +$endif$ +$for(include-after)$ +$include-after$ + +$endfor$ +\end{document}  | 
