Document List

Imagine that you have the following list of documents—which are part of the ConTeXt Suite—in a CSV file:

"About \LuaTeX\ and \ConTeXt";"about.pdf"
"l2r, r2l: A Few Tips";"bidi.pdf"
"Flowcharts";"charts-mkiv.pdf"
"\ConTeXt\ Lua Documents";"cld-mkiv.pdf"
"Coloring \ConTeXt: Explaining \LuaTeX\ and MkIV";"colors-mkiv.pdf"
"Columns";"columnsets.pdf"
"It’s in the Details";"details.pdf"
;
;
"Exporting XML and ePub from \ConTeXt";"epub-mkiv.pdf"
"MkIV Hybrid Technology";"hybrid.pdf"
"Languages in \ConTeXt: Explaining \LuaTeX\ and MkIV";"languages-mkiv.pdf"
"Libraries in \ConTeXt";"libraries-mkiv.pdf"
"Lua: The \ConTeXt\ Libraries";"lua-mkiv.pdf"
"\LuaTeX\ Reference Manual";"luatex.pdf"
"\ConTeXt\ Mark IV: An Excursion";"ma-cb-en.pdf"
"Math";"math-mkiv.pdf"
"\MetaFun: \ConTeXt\ MkIV";"metafun-p.pdf"
;
"Bibliographies: The \ConTeXt\ Way";"mkiv-publications.pdf"
"\ConTeXt\ MKII – MKIV: The History of \LuaTeX";"mk.pdf"
;
"MathML";"mmlprime.pdf"
"Read Me First";"mreadme.pdf"
"\ConTeXt\ Musings";"musings.pdf"
"Nodes";"nodes.pdf"
"Why Not Now";"notnow.pdf"
"On and On";"onandon.pdf"
"Pages";"pagecolumns.pdf"
"Rules: A \ConTeXt\ MkIV Manual";"rules-mkiv.pdf"
"Spacing in \ConTeXt";"spacing-mkiv.pdf"
"Simple Spreadsheets: \ConTeXt\ MkIV";"spreadsheets-mkiv.pdf"
"SQL in \ConTeXt";"sql-mkiv.pdf"
"Steps: \ConTeXt\ MkIV";"steps-mkiv.pdf"
"Still Going On";"still.pdf"
"SwigLib Basics";"swiglib-mkiv.pdf"
"LMX Templates";"templates-mkiv.pdf"
;
"Tools: luatools, mtxrun, context";"tools-mkiv.pdf"
"Units: \ConTeXt\ MkIV";"units-mkiv.pdf"
"Workflow Support in \ConTeXt";"workflows-mkiv.pdf"
"Dealing with XML in \ConTeXt\ MkIV";"xml-mkiv.pdf"
"Extreme Tables: \ConTeXt\ MkIV";"xtables-mkiv.pdf"

ConTeXt Source

You may embed them in PDF document, using the following ConTeXt source:

\enablemode[external-sha]
\enabledirectives[backend.date=no]
\enabledirectives[backend.xmp=no]

\startluacode
function document.addfunnyhyphen(tfmdata)
    local underscore = utf.byte("_")
    local char       = tfmdata.characters[underscore]
    if not char then return end
    tfmdata.characters[0xFE000]   = {
        width    = 0,
        height   = 0,
        depth    = 0,
        commands = {
            { "right", -char.width },
            { "down", char.depth },
            { "slot", 1, underscore },
        }
    }
end


utilities.sequencers.appendaction("aftercopyingcharacters",
"after","document.addfunnyhyphen")

local shared = {
    start  = 1,
    length = 1,
    before = utf.char(0xFE000),
    after  = nil,
    left   = false,
    right  = false,
}

local all = table.setmetatableindex({ }, function(t,k)
    return shared
end)

languages.hyphenators.traditional.installmethod("sha",
    function(dictionary,word,n)
        return all
end
)

function document.capture(cmd, raw)
    local f = assert(io.popen(cmd, 'r'))
    local s = assert(f:read('*a'))
    f:close()
    if raw then return s end
    s = string.gsub(s, '^%s+', '')
    s = string.gsub(s, '%s+$', '')
    s = string.gsub(s, '[\n\r]+', ' ')
    return s
end

function document.sha256(file)
    command_output= document.capture("sha256sum -b " .. file)
    context(command_output:sub(0,64))
end

function document.sha512(file)
    command_output= document.capture("sha512sum -b " .. file)
    context(command_output:sub(0,128))
end
\stopluacode

\definehyphenationfeatures
   [sha]
   [characters=all,
    alternative=sha,
    righthyphenchar="FE000]

\unexpanded\def\sha#1%
   {\begingroup\tt
    \sethyphenationfeatures[sha]%
    \setuphyphenation[method=traditional]%
    #1%
    \endgroup}

\startmode[external-sha]
    \def\shatwo#1{\ctxlua{document.sha256("#1")}}
    \def\shafive#1{{\tt\ctxlua{document.sha512("#1")}}}
\stopmode

\startnotmode[external-sha]
    \ctxlua{require("util-sha")}

    \def\shatwo#1{%
        \cldcontext{utilities.sha2.hash256(io.loaddata("#1"))}}

    \def\shafive#1{%
        \cldcontext{utilities.sha2.hash512(io.loaddata("#1"))}}
\stopnotmode

\setupinteraction[state=start, color=, style=, contrastcolor=]
\setupinteractionscreen[option={portrait, attachment}]

\usemodule[handlecsv]

\opencsvfile{context-documents.csv}
\removeemptylines

\setupbodyfont[times]

\def\DocumentsPath{ctxbeta/tex/texmf-context/doc/context/documents/general/manuals/}

\starttext
\title{Some Special \ConTeXt\ Documents}
\startbuffer[item-file]
    \item {\em\cA} \doiffile{\DocumentsPath\cB}{\attachment[title=\cA,
      name={\zeroedlineno-\cB}, file={\DocumentsPath\cB},
      subtitle={SHA256: \shatwo{\DocumentsPath\cB}}]}\stopmode, with SHA512:
    \doiffileelse{\DocumentsPath\cB}{\sha{\shafive{\DocumentsPath\cB}}}
        {{\ssbf\WORD{\color[red]{\\attachment\\is missing}}}}.
\stopbuffer
\startitemize[n]
\doloopif{\cB}{~=}{}{\getbuffer[item-file]}
\stopitemize
\stoptext

Compilation Times

The code above is something I use at work to submit many digitally signed PDF documents. I want to provide the stronger SHA512, but for reference I also add the SHA256 in the note to the attachment.

The list of 38 documents have to be embedded in the final PDF document and are hashed for SHA512 and SHA256.

There are three ConTeXt versions1 (all betas), from 2018.08.28 17:21 and from 2018.08.30 18:41. The first beta comes with LuaTeX-1.08 6731 and the second beta comes with LuaTeX-1.08 6909. The third beta is from LMTX 2019.04.26 00:322.

These are the average generation times of full compilations:

  Lua-5.3 Lua-5.2 (JIT) Lua-5.4
LuaTeX-1.08 6731 160″ 10.6″
LuaTeX-1.08 6909 9.9″ 10.5″
LuaTeX 2.00 7079 7.3″3

Notes

  1. As it can be noticed from the dates, this testing was performed first when LuaTeX-1.08 was improved. And I performed it again with ConTeXt LuaMetaTeX—almost seven months later. 

  2. The next generation of ConTeXt MkIV is LMTX (or LuaMetaTeX). It works with Lua-5.4 and there will be no JIT version. 

  3. Using the external option, compilation times are the same.