From 75007b20b4071ad4c6f7168b98c3218739693769 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 15 Jan 2015 16:08:03 -0800 Subject: Re-added tools/{makespec.py, template.html, template.tex}. These were inadvertently dropped in the commit that described them as being moved to tools/. --- tools/makespec.py | 165 +++++++++++++++++++++++++++++++++++++ tools/mkcasefold.pl | 0 tools/template.html | 110 +++++++++++++++++++++++++ tools/template.tex | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 504 insertions(+) create mode 100755 tools/makespec.py mode change 100644 => 100755 tools/mkcasefold.pl create mode 100644 tools/template.html create mode 100644 tools/template.tex (limited to 'tools') 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 '{0}'.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
\n".format(example, section)) + mdlines.append("\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("
\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'# +', '# '.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 = '
\n\n' + '\n'.join(toclines) + '\n\n
\n\n' + prog = "build/src/cmark" + [retcode, result, err] = pipe_through_prog(prog, toc + mdtext) + if retcode == 0: + result = re.sub(r'␣', ' ', result) + result = re.sub(r'<\/a> ', + "", result) + # put plural s inside links for better visuals: + result = re.sub(r'<\/a>s', "s", 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 old mode 100644 new mode 100755 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 @@ + + + + +${title} + + + + + +

${title}

+
Version ${version} (${date})
+
+ ${author} +
+ +
+${body} + + 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} -- cgit v1.2.3