diff options
author | Karl Berry <karl@freefriends.org> | 2020-05-04 21:19:49 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-05-04 21:19:49 +0000 |
commit | 576edc303564df0402350ff7a4c81fe179ac7929 (patch) | |
tree | 984060d46bbf5da3ba47f7b2d970bab18f6f17ad /Master/texmf-dist/tex/latex/metanorma | |
parent | 0258bc8612e27c4ad2f1f1bdba6f31cd54eb96ce (diff) |
metanorma (4may20)
git-svn-id: svn://tug.org/texlive/trunk@55010 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/metanorma')
-rw-r--r-- | Master/texmf-dist/tex/latex/metanorma/metanorma.cls | 132 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/metanorma/metanorma.cls.ltxml | 149 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/metanorma/metanorma.xsl | 693 |
3 files changed, 974 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/metanorma/metanorma.cls b/Master/texmf-dist/tex/latex/metanorma/metanorma.cls new file mode 100644 index 00000000000..894f9a860dc --- /dev/null +++ b/Master/texmf-dist/tex/latex/metanorma/metanorma.cls @@ -0,0 +1,132 @@ +% +% tex2mn 0.5.0 - converts Metanorma documents from LaTeX to AsciiDoc +% +% Copyright (C) 2019-2020 Ribose Inc. <open.source@ribose.com> +% This project is available under the terms of the MIT License. +% + +\NeedsTeXFormat{LaTeX2e} +\ProvidesClass{metanorma} + [2019/07/07 Metanorma] + +\LoadClass{article} + +\RequirePackage{graphicx} +\RequirePackage{hyperref} +% TODO: what's the best baseline AMS setup? +\RequirePackage{amsmath} +\RequirePackage{subcaption} +\RequirePackage{enumitem} + +\RequirePackage{verbatim} + +\RequirePackage{xparse} + +%% RDF %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \RequirePackage{lxRDFa} +% Let's not introduce another (mostly trivial) dependency, and just embed it: +\DeclareRobustCommand{\lxRDFa}[2][]{} +\DeclareRobustCommand{\lxRDF}[2][]{} + +\NewDocumentCommand{\mn}{m} + {\lxRDF[#1]{property=mn:attributes}} + +%% Document attributes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\makeatletter + +\NewDocumentCommand{\set}{mm}{% + \lxRDF{property=#1,content=#2}% + \expandafter\def\csname metadata@#1\endcsname{#2}} + +\@onlypreamble\set + +\NewDocumentCommand{\get}{m} + {\csname metadata@#1\endcsname} + +\makeatother + +\NewDocumentCommand{\att}{om}{#2} + +%% General style %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% No indentation on paragraphs. +\setlength\parindent{0pt} + +%% Strikethrough %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% `normalem` avoids changes to the behaviour of emphasis. +\RequirePackage[normalem]{ulem} + +% We decouple the class' API from the package choice. +\let\textst\sout + +%% Blocks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\RequirePackage[framemethod=TikZ]{mdframed} + +\mdfdefinestyle{mnbase}{ + frametitlerule=true, + frametitlefont=\sffamily\bfseries\scshape\small, + linecolor=gray, +} + +% Admonitions + +\mdfdefinestyle{note}{linecolor=blue,frametitle=Note} +\mdfdefinestyle{tip}{linecolor=green,frametitle=Tip} +\mdfdefinestyle{important}{linecolor=yellow,frametitle=Important} +\mdfdefinestyle{caution}{linecolor=red,frametitle=Caution} +\mdfdefinestyle{warning}{linecolor=orange,frametitle=Warning} + +\newmdenv[style=mnbase,style=note]{note} +\newmdenv[style=mnbase,style=tip]{tip} +\newmdenv[style=mnbase,style=important]{important} +\newmdenv[style=mnbase,style=caution]{caution} +\newmdenv[style=mnbase,style=warning]{warning} + +% Requirement, recommendation and permission + +\mdfdefinestyle{requirement}{linecolor=gray,frametitle=Requirement} +\mdfdefinestyle{recommendation}{linecolor=gray,frametitle=Recommendation} +\mdfdefinestyle{permission}{linecolor=gray,frametitle=Permission} + +\newmdenv[style=mnbase,style=requirement]{requirement} +\newmdenv[style=mnbase,style=recommendation]{recommendation} +\newmdenv[style=mnbase,style=permission]{permission} + +% Specification, measurement target, verification and import + +\mdfdefinestyle{specification}{linecolor=lightgray,frametitle=Specification} +\mdfdefinestyle{measurement-target}{linecolor=lightgray,frametitle=Measurement target} +\mdfdefinestyle{verification}{linecolor=lightgray,frametitle=Verification} +\mdfdefinestyle{import}{linecolor=lightgray,frametitle=Import} + +\newmdenv[style=mnbase,style=specification]{specification} +\newmdenv[style=mnbase,style=measurement-target]{measurement-target} +\newmdenv[style=mnbase,style=verification]{verification} +\newmdenv[style=mnbase,style=import]{import} + +%% Terms and definitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\NewDocumentCommand{\alt}{m}{{\large #1}\par} +\NewDocumentCommand{\deprecated}{m}{\textbf{DEPRECATED:} #1\par} +\NewDocumentCommand{\domain}{m}{\textbf{DOMAIN:} #1\par} + +\mdfdefinestyle{example}{linecolor=lightgray,frametitle=Example} +\mdfdefinestyle{source}{linecolor=lightgray,frametitle=Source} + +\newmdenv[style=mnbase,style=example]{example} +\newmdenv[style=mnbase,style=source]{source} + +%% Citation macros %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% TODO: handle localities formatting +\NewDocumentCommand{\mncite}{omo}{\cite[#1]{#2}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\newlist{key}{description}{1} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/Master/texmf-dist/tex/latex/metanorma/metanorma.cls.ltxml b/Master/texmf-dist/tex/latex/metanorma/metanorma.cls.ltxml new file mode 100644 index 00000000000..eb17757cb5a --- /dev/null +++ b/Master/texmf-dist/tex/latex/metanorma/metanorma.cls.ltxml @@ -0,0 +1,149 @@ +# +# tex2mn 0.5.0 - converts Metanorma documents from LaTeX to AsciiDoc +# +# Copyright (C) 2019-2020 Ribose Inc. <open.source@ribose.com> +# This project is available under the terms of the MIT License. +# + +package LaTeXML::Package::Pool; + +use LaTeXML::Package; +use strict; +use warnings; + +LoadClass('article'); + +RequirePackage('lxRDFa'); +RequirePackage('graphicx'); +RequirePackage('hyperref'); +RequirePackage('amsmath'); +RequirePackage('subcaption'); + +RequirePackage('verbatim'); + +# NOTE: switching to ASCII encoding (inside the enveloping group) preserves quotes. +# Otherwise, they would be mapped to curly ones by Tex.pool.ltxml fontmaps and ligatures. +DefMacro('\mn Semiverbatim', + '{\fontencoding{ASCII}\lxRDF[#1]{property=mn:attributes}}'); + +# NOTE: let's avoid \mna until possible + +# NOTE: this fixes and specializes \lxRDFa +# \mna{xpath}{keywordpairs} +# Add RDF attributes to nodes specified by the xpath expression. +# DefConstructor('\mna Semiverbatim RequiredKeyVals:RDFa', sub { +# my ($document, $xpath, $kv) = @_; +# my ($save, @nodes); +# $xpath = ToString($xpath); +# $save = $document->getNode; +# @nodes = $document->findnodes($xpath, $save); +# Warn('expected', 'node', $document, +# "Expected to find a node for RDFa attributes at the xpath: " . $xpath) unless scalar(@nodes); +# my $attr = RDFAttributes($kv); +# foreach my $node (@nodes) { +# foreach my $k (sort keys %$attr) { +# # use direct method ($doc method doesn't skips about="", which we need!) +# $node->setAttribute($k => ToString($$attr{$k})); }} +# $document->setNode($save); }); + +## Document attributes ######################################################### + +DefMacro('\set Semiverbatim {}', + '{\fontencoding{ASCII}\lxRDF{property=#1,content=#2}}'); + +DefConstructor('\get Semiverbatim', + "<ltx:text content='#1'/>"); + +DefConstructor('\att OptionalUndigested {}', + "<ltx:text class='with-mn-attributes'><ltx:rdf about=\".\" property=\"mn:attributes\">#1</ltx:rdf>#2</ltx:text>"); + +## Strikethrough ############################################################### + +DefConstructor('\textst{}', + "<ltx:text class='strikethrough'>#1</ltx:text>"); + +## Blocks ###################################################################### + +# NOTE: this is modeled after quote's treatment in LaTeX.pool.ltxml +# NOTE: source are meant to be a single paragraph +DefEnvironment("{source}", + "<ltx:para class=\"source\">#body</ltx:para>", + # NOTE: this beforeDigest gives us a single <p> inside <para> broken by <break>, + # instead of multiple <p> splitted on multiple <para>s (with no classes after the first one). + beforeDigest => sub { Let('\\\\', '\@block@cr'); Let('\par', '\@block@cr') }, + mode => 'text'); + +sub define_block { + my ($environment, $class) = @_; + DefEnvironment( + "{$environment}", + sub { + my ($document, %props) = @_; + $_[0]->maybeCloseElement('ltx:p'); # this starts a new vertical block + insertBlock( + $document, + $props{body}, + class => $class, + ); + }, + beforeDigest => sub { + Let('\par', '\inner@par'); + # Let('\\\\', '\inner@par'); + }, + # mode => 'text' + ); +} + +sub define_blocks { + my ($block, @modifiers) = @_; + foreach my $modifier (@modifiers) { + define_block("{$modifier}", "$block--$modifier"); + } +} + +define_block('quote', 'block-quote'); +define_block('example', 'block-example'); +define_block('reviewernote', 'block-sidebar'); +define_block('todo', 'block-admonition--todo'); +define_blocks('block-example', qw(requirement recommendation permission)); +define_blocks('block-open', qw(specification measurement-target verification import)); +define_blocks('block-admonition', qw(note tip important caution warning)); + +## Terms and Definitions ####################################################### + +DefMacro('\alt{}', '\lxRDF[#1]{property=alt}'); +DefMacro('\deprecated{}', '\lxRDF[#1]{property=deprecated}'); +DefMacro('\domain{}', '\lxRDF[#1]{property=domain}'); + +## Citation macros ############################################################# + +# NOTE: this is intended as a smarter version of +# DefMacro('\mncite[]{}[]','\cite[#1]{#2}\mn{#3,#1}'); +DefMacro('\mncite[]{}[]', sub { + my (@mn_attributes, @tokens); + push(@mn_attributes, ToString($_[3])) if $_[3]; + push(@mn_attributes, ToString($_[1])) if $_[1]; + push(@tokens, Invocation(T_CS('\cite'), $_[1], $_[2])); + # NOTE: we should be putting the ltx:rdf *inside* the ltx:cite + push(@tokens, Invocation(T_CS('\mn'), join(',', @mn_attributes))) if scalar(@mn_attributes); + return @tokens; +}); + +## Figures keys ################################################################ + +# NOTE: this is straight from LaTeXML/lib/LaTeXML/Package/enumitem.sty.ltxml +DefEnvironment('{key} OptionalUndigested', + "<ltx:description xml:id='#id'>#body</ltx:description>", + beforeDigest => sub { Let('\makelabel', '\descriptionlabel'); }, + properties => sub { beginItemize('description', '@desc'); }, + beforeDigestEnd => sub { Digest('\par'); }, + locked => 1, mode => 'text'); + +## LaTeX.pool.ltxml overrides ################################################## + +# NOTE: the original is '\normalfont\bfseries #1' but that's annoying since +# we want to just do <xsl:apply-templates select="ltx:tags/ltx:tag[not(@role)]"/> +# to match description list labels and that would get us an undesired bold. +DefMacro('\descriptionlabel{}', '\normalfont #1'); + +1; diff --git a/Master/texmf-dist/tex/latex/metanorma/metanorma.xsl b/Master/texmf-dist/tex/latex/metanorma/metanorma.xsl new file mode 100644 index 00000000000..7814c49e327 --- /dev/null +++ b/Master/texmf-dist/tex/latex/metanorma/metanorma.xsl @@ -0,0 +1,693 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + tex2mn 0.5.0 - converts Metanorma documents from LaTeX to AsciiDoc + + Copyright (C) 2019-2020 Ribose Inc. <open.source@ribose.com> + This project is available under the terms of the MIT License. +--> + +<xsl:stylesheet + version = "1.0" + xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" + xmlns:ltx = "http://dlmf.nist.gov/LaTeXML" + xmlns:str = "http://exslt.org/strings" + extension-element-prefixes = "str" + exclude-result-prefixes = "ltx str"> + + <xsl:output method="text" omit-xml-declaration="yes" indent="no"/> + + <xsl:strip-space elements="*" /> + + <!-- NOTE: these are tags which are either matched explicitly or ignored --> + <xsl:template match="ltx:tags|ltx:title|ltx:toctitle|ltx:rdf"/> + + <!-- <xsl:template match="@*|node()"> + <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy> + </xsl:template> --> + + <!-- NOTE: it's apparently forbidden (by latexmlpost) to use a variable in a predicate --> + <xsl:template match="ltx:section[translate(ltx:title/text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='foreword' or ltx:rdf[@property='mn:attributes']/text()='heading=foreword']"> + <xsl:text>[[Foreword]]
</xsl:text> + <xsl:value-of select="concat('.', ltx:title/text(), '
')"/> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template name="term-extras"> + <xsl:for-each select="tokenize(@alternate, ',')"> + <xsl:value-of select="concat('alternate:[', ., ']')"/> + <xsl:call-template name="newline"/> + </xsl:for-each> + <xsl:for-each select="tokenize(@deprecated, ',')"> + <xsl:value-of select="concat('deprecated:[', ., ']')"/> + <xsl:call-template name="newline"/> + </xsl:for-each> + <xsl:if test="@domain"> + <xsl:value-of select="concat('domain:[', @domain, ']')"/> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template name="newline"> + <xsl:text>
</xsl:text> + </xsl:template> + + <!-- + Document root + --> + + <xsl:template match="/"> + <xsl:call-template name="document-title"/> + <xsl:call-template name="document-attributes"/> + <xsl:apply-templates/> + </xsl:template> + + <!-- + Document title + --> + + <xsl:template name="document-title"> + <xsl:if test="ltx:document/ltx:title"> + <xsl:value-of select="concat('= ', ltx:document/ltx:title, '
')"/> + </xsl:if> + </xsl:template> + + <!-- + Document attributes + --> + + <xsl:template name="document-attributes"> + <xsl:for-each select="ltx:document/ltx:rdf"> + <xsl:if test="@content"> + <xsl:value-of select="concat(':', @property, ': ', @content, '
')"/> + </xsl:if> + <xsl:if test="not(@content)"> + <xsl:value-of select="concat(':', @property, ':
')"/> + </xsl:if> + </xsl:for-each> + <xsl:if test="ltx:document/ltx:rdf"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template match="ltx:text[@content]"> + <xsl:value-of select="concat('{', @content, '}')"/> + </xsl:template> + + <xsl:template match="ltx:text[@class='with-mn-attributes']"> + <xsl:value-of select="concat('[', ltx:rdf[@property='mn:attributes']/text(), ']#')"/> + <xsl:apply-templates/> + <xsl:text>#</xsl:text> + </xsl:template> + + <!-- + Sectioning + --> + + <xsl:template name="heading"> + <xsl:param name="depth"/> + <xsl:param name="extra"/> + <!-- optional label --> + <xsl:if test="@labels"> + <!-- NOTE: latexml lists and prefixes labels as "LABEL:lab1 LABEL:lab2" so we take the first one and drop the prefix --> + <xsl:value-of select="concat('[[', substring-after(substring-before(concat(@labels, ' '), ' '), ':'), ']]
')"/> + </xsl:if> + <!-- optional attributes tag --> + <xsl:choose> + <xsl:when test="ltx:rdf[@property='mn:attributes'] and $extra"> + <xsl:value-of select="concat('[', $extra, ',', ltx:rdf[@property='mn:attributes']/text(), ']')"/> + <xsl:call-template name="newline"/> + </xsl:when> + <xsl:when test="ltx:rdf[@property='mn:attributes'] or $extra"> + <xsl:value-of select="concat('[', $extra, ltx:rdf[@property='mn:attributes']/text(), ']')"/> + <xsl:call-template name="newline"/> + </xsl:when> + </xsl:choose> + <!-- heading command --> + <xsl:choose> + <xsl:when test="ltx:title/text()!=''"> + <xsl:value-of select="concat($depth, ' ', ltx:title/text())"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="concat($depth, ' ', '{blank}')"/> + </xsl:otherwise> + </xsl:choose> + <xsl:call-template name="newline"/> + <!-- blank line --> + <xsl:call-template name="newline"/> + <!-- contents --> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="ltx:appendix"> + <xsl:call-template name="heading"> + <xsl:with-param name="depth" select="'=='" /> + <xsl:with-param name="extra" select="'appendix'" /> + </xsl:call-template> + </xsl:template> + + <xsl:template match="ltx:section"> + <xsl:call-template name="heading"> + <xsl:with-param name="depth" select="'=='" /> + </xsl:call-template> + </xsl:template> + + <xsl:template match="ltx:subsection"> + <xsl:call-template name="heading"> + <xsl:with-param name="depth" select="'==='" /> + </xsl:call-template> + </xsl:template> + + <xsl:template match="ltx:subsubsection"> + <xsl:call-template name="heading"> + <xsl:with-param name="depth" select="'===='" /> + </xsl:call-template> + </xsl:template> + + <xsl:template match="ltx:paragraph"> + <xsl:call-template name="heading"> + <xsl:with-param name="depth" select="'====='" /> + </xsl:call-template> + </xsl:template> + + <xsl:template match="ltx:subparagraph"> + <xsl:call-template name="heading"> + <xsl:with-param name="depth" select="'======'" /> + </xsl:call-template> + </xsl:template> + + <!-- + Text formatting + --> + + <xsl:template match="ltx:text[@font='bold']">**<xsl:apply-templates/>**</xsl:template> + <xsl:template match="ltx:text[@font='italic']">__<xsl:apply-templates/>__</xsl:template> + <xsl:template match="ltx:text[@font='typewriter']">``<xsl:apply-templates/>``</xsl:template> + <xsl:template match="ltx:text[@font='smallcaps']">[smallcap]#<xsl:apply-templates/>#</xsl:template> + <xsl:template match="ltx:text[@class='strikethrough']">[strike]#<xsl:apply-templates/>#</xsl:template> + <xsl:template match="ltx:sup">^<xsl:apply-templates/>^</xsl:template> + <xsl:template match="ltx:sub">~<xsl:apply-templates/>~</xsl:template> + + <!-- + Paragraphs and their alignment + --> + + <xsl:template name="paragraph-alignment"> + <xsl:if test="../@align"> <!-- NOTE: parent is expected to be ltx:para --> + <xsl:value-of select="concat('[align=', ../@align, ']')"/> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template match="ltx:para"> + <xsl:apply-templates/> + <xsl:call-template name="newline"/> + </xsl:template> + + <xsl:template match="ltx:p"> + <xsl:call-template name="paragraph-alignment"/> + <xsl:apply-templates/> + <xsl:call-template name="newline"/> <!-- this is the trailing newline of the last line --> + <xsl:if test="current()[following-sibling::*]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <!-- + Quotes + --> + + <xsl:template name="quote-attributes"> + <xsl:text>[quote</xsl:text> + <xsl:if test="ltx:rdf[@property='mn:attributes']"> + <xsl:value-of select="concat(',', ltx:rdf[@property='mn:attributes']/text())"/> + </xsl:if> + <xsl:text>]
</xsl:text> + </xsl:template> + + <xsl:template name="quote-delimiter"> + <xsl:text>_____
</xsl:text> + </xsl:template> + + <!-- <xsl:template match="ltx:quote"> --> + <xsl:template match="ltx:*[@class='block-quote']" priority="1"> + <xsl:call-template name="quote-attributes"/> + <xsl:call-template name="quote-delimiter"/> + <xsl:apply-templates/><xsl:if test="name()='p'"><xsl:text>
</xsl:text></xsl:if> + <xsl:call-template name="quote-delimiter"/> + <!-- TODO: should a blank line be here? --> + </xsl:template> + + <!-- + Admonitions + --> + + <xsl:template name="block-admonition__attributes"> + <xsl:value-of select="concat('[', translate(substring(@class, 19), $lowercase, $uppercase))"/> + <xsl:if test="ltx:rdf[@property='mn:attributes']"> + <xsl:value-of select="concat(',', ltx:rdf[@property='mn:attributes']/text())"/> + </xsl:if> + <xsl:text>]
</xsl:text> + </xsl:template> + + <xsl:template name="block-admonition__delimiter"> + <xsl:text>====
</xsl:text> + </xsl:template> + + <xsl:template match="//ltx:*[starts-with(@class, 'block-admonition--')]"> + <xsl:call-template name="block-admonition__attributes"/> + <xsl:call-template name="block-admonition__delimiter"/> + <xsl:apply-templates/><xsl:if test="name()='p'"><xsl:text>
</xsl:text></xsl:if> + <xsl:call-template name="block-admonition__delimiter"/> + </xsl:template> + + <!-- + Footnotes + --> + + <xsl:template match="ltx:note"> + <xsl:value-of select="concat(' footnote:[', text(), ']')"/> + </xsl:template> + + <!-- + Hard line breaks (in paragraphs) + --> + + <xsl:template match="ltx:p/ltx:break"> + <xsl:text> +
</xsl:text> + </xsl:template> + + <!-- + Lists (arbitrarily nested, w/ line breaks and paragraphs) + --> + + <xsl:template name="list__continuation_marker"> + <xsl:text>+
</xsl:text> + </xsl:template> + + <xsl:template name="list__item_label_marker"> + <xsl:if test="../@labels"> + <!-- NOTE: latexml lists and prefixes labels as "LABEL:lab1 LABEL:lab2" so we take the first one and drop the prefix --> + <xsl:value-of select="concat('[[', substring-after(substring-before(concat(../@labels, ' '), ' '), ':'), ']] ')"/> + </xsl:if> + </xsl:template> + + <xsl:template match="ltx:item/ltx:para/ltx:p"> + <xsl:apply-templates/> + <xsl:call-template name="newline"/> <!-- this is the trailing newline of the last line --> + </xsl:template> + + <!-- Unordered lists --> + + <xsl:template name="list--unordered__item_depth_marker"> + <xsl:for-each select="ancestor-or-self::ltx:itemize">*</xsl:for-each> + <xsl:text> </xsl:text> + </xsl:template> + + <xsl:template match="ltx:itemize/ltx:item/ltx:para[not(preceding-sibling::ltx:para)]"> + <xsl:call-template name="list--unordered__item_depth_marker"/> + <xsl:call-template name="list__item_label_marker"/> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="ltx:itemize/ltx:item/ltx:para[preceding-sibling::ltx:para]"> + <xsl:call-template name="list__continuation_marker"/> + <xsl:call-template name="list__item_label_marker"/> + <xsl:apply-templates/> + </xsl:template> + + <!-- Ordered lists --> + + <xsl:template name="list--ordered__item_depth_marker"> + <xsl:for-each select="ancestor-or-self::ltx:enumerate">.</xsl:for-each> + <xsl:text> </xsl:text> + </xsl:template> + + <xsl:template match="ltx:enumerate/ltx:item/ltx:para[not(preceding-sibling::ltx:para)]"> + <xsl:call-template name="list--ordered__item_depth_marker"/> + <xsl:call-template name="list__item_label_marker"/> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="ltx:enumerate/ltx:item/ltx:para[preceding-sibling::ltx:para]"> + <xsl:call-template name="list__continuation_marker"/> + <xsl:call-template name="list__item_label_marker"/> + <xsl:apply-templates/> + </xsl:template> + + <!-- Description lists --> + + <xsl:template match="ltx:description"> + <xsl:for-each select="ltx:item"> + <xsl:apply-templates select="ltx:tags/ltx:tag[not(@role)]"/> + <xsl:text>:</xsl:text> + <xsl:for-each select="ancestor-or-self::ltx:description">:</xsl:for-each> + <xsl:text>
</xsl:text> + <xsl:apply-templates/> + </xsl:for-each> + </xsl:template> + + <xsl:template match="ltx:description/ltx:item/ltx:para[not(preceding-sibling::ltx:para)]"> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="ltx:description/ltx:item/ltx:para[preceding-sibling::ltx:para]"> + <xsl:call-template name="list__continuation_marker"/> + <xsl:apply-templates/> + </xsl:template> + + <!-- + Figures + --> + + <xsl:template name="figure__label"> + <xsl:if test="@labels"> + <!-- NOTE: latexml lists and prefixes labels as "LABEL:lab1 LABEL:lab2" so we take the first one and drop the prefix --> + <xsl:value-of select="concat('[[', substring-after(substring-before(concat(@labels, ' '), ' '), ':'), ']]
')"/> + </xsl:if> + <xsl:if test="not(@labels)"> + <!-- TODO: drop this unless it's required by asciidoc --> + <xsl:value-of select="concat('[[', @xml:id, ']]
')"/> + </xsl:if> + </xsl:template> + + <!-- NOTE: this matches only parent of composite figures --> + <xsl:template match="ltx:figure[./ltx:figure]"> + <xsl:call-template name="figure__label"/> + <xsl:apply-templates select="ltx:caption"/> + <xsl:call-template name="figure__attributes"/> + <xsl:text>====
</xsl:text> + <xsl:apply-templates select="ltx:figure"/> + <xsl:text>====
</xsl:text> + <xsl:call-template name="newline"/> + <xsl:apply-templates select="ltx:paragraph"/> + </xsl:template> + + <!-- NOTE: this matches either simple figures or children of composite figures --> + <xsl:template match="ltx:figure[not(./ltx:figure)]"> + <xsl:call-template name="figure__label"/> + <xsl:apply-templates select="ltx:caption"/> + <xsl:call-template name="figure__attributes"/> + <xsl:apply-templates select="ltx:graphics"/> + <xsl:apply-templates select="ltx:verbatim"/> <!-- NOTE: this is temporary --> + <xsl:call-template name="newline"/> + <xsl:if test="./ltx:description"> + <xsl:text>*Key*
</xsl:text> + <xsl:call-template name="newline"/> + <xsl:apply-templates select="./ltx:description"/> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template match="ltx:figure/ltx:graphics"> + <!-- TODO: we could use the caption as alt text, perhaps? --> + <xsl:value-of select="concat('image::', @graphic, '[]
')"/> + </xsl:template> + + <xsl:template name="figure__attributes"> + <xsl:if test="ltx:rdf[@property='mn:attributes']"> + <xsl:value-of select="concat('[', ltx:rdf[@property='mn:attributes']/text(), ']
')"/> + </xsl:if> + </xsl:template> + + <xsl:template match="ltx:figure/ltx:caption/ltx:tag"/> + <!-- NOTE: is it correct to assume there's only one ltx:tex inside the caption? --> + <xsl:template match="ltx:figure/ltx:caption/ltx:text"> + <xsl:value-of select="concat('.', text(), '
')"/> + </xsl:template> + + <!-- + Math + --> + + <xsl:template match="ltx:equation"> + <xsl:if test="@labels"> + <!-- NOTE: latexml lists and prefixes labels as "LABEL:lab1 LABEL:lab2" so we take the first one and drop the prefix --> + <xsl:value-of select="concat('[[', substring-after(substring-before(concat(@labels, ' '), ' '), ':'), ']]
')"/> + </xsl:if> + <!-- TODO: should distinction between environments be stricter? --> + <!-- equation, gather --> + <xsl:apply-templates select="ltx:Math"/> + <!-- align --> + <xsl:apply-templates select="ltx:MathFork/ltx:Math"/> + <xsl:call-template name="newline"/> + </xsl:template> + + <xsl:template match="ltx:Math[@mode='inline']"> + <xsl:value-of select="concat('stem:[', @tex, ']')"/> + </xsl:template> + + <xsl:template match="ltx:Math[not(@mode) or @mode='display']"> + <xsl:text>[stem]
</xsl:text> + <xsl:text>++++
</xsl:text> + <xsl:value-of select="@tex"/> + <xsl:text>
++++
</xsl:text> + </xsl:template> + + <!-- + Tables + --> + + <xsl:template match="ltx:table"> + <xsl:if test="@labels"> + <!-- NOTE: latexml lists and prefixes labels as "LABEL:lab1 LABEL:lab2" so we take the first one and drop the prefix --> + <xsl:value-of select="concat('[[', substring-after(substring-before(concat(@labels, ' '), ' '), ':'), ']]
')"/> + </xsl:if> + <xsl:apply-templates select="ltx:caption"/> + <xsl:apply-templates select="ltx:tabular"/> + <xsl:call-template name="newline"/> + </xsl:template> + + <xsl:template match="ltx:table/ltx:caption/ltx:tag"/> + <!-- NOTE: is it correct to assume there's only one ltx:tex inside the caption? --> + <xsl:template match="ltx:table/ltx:caption/ltx:text"> + <xsl:value-of select="concat('.', text(), '
')"/> + </xsl:template> + + <xsl:template match="ltx:tabular"> + <xsl:value-of select="concat('[cols=', count(ltx:tbody/ltx:tr[1]/ltx:td), '*]
')"/> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match="ltx:tbody"> + <xsl:text>|===
</xsl:text> + <xsl:apply-templates/> + <xsl:text>|===
</xsl:text> + </xsl:template> + + <xsl:template match="ltx:tr"> + <xsl:apply-templates/> + <xsl:if test="current()[following-sibling::*]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template match="ltx:td"> + <xsl:text>| </xsl:text> + <xsl:apply-templates/> + <xsl:text>
</xsl:text> + </xsl:template> + + <!-- + Links + --> + + <xsl:template match="ltx:ref[@href]"> + <!-- NOTE: to handle *anything* a user might throw at us, we use the explicit link macro --> + <xsl:choose> + <xsl:when test="@href!=node()"> + <xsl:value-of select="concat('link:++', @href, '++', '[', node(), ']')"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="concat('link:++', @href, '++', '[]')"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- + Cross references + --> + + <xsl:template match="ltx:ref[@labelref]"> + <xsl:choose> + <!-- NOTE: by default (disabled with nocrossref) latexmk would add a child text node containing @labelref so we couldn't choose here --> + <xsl:when test="node()"> + <xsl:value-of select="concat('<<', substring-after(@labelref, ':'), ', ', text(), '>>')"/> + </xsl:when> + <xsl:otherwise> + <xsl:value-of select="concat('<<', substring-after(@labelref, ':'), '>>')"/> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <!-- + Reviewer notes + --> + + <xsl:template match="ltx:*[@class='block-sidebar']" priority="1"> + <xsl:call-template name="block-sidebar__attributes"/> + <xsl:call-template name="block-sidebar__delimiter"/> + <xsl:apply-templates/> + <xsl:call-template name="block-sidebar__delimiter"/> + <xsl:if test="current()[following-sibling::*]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template name="block-sidebar__attributes"> + <xsl:if test="ltx:rdf[@property='mn:attributes']"> + <xsl:value-of select="concat('[', ltx:rdf[@property='mn:attributes']/text(), ']
')"/> + </xsl:if> + </xsl:template> + + <xsl:template name="block-sidebar__delimiter"> + <!-- TODO: should we handle block nesting? --> + <xsl:text>****
</xsl:text> + </xsl:template> + + <!-- + Blocks + --> + + <!-- NOTE: we expect to match only p, block and inline-block but use priority to simplify the XSL --> + <xsl:template match="ltx:*[starts-with(@class, 'block-example--')]" priority="1"> + <xsl:value-of select="concat('[.', substring-after(@class, 'block-example--'), ']
')"/> + <xsl:call-template name="block--example__delimiter"/> + <!-- NOTE: if we matched a p we need an extra line termination --> + <xsl:apply-templates/><xsl:if test="name()='p'"><xsl:text>
</xsl:text></xsl:if> + <xsl:call-template name="block--example__delimiter"/> + <xsl:if test="current()[following-sibling::*]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template name="block--example__delimiter"> + <!-- NOTE: we add a = for each nesting level --> + <xsl:for-each select="ancestor::ltx:*[starts-with(@class, 'block-example--')]">=</xsl:for-each> + <xsl:text>====
</xsl:text> + </xsl:template> + + <!-- NOTE: we expect to match only p, block and inline-block but use priority to simplify the XSL --> + <xsl:template match="ltx:*[starts-with(@class, 'block-open--')]" priority="1"> + <xsl:value-of select="concat('[.', substring-after(@class, 'block-open--'), ']
')"/> + <xsl:call-template name="block--open__delimiter"/> + <xsl:apply-templates/> + <xsl:text>
</xsl:text> + <xsl:call-template name="block--open__delimiter"/> + <xsl:if test="current()[following-sibling::*]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template name="block--open__delimiter"> + <xsl:text>--
</xsl:text> + </xsl:template> + + <!-- + Verbatim + --> + + <!-- NOTE: this is temporary, undocumented and we'll end up using lstlistings in the final version --> + + <xsl:template match="ltx:verbatim"> + <xsl:text>....</xsl:text> + <xsl:apply-templates/> + <xsl:text>....
</xsl:text> + <xsl:if test="current()[following-sibling::*]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <!-- + Terms and Definitions + --> + + <xsl:template match="ltx:*[@class='block-example']" priority="1"> + <xsl:text>[example]
</xsl:text> + <xsl:call-template name="block--example__delimiter"/> + <!-- NOTE: if we matched a p we need an extra line termination --> + <xsl:apply-templates/><xsl:if test="name()='p'"><xsl:text>
</xsl:text></xsl:if> + <xsl:call-template name="block--example__delimiter"/> + <xsl:if test="current()[following-sibling::*]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <xsl:template match="ltx:para[@class='source']"> + <xsl:text>[.source]
</xsl:text> + <xsl:apply-templates/> + <xsl:call-template name="newline"/> + </xsl:template> + + <xsl:template match="ltx:rdf[@property='alt' or @property='deprecated' or @property='domain']"> + <xsl:value-of select="concat(@property, ':[')"/> + <xsl:apply-templates/> + <xsl:text>]
</xsl:text> + <xsl:if test="current()[not(following-sibling::ltx:rdf)]"> + <xsl:call-template name="newline"/> + </xsl:if> + </xsl:template> + + <!-- + Citations + --> + + <xsl:template match="ltx:cite"> + <xsl:text><<</xsl:text> + <xsl:value-of select="ltx:bibref/@bibrefs"/> + <xsl:if test="./following-sibling::ltx:rdf[@property='mn:attributes']/text()"> + <xsl:value-of select="concat(',', ./following-sibling::ltx:rdf[@property='mn:attributes'])"/> + </xsl:if> + <xsl:text>>></xsl:text> + </xsl:template> + + <!-- + Bibliography + --> + + <xsl:template match="ltx:bibliography/ltx:title"> + <xsl:text>[bibliography]
</xsl:text> + <xsl:value-of select="concat('== ', ., '
')"/> + <xsl:call-template name="newline"/> + </xsl:template> + + <!-- NOTE: this matches embedded bibliographies written by the user --> + <xsl:template match="ltx:bibliography[not(@files)]/ltx:biblist"> + <xsl:for-each select="ltx:bibitem"> + <xsl:text>* </xsl:text> + <!-- NOTE: remember that position() should be equivalent to refnum if no label is given --> + <xsl:value-of select="concat('[[[', @key, ',', ./ltx:tags/ltx:tag[@role='refnum'], ']]]')"/> + <!-- NOTE: embedded bibliographic entries produce one bibblock each --> + <xsl:apply-templates match="ltx:bibblock"/> + <xsl:text>
</xsl:text> + <!-- <xsl:if test="string-length(substring(node(), 1, 1))!='
'"><xsl:text>
</xsl:text></xsl:if> --> + </xsl:for-each> + <xsl:call-template name="newline"/> + </xsl:template> + + <!-- NOTE: this matches BibTeX bibliographies generated by the MakeBibliography preprocessor --> + <xsl:template match="ltx:bibliography[@files]/ltx:biblist"> + <xsl:for-each select="ltx:bibitem"> + <xsl:text>* </xsl:text> + <!-- NOTE: remember that position() should be equivalent to refnum if no label is given --> + <xsl:value-of select="concat('[[[', @key, ',', ./ltx:tags/ltx:tag[@role='refnum'], ']]]', '
')"/> + <!-- NOTE: [not(contains(@class, 'ltx_bib_cited'))] skips the "Cited by" block which we aren't handling --> + <xsl:for-each select="ltx:bibblock[not(contains(@class, 'ltx_bib_cited'))]"> + <!-- NOTE: instead of handling whitespace through concatenation we just break the line --> + <!-- NOTE: this intercepts blocks beginning with an initial (e.g. "A. Einstein") and prepends a {blank} to avoid generating a spurious list --> + <xsl:if test="string-length(substring-before(node(), '. '))=1"><xsl:text>{blank}</xsl:text></xsl:if> + <xsl:apply-templates/> + <xsl:text>
</xsl:text> + </xsl:for-each> + <xsl:text>
</xsl:text> + </xsl:for-each> + </xsl:template> + + <!-- + Utilities + --> + + <!-- XSL 2.0 has upper-case() but we must use translate() with XSL 1.0 --> + <xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" /> + <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" /> + +</xsl:stylesheet>
\ No newline at end of file |