Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git

Add basic styling to PDF output; drop HTTP HEAD request for GET

Author DaveJarvis <email>
Date 2021-04-03 20:43:23 GMT-0700
Commit c95d901024ab90063ee3d595a2564df01efe6dec
Parent 25d2998
src/main/java/com/keenwrite/io/File.java
* file located in the PATH environment variable.
*/
- public boolean canExecute() {
+ public boolean canRun() {
final var exe = getName();
final var paths = getenv( "PATH" ).split( quote( pathSeparator ) );
src/main/java/com/keenwrite/io/HttpMediaType.java
/**
- * Performs an HTTP HEAD request to determine the media type based on the
+ * Performs an HTTP request to determine the media type based on the
* Content-Type header returned from the server.
*
.newBuilder()
.setHeader( "User-Agent", System.getProperty( "http.agent" ) )
- .method( "HEAD", noBody() )
+ .method( "GET", noBody() )
.uri( uri )
.build();
src/main/java/com/keenwrite/io/MediaType.java
*/
public boolean isSvg() {
- // Kroki serves HTTP HEAD requests back as text/plain for SVG images.
- return this == IMAGE_SVG_XML || this == TEXT_PLAIN;
+ return this == IMAGE_SVG_XML;
}
src/main/java/com/keenwrite/processors/XhtmlProcessor.java
import com.keenwrite.preferences.Workspace;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import static java.util.regex.Pattern.UNICODE_CHARACTER_CLASS;
import static java.util.regex.Pattern.compile;
+import static javax.xml.transform.OutputKeys.INDENT;
+import static javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION;
import static org.jsoup.Jsoup.parse;
import static org.jsoup.nodes.Document.OutputSettings.Syntax;
if( protocol.isRemote() ) {
final var url = new URL( src );
- final var conn = url.openConnection();
+ final var conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches( false );
+ conn.setInstanceFollowRedirects( true );
- final var type = conn.getContentType();
- final var mediaType = valueFrom( type );
+ final var mediaType = valueFrom( conn.getContentType() );
imageFile = mediaType.createTemporaryFile( APP_TITLE_LOWERCASE );
try( final var svgIn = conn.getInputStream() ) {
copy( svgIn, imageFile, REPLACE_EXISTING );
}
- if( conn instanceof HttpURLConnection ) {
- ((HttpURLConnection) conn).disconnect();
+ conn.disconnect();
+
+ // Strip comments, superfluous whitespace, DOCTYPE, and XML declarations.
+ if( mediaType.isSvg() ) {
+ sanitize( imageFile );
}
}
return imageFile;
+ }
+
+ /**
+ * Remove whitespace, comments, and XML/DOCTYPE declarations to make
+ * processing work with ConTeXT.
+ *
+ * @param path The SVG file to process.
+ * @throws Exception The file could not be processed.
+ */
+ private void sanitize( final Path path )
+ throws Exception {
+ final var file = path.toFile();
+
+ final var dbf = DocumentBuilderFactory.newInstance();
+ dbf.setIgnoringComments( true );
+ dbf.setIgnoringElementContentWhitespace( true );
+
+ final var db = dbf.newDocumentBuilder();
+ final var document = db.parse( file );
+
+ final var tf = TransformerFactory.newInstance();
+ final var transformer = tf.newTransformer();
+
+ final var source = new DOMSource( document );
+ final var result = new StreamResult( file );
+ transformer.setOutputProperty( OMIT_XML_DECLARATION, "yes" );
+ transformer.setOutputProperty( INDENT, "no" );
+ transformer.transform( source, result );
+ }
+
+ /**
+ * Overwrites content in the given file up to the first occurrence of a
+ * terminal token.
+ * <p>
+ * Kroki adds XML and DOCTYPE declarations to SVG files, which ConTeXt cannot
+ * parse. This method overwrites them with spaces without reloading the
+ * whole file.
+ * </p>
+ *
+ * @param path Path to the file subject to overwriting.
+ * @param terminal The token string that indicates the search is over.
+ * @param replacement The replacement byte to use for overwriting.
+ * @throws IOException Could not perform I/O operations on the file.
+ */
+ private void overwrite(
+ final Path path, final String terminal, final byte replacement )
+ throws IOException {
+ assert terminal != null;
+
+ try( final var raf = new RandomAccessFile( path.toFile(), "rw" ) ) {
+ final var bytes = terminal.getBytes();
+ final var length = raf.length();
+ var index = 0;
+ raf.seek( 0 );
+
+ while( raf.getFilePointer() < length && index < bytes.length ) {
+ final var b = raf.read();
+ index += bytes[ index ] == b ? 1 : -index;
+ raf.seek( raf.getFilePointer() - 1 );
+ raf.write( replacement );
+ }
+
+ // Restore the terminal token.
+ if( index == bytes.length ) {
+ raf.seek( raf.getFilePointer() - index );
+ raf.write( bytes );
+ }
+ }
}
src/main/java/com/keenwrite/typesetting/Typesetter.java
public void typeset( final Path input, final Path output )
throws IOException {
- if( TYPESETTER.canExecute() ) {
+ if( TYPESETTER.canRun() ) {
sService.submit( new TypesetTask( input, output ) );
}
themes/README.md
+# Overview
+
+Themes define how ConTeXt renders the final document into a PDF file. This
+document provides information that may be helpful for configuring the
+typesetter.
+
+# Fonts
+
+This section lists fonts recommended by various websites regarding serif
+fonts used by professional typesetters.
+
+## Highly Recommended
+
+Recommendations from at least two sources:
+
+* Bembo
+* Caslon Pro
+* Dante
+* Adobe Garamond Pro
+* Minion Pro
+* Palatino
+* Sabon
+
+## Typical
+
+Recommendations from one source:
+
+* Agmena Pro
+* Baskerville
+* Bodoni
+* Bookman Old Style
+* Cardo
+* Centaur
+* Century
+* Electra
+* Filosophia
+* Fournier
+* Jenson
+* Georgia
+* Goudy Bookletter 1911
+* Hawking
+* Hoefler Text
+* Solitas Serif
+* Theano Didot
+* Tryst
+
+## Kindle
+
+Fonts available for use by Kindle readers:
+
+* Arial
+* Baskerville
+* Caecilia
+* Courier
+* Georgia
+* Helvetica
+* Lucida Sans Unicode
+* Palatino
+* Times New Roman
+* Trebuchet
+* Verdana
+
themes/plain/classes.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Custom styling for annotations that appear in the document
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
\defineframedtext[projection][
style=tt,
themes/plain/colours.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Constant declarations for colours used throughout the document
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Darken or lighten the colours by the same amount.
+\def\TextColourDk{0.5}
+\def\TextColourLt{1.5}
+
+% Main colour
+\definecolor[TextColourPrimary][h=0081C2]
+
+% Accent colour
+\definecolor[TextColourSecondary][h=CB4A4C]
+
+% Shade colours
+\definecolor[TextColourTertiary][h=454545]
+
+% Hyperlink colour
+\definecolor[TextColourHyperlink][h=6C984C]
+
+\definespotcolor[TextColourPrimaryDk][TextColourPrimary][p=\TextColourDk]
+\definespotcolor[TextColourPrimaryLt][TextColourPrimary][p=\TextColourLt]
+
+\definespotcolor[TextColourSecondaryDk][TextColourSecondary][p=\TextColourDk]
+\definespotcolor[TextColourSecondaryLt][TextColourSecondary][p=\TextColourLt]
+
+\definespotcolor[TextColourTertiaryDk][TextColourTertiary][p=\TextColourDk]
+\definespotcolor[TextColourTertiaryLt][TextColourTertiary][p=\TextColourLt]
+
themes/plain/document.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Settings that apply to the whole document
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Enable full-colour documents
+\setupcolors[
+ state=start,
+ rgb=yes,
+ color=TextColourHyperlink,
+ textcolor=TextColourTertiaryDk,
+ pagecolormodel=auto,
+]
+
+% Enable clickable hyperlinks
+\setupinteraction[
+ state=start
+]
+
+
themes/plain/entities.tex
-% Map XHTML document entities to ConTeXt symbols and TeX macros.
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Map XHTML document entities to ConTeXt symbols and TeX macros
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\xmltexentity{ldquo}{\symbol[leftquotation]{}}
themes/plain/env.tex
-% Defines any macros required by all other TeX files.
-
-\define[2]\href{%
- \begingroup
- \setupinteraction[
- style=normal,
- color=steelblue,
- ]%
- \goto{\color[blue]{#1}}[url(#2)]%
- \endgroup%
-}
-
themes/plain/figures.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Configure how images are presented
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\setupexternalfigures[
+ order={svg,pdf,png},
+ maxwidth=\makeupwidth,
+ width=\makeupwidth,
+]
+
themes/plain/floats.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Configure floating element styles and behaviours
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Indent the paragraph following each table or image
+\setupfloats[indentnext=yes]
+
+% Force images to flow exactly where they fall in the text, captionlessly
+\setupfloat[figure][default={force,none}]
+
+% Allow tables to split across pages, force location in the text
+\setupfloat[table][default={here,split}]
+
themes/plain/fonts.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Define body fonts
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\usetypescript[termes]
+\setupbodyfont[termes, 11pt]
+
+% Enable italics synonym
+\setupbodyfontenvironment[default][em=italic]
+
+\definefontfeature[default][default][
+ expansion=quality,
+]
+
themes/plain/headings.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Configure heading styles and behaviours
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\setuphead[chapter][
+ page=yes,
+ header=empty,
+ after={\blank[line]}
+]
+
+\setuphead[section,subsection][
+ page=no,
+ number=yes,
+ before={\blank[big]},
+ after={\blank[line]}
+]
+
themes/plain/hyperlinks.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Command to simplify hyperlink syntax
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\define[2]\href{%
+ \begingroup
+ \setupinteraction[
+ style=normal,
+ color=TextColourHyperlink,
+ ]%
+ \goto{\color[TextColourHyperlink]{#1}}[url(#2)]%
+ \endgroup%
+}
+
themes/plain/lists.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Configure bullet and enumerated lists
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\definesymbol[bullet][•]
+
+% Reduce the spacing around bullets.
+\setupitemgroup[itemize][1][packed,paragraph][
+ leftmargin=2em,
+ distance=\zeropoint,
+ symbol=bullet,
+]
+
themes/plain/main.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Import all definition and setup configurations
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\input entities.tex
+\input xhtml.tex
+\input fonts.tex
+\input colours.tex
+\input classes.tex
+\input document.tex
+\input hyperlinks.tex
+\input headings.tex
+\input floats.tex
+\input figures.tex
+\input lists.tex
+\input tables.tex
+\input paragraphs.tex
+
themes/plain/paragraphs.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Configure how paragraphs are presented
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\setupindenting[medium, yes]
+
+\setbreakpoints[compound]
+
+\setupalign[
+ hz,
+ hanging,
+ lesshyphenation,
+]
+
+\setuptolerance[
+ stretch,
+ verytolerant,
+]
+
themes/plain/setups.tex
-% XML setups map ConTeXt commands to HTML elements.
-
-\startxmlsetups xml:xhtml
- % Do not typeset the HTML document's header title element.
- \xmlsetsetup{\xmldocument}{*}{-}
-
- % Document elements
- \xmlsetsetup{\xmldocument}{html|body}{xml:*}
-
- % Header elements
- \xmlsetsetup{\xmldocument}{h1|h2|h3|h4|h5|h6}{xml:*}
-
- % Block elements
- \xmlsetsetup{\xmldocument}{p|q|blockquote|div}{xml:*}
-
- % List elements
- \xmlsetsetup{\xmldocument}{ul|ol|li|dl|dt|dd}{xml:*}
-
- % Break elements
- \xmlsetsetup{\xmldocument}{hr|br}{xml:*}
-
- % Inline elements
- \xmlsetsetup{\xmldocument}{span|em|b|strong|a|sup|sub|code|img}{xml:*}
-
- % TeX elements
- \xmlsetsetup{\xmldocument}{tex}{xml:*}
-\stopxmlsetups
-
-\startxmlsetups xml:html
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:body
- \xmlflush{#1}
-\stopxmlsetups
-
-\startxmlsetups xml:h1
- \chapter{\xmlflush{#1}}
-\stopxmlsetups
-
-\startxmlsetups xml:h2
- \section{\xmlflush{#1}}
-\stopxmlsetups
-
-\startxmlsetups xml:h3
- \subsection{\xmlflush{#1}}
-\stopxmlsetups
-
-% Paragraphs are followed by a paragraph break.
-\startxmlsetups xml:p
- \xmlflush{#1}\par
-\stopxmlsetups
-
-\startxmlsetups xml:ul
- \startitemize
- \xmlflush{#1}
- \stopitemize
-\stopxmlsetups
-
-\startxmlsetups xml:li
- \startitem \xmlflush{#1} \stopitem
-\stopxmlsetups
-
-% Requires the \href macro.
-\startxmlsetups xml:a
- \href{\xmlflush{#1}}{\xmlatt{#1}{href}}
-\stopxmlsetups
-
-\startxmlsetups xml:tex
- \xmlflushcontext{#1}
-\stopxmlsetups
-
-% Emphasized text is italicized, typically.
-\startxmlsetups xml:em
- \dontleavehmode{\em\xmlflush{#1}}
-\stopxmlsetups
-
-% Strong text is bolded, typically.
-\startxmlsetups xml:strong
- \dontleavehmode{\bf\xmlflush{#1}}
-\stopxmlsetups
-
-\startxmlsetups xml:img
- \placefigure{}{%
- \externalfigure[\xmlatt{#1}{src}]
- }
-\stopxmlsetups
-
-\startxmlsetups xml:q
- \quotation{\xmlflush{#1}}
-\stopxmlsetups
-
-% Map arbitrary div classes, defined by fenced divs.
-\startxmlsetups xml:div
- \start[\xmlatt{#1}{class}]
- \xmlflush{#1}
- \stop
-\stopxmlsetups
-
-\xmlregistersetup{xml:xhtml}
-
themes/plain/style.tex
-\usetypescript[termes]
-\setupbodyfont[termes, 11pt]
-
-\setupbodyfontenvironment[default][em=italic]
-
-\setupinteraction[state=start]
-
-\setuphead[chapter][
- page=yes,
- header=empty,
- after={\blank[line]}
-]
-
-\setuphead[section,subsection][
- page=no,
- number=yes,
- before={\blank[big]},
- after={\blank[line]}
-]
-
-\setupindenting[medium, yes]
-
-\setupexternalfigures[
- order={svg,pdf,png},
- maxwidth=\makeupwidth,
- width=\makeupwidth,
-]
-
-% Force images to flow exactly where they fall in the text, captionlessly.
-\setupfloat[figure][default={force,none}]
-
-% Indent the paragraph following each image.
-\setupfloats[indentnext=yes]
-
-\definesymbol[bullet][•]
-
-% Reduce the spacing around bullets.
-\setupitemgroup[itemize][1][packed,paragraph][
- leftmargin=2em,
- distance=\zeropoint,
- symbol=bullet,
-]
-
themes/plain/tables.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Configures how tables are presented
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\setupcaption[table][number=no]
+
+\setupxtable[
+ frame=off,
+ topframe=on,
+ bottomframe=on,
+ framecolor=TextColourPrimaryLt,
+ toffset=2pt,
+ boffset=2pt,
+ option={stretch,width},
+ split=yes,
+ header=repeat,
+ footer=repeat,
+]
+
+\setupxtable[head][rulethickness=1pt]
+\setupxtable[body][]
+\setupxtable[foot][rulethickness=1pt]
+
themes/plain/xhtml.tex
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% Map XHTML elements to ConTeXt commands
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\startxmlsetups xml:xhtml
+ % Do not typeset the HTML document's header title element
+ \xmlsetsetup{\xmldocument}{*}{-}
+
+ % Document elements
+ \xmlsetsetup{\xmldocument}{html|body}{xml:*}
+
+ % Header elements
+ \xmlsetsetup{\xmldocument}{h1|h2|h3|h4|h5|h6}{xml:*}
+
+ % Block elements
+ \xmlsetsetup{\xmldocument}{p|q|blockquote|div}{xml:*}
+
+ % List elements
+ \xmlsetsetup{\xmldocument}{ul|ol|li|dl|dt|dd}{xml:*}
+
+ % Table elements
+ \xmlsetsetup{\xmldocument}{table|thead|tbody|tfoot|tr|th|td|caption}{xml:*}
+
+ % Break elements
+ \xmlsetsetup{\xmldocument}{hr|br}{xml:*}
+
+ % Inline elements
+ \xmlsetsetup{\xmldocument}{span|em|b|strong|a|sup|sub|code|img}{xml:*}
+
+ % TeX elements
+ \xmlsetsetup{\xmldocument}{tex}{xml:*}
+\stopxmlsetups
+
+\startxmlsetups xml:html
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:body
+ \xmlflush{#1}
+\stopxmlsetups
+
+\startxmlsetups xml:h1
+ \chapter{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:h2
+ \section{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:h3
+ \subsection{\xmlflush{#1}}
+\stopxmlsetups
+
+% Paragraphs are followed by a paragraph break.
+\startxmlsetups xml:p
+ \xmlflush{#1}\par
+\stopxmlsetups
+
+\startxmlsetups xml:ul
+ \startitemize
+ \xmlflush{#1}
+ \stopitemize
+\stopxmlsetups
+
+\startxmlsetups xml:li
+ \startitem \xmlflush{#1} \stopitem
+\stopxmlsetups
+
+% Requires the \href macro.
+\startxmlsetups xml:a
+ \href{\xmlflush{#1}}{\xmlatt{#1}{href}}
+\stopxmlsetups
+
+\startxmlsetups xml:tex
+ \xmlflushcontext{#1}
+\stopxmlsetups
+
+% Emphasized text is italicized, typically.
+\startxmlsetups xml:em
+ \dontleavehmode{\em\xmlflush{#1}}
+\stopxmlsetups
+
+% Strong text is bolded, typically.
+\startxmlsetups xml:strong
+ \dontleavehmode{\bf\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:img
+ \starttexcode
+ \placefigure{}{%
+ \externalfigure[\xmlatt{#1}{src}][conversion=mp]
+ }
+ \stoptexcode
+\stopxmlsetups
+
+\startxmlsetups xml:q
+ \quotation{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:b
+ \bold{\xmlflush{#1}}
+\stopxmlsetups
+
+\startxmlsetups xml:table
+ \blank[medium]
+ \startembeddedxtable
+ \xmlflush{#1}
+ \stopembeddedxtable
+ \blank[medium]
+\stopxmlsetups
+
+\startxmlsetups xml:thead
+ \startxtablebody[head]
+ \xmlflush{#1}
+ \stopxtablebody
+\stopxmlsetups
+
+\startxmlsetups xml:tbody
+ \startxtablebody[body]
+ \xmlflush{#1}
+ \stopxtablebody
+\stopxmlsetups
+
+\startxmlsetups xml:tfoot
+ \startxtablebody[foot]
+ \xmlflush{#1}
+ \stopxtablebody
+\stopxmlsetups
+
+\startxmlsetups xml:tr
+ \startxrow
+ \xmlflush{#1}
+ \stopxrow
+\stopxmlsetups
+
+\startxmlsetups xml:th
+ \startxcell
+ \bold{\xmlflush{#1}}
+ \stopxcell
+\stopxmlsetups
+
+\startxmlsetups xml:td
+ \startxcell
+ \xmlflush{#1}
+ \stopxcell
+\stopxmlsetups
+
+% Map arbitrary div classes, defined by fenced divs.
+\startxmlsetups xml:div
+ \start[\xmlatt{#1}{class}]\xmlflush{#1}\stop
+\stopxmlsetups
+
+\xmlregistersetup{xml:xhtml}
+
Delta 529 lines added, 168 lines removed, 361-line increase