#######################################################
# Build the complete Comprehensive LaTeX Symbol List. #
#                                                     #
# Author: Scott Pakin <scott-clsl@pakin.org>          #
#######################################################

# Run only one parallelized operation at a time.
pool already_parallel
  depth = 1

# Remove the fancy title page and all old index files to speed up the
# initial build.  (Technically, only the .ind file needs to be removed.)
rule remove-index
  command = $
    workdir=build-$SIZE ; $
    mkdir -p "$$workdir" ; $
    rm -f "$$workdir/title-${SIZE}.idx" $
          "$$workdir/symbols-${SIZE}.ind" $
          "$$workdir/symbols-${SIZE}.idx" $
          "$$workdir/symbols-${SIZE}.ilg" $
          "$$workdir/symbols-${SIZE}-full.ind" $
          "$$workdir/symbols-${SIZE}-full.idx" ; $
    touch $out
  description = Remove index files from $$workdir

# Perform a single run of LaTeX.  The following Ninja variables are
# recognized:
#
# * DEFS (optional): additional LaTeX code to evaluate before reading symbols.tex
# * DIR (mandatory): LaTeX output directory
# * LATEX (mandatory): LaTeX engine; either "pdflatex" or "lualatex"
# * PK (optional): base directory to which mktexpk should write PK files
# * RUN (mandatory): LaTeX run number to output to the user
# * SIZE (mandatory): paper size; either "letter" or "a4"
rule run-latex
  command = $
    set -e ; $
    mkdir -p "$DIR" ; $
    export max_print_line=1048576 ; $
    if [ "$PK" ] ; then export MT_DESTROOT="$$(readlink -f $PK)" ; fi ; $
    $LATEX -output-directory="$DIR" -jobname symbols-$SIZE '\PassOptionsToClass{${SIZE}paper}{article}$DEFS\input symbols' ; $
    touch $out
  description = $LATEX symbols-$SIZE (run $RUN of 5)

# Create an index without any pruning applied to it.  This index is not
# included in the document.  Rather it is used to acquire an accurate
# symbol count for the final build of the document
rule create-full-index
  command = $
    set -e ; $
    targetdir=build-$SIZE ; $
    workdir="$$targetdir/index" ; $
    mkdir -p "$$workdir" ; $
    ./patch-idx "$$workdir/symbols-$SIZE.idx" ; $
    makeindex -s symbols.ist "$$workdir/symbols-$SIZE" ; $
    cp "$$workdir/symbols-$SIZE.ind" "$$targetdir/symbols-${SIZE}-full.ind" ; $
    cp "$$workdir/symbols-$SIZE.idx" "$$targetdir/symbols-${SIZE}-full.idx" ; $
    touch $out
  pool = already_parallel
  description = Creating raw index files

# Create an index based on the current layout.  This index is included
# in the document.  We do some pruning and coalescing of the .idx file
# to improve usability.
rule create-index
  command = $
    set -e ; $
    workdir=build-$SIZE ; $
    ./patch-idx "$$workdir/symbols-$SIZE.idx" ; $
    ./prune-idx "$$workdir/symbols-$SIZE.idx" $PRUNETOML ; $
    makeindex -s symbols.ist "$$workdir/symbols-$SIZE" ; $
    touch $out
  pool = already_parallel
  description = Creating polished index files

# Perform multiple partial builds to generate a title page.
rule create-title-page
  command = $
    set -e ; $
    export max_print_line=1048576 ; $
    ./maketitlepage $LATEX symbols-${SIZE}-full.idx $SIZE ; $
    touch $out
  description = maketitlepage title-${SIZE}

# Get a final symbol count, and put it in the .aux file.
rule count-symbols
  command = $
    set -e ; $
    workdir=build-$SIZE ; $
    cd "$$workdir" ; $
    totalsymbols=`../generate-symlist symbols-${SIZE}-full.ind | wc -l` ; $
    grep -v prevtotalsymbols symbols-${SIZE}.aux > symbols-${SIZE}.pts ; $
    ( echo "\\\\gdef\\\\prevtotalsymbols{$$totalsymbols}" ; $
      echo "\\\\gdef\\\\approxcount{}" ) >> symbols-${SIZE}.pts ; $
    mv symbols-${SIZE}.pts symbols-${SIZE}.aux ; $
    echo "Total symbols: $$totalsymbols" ; $
    cd .. ; $
    touch $out
  description = Counting symbols in symbols-${SIZE}-full.ind

# Postprocess the document.  Adobe Acrobat -- and seemingly no other
# PDF reader -- complains about the title page.  We therefore use
# Ghostscript to fix the PDF; exiftool to copy over the XMP metadata
# that Ghostscript discards; and qpdf to remove duplicate metadata and
# perform additional cleanup.
rule postprocess
  command = $
    set -e ; $
    workdir=build-$SIZE ; $
    cd "$$workdir" ; $
    gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=symbols-${SIZE}-clean.pdf symbols-${SIZE}.pdf ; $
    exiftool -ignoreMinorErrors -tagsfromfile symbols-${SIZE}.pdf -extractEmbedded -xmp:all symbols-${SIZE}-clean.pdf ; $
    qpdf --linearize symbols-${SIZE}-clean.pdf symbols-${SIZE}.pdf ; $
    rm symbols-${SIZE}-clean.pdf symbols-${SIZE}-clean.pdf_original ; $
    cp symbols-${SIZE}.pdf .. ; $
    cd .. ; $
    touch $out
  description = Postprocessing symbols-${SIZE}.pdf

# Bring important LaTeX warnings to the user's attention.
rule report
  command = $
    workdir=build-$SIZE ; $
    cd "$$workdir" ; $
    grep --color -E "^.*multiply.defined.*" symbols-${SIZE}.log ; $
    grep --color -E "^.*undefined.*" symbols-${SIZE}.log | grep -v U/stmry/b/n ; $
    cd .. ; $
    touch $out
  description = Recapping build warnings for symbols-${SIZE}.pdf

###########################################################################

# Step 1.  Delete existing index files so we don't spend time rendering
# index pages on our first few builds.
build build-letter/step-1.stamp : remove-index common-deps.stamp
  SIZE = letter

# Step 2.  Perform an initial build of the document with a generic title
# page and no index pages or table of contents.
build build-letter/step-2.stamp : run-latex build-letter/step-1.stamp
  DIR = build-letter
  SIZE = letter
  RUN = 1

# Step 3.  Perform an initial build of the document, again with a generic
# title page and no index pages but a complete table of contents.
# Afterward, the generated .idx file should incorporate final page numbers.
build build-letter/step-3.stamp build-letter/symbols-letter.idx : run-latex build-letter/step-2.stamp
  DIR = build-letter
  SIZE = letter
  RUN = 2

# Step 4.  Concurrently with Step 3, perform another initial build of the
# document with a generic title page and no index pages but this time
# forcing the indexing of all symbols.
build build-letter/step-4.stamp build-letter/index/symbols-letter.idx : run-latex build-letter/step-2.stamp
  DIR = build-letter/index
  SIZE = letter
  DEFS = \def\forceindexingon{}
  PK = build-letter/index
  RUN = 3

# Step 5.  Produce a filtered index in symbols-letter.idx and
# symbols-letter.ind.
build build-letter/step-5.stamp | build-letter/symbols-letter.ind : create-index build-letter/symbols-letter.idx
  SIZE = letter

# Step 6.  Produce an unfiltered index in symbols-letter-full.idx and
# symbols-letter-full.ind.
build build-letter/step-6.stamp | build-letter/symbols-letter-full.ind : create-full-index build-letter/index/symbols-letter.idx
  SIZE = letter

# Step 7.  Generate a title page using symbols found in the unfiltered
# index.
build build-letter/step-7.stamp | build-letter/title-letter.tex : create-title-page build-letter/symbols-letter-full.ind
  SIZE = letter

# Step 8.  Build the document with the filtered index.  Afterward, the
# table of contents and PDF bookmarks files should point to the correct
# index pages, but these (and the title page) are not yet incorporated into
# the document.
build build-letter/step-8.stamp build-letter/symbols-letter.out : run-latex build-letter/symbols-letter.ind
  DIR = build-letter
  SIZE = letter
  RUN = 4

# Step 9.  Modify in place the symbols-letter.aux produced in Step 8 to
# include an accurate symbol count based on the unfiltered index from Step
# 5.
build build-letter/step-9.stamp | build-letter/symbols-letter.aux : count-symbols build-letter/step-8.stamp build-letter/symbols-letter-full.ind generate-symlist
  SIZE = letter

# Step 10.  Build the final document using the fancy title page (Step 7),
# the table of contents and PDF bookmarks correctly reflecting the index
# pages (Step 8), and the final symbol count (Step 9),
build build-letter/step-10.stamp | build-letter/symbols-letter.log : run-latex build-letter/title-letter.tex build-letter/symbols-letter.out build-letter/symbols-letter.aux
  DIR = build-letter
  SIZE = letter
  RUN = 5
  DEFS = \def\titlefile{build-letter/title-letter}

# Step 11.  Postprocess the symbols-letter.pdf produced in Step 10 to
# make it work with more PDF readers.  Copy the result from the build
# directory to the top-level directory.
build build-letter/step-11.stamp | symbols-letter.pdf : postprocess build-letter/symbols-letter.log
  SIZE = letter

# Step 12.  For user convenience, repeat and highlight certain warnings
# encountered during the Step 10 build of the document after Step 11
# postprocessing is complete.
build build-letter/step-12.stamp : report symbols-letter.pdf
  SIZE = letter

# Define "letter" as an alias for building the complete symbols-letter.pdf
# and re-reporting any warning messages.
build letter : phony build-letter/step-12.stamp

###########################################################################

# Step 1.  Delete existing index files so we don't spend time rendering
# index pages on our first few builds.
build build-a4/step-1.stamp : remove-index common-deps.stamp
  SIZE = a4

# Step 2.  Perform an initial build of the document with a generic title
# page and no index pages or table of contents.
build build-a4/step-2.stamp : run-latex build-a4/step-1.stamp
  DIR = build-a4
  SIZE = a4
  RUN = 1

# Step 3.  Perform an initial build of the document, again with a generic
# title page and no index pages but a complete table of contents.
# Afterward, the generated .idx file should incorporate final page numbers.
build build-a4/step-3.stamp build-a4/symbols-a4.idx : run-latex build-a4/step-2.stamp
  DIR = build-a4
  SIZE = a4
  RUN = 2

# Step 4.  Concurrently with Step 3, perform another initial build of the
# document with a generic title page and no index pages but this time
# forcing the indexing of all symbols.
build build-a4/step-4.stamp build-a4/index/symbols-a4.idx : run-latex build-a4/step-2.stamp
  DIR = build-a4/index
  SIZE = a4
  DEFS = \def\forceindexingon{}
  PK = build-a4/index
  RUN = 3

# Step 5.  Produce a filtered index in symbols-a4.idx and
# symbols-a4.ind.
build build-a4/step-5.stamp | build-a4/symbols-a4.ind : create-index build-a4/symbols-a4.idx
  SIZE = a4

# Step 6.  Produce an unfiltered index in symbols-a4-full.idx and
# symbols-a4-full.ind.
build build-a4/step-6.stamp | build-a4/symbols-a4-full.ind : create-full-index build-a4/index/symbols-a4.idx
  SIZE = a4

# Step 7.  Generate a title page using symbols found in the unfiltered
# index.
build build-a4/step-7.stamp | build-a4/title-a4.tex : create-title-page build-a4/symbols-a4-full.ind
  SIZE = a4

# Step 8.  Build the document with the filtered index.  Afterward, the
# table of contents and PDF bookmarks files should point to the correct
# index pages, but these (and the title page) are not yet incorporated into
# the document.
build build-a4/step-8.stamp build-a4/symbols-a4.out : run-latex build-a4/symbols-a4.ind
  DIR = build-a4
  SIZE = a4
  RUN = 4

# Step 9.  Modify in place the symbols-a4.aux produced in Step 8 to
# include an accurate symbol count based on the unfiltered index from Step
# 5.
build build-a4/step-9.stamp | build-a4/symbols-a4.aux : count-symbols build-a4/step-8.stamp build-a4/symbols-a4-full.ind generate-symlist
  SIZE = a4

# Step 10.  Build the final document using the fancy title page (Step 7),
# the table of contents and PDF bookmarks correctly reflecting the index
# pages (Step 8), and the final symbol count (Step 9),
build build-a4/step-10.stamp | build-a4/symbols-a4.log : run-latex build-a4/title-a4.tex build-a4/symbols-a4.out build-a4/symbols-a4.aux
  DIR = build-a4
  SIZE = a4
  RUN = 5
  DEFS = \def\titlefile{build-a4/title-a4}

# Step 11.  Postprocess the symbols-a4.pdf produced in Step 10 to
# make it work with more PDF readers.  Copy the result from the build
# directory to the top-level directory.
build build-a4/step-11.stamp | symbols-a4.pdf : postprocess build-a4/symbols-a4.log
  SIZE = a4

# Step 12.  For user convenience, repeat and highlight certain warnings
# encountered during the Step 10 build of the document after Step 11
# postprocessing is complete.
build build-a4/step-12.stamp : report symbols-a4.pdf
  SIZE = a4

# Define "a4" as an alias for building the complete symbols-a4.pdf
# and re-reporting any warning messages.
build a4 : phony build-a4/step-12.stamp
