Package: pdf.tocgen
pdf.tocgenin.pdf
                            |
                            |
     +----------------------+--------------------+
     |                      |                    |
     V                      V                    V
+----------+          +-----------+         +----------+
|          |  recipe  |           |   ToC   |          |
| pdfxmeta +--------->| pdftocgen +-------->| pdftocio +---> out.pdf
|          |          |           |         |          |
+----------+          +-----------+         +----------+pdf.tocgenis a set of command-line tools for automatically
extracting and generating the table of contents (ToC) of a PDF file. It uses
the embedded font attributes and position of headings to deduce the basic
outline of a PDF file.It works best for PDF files produces from a TeX document usingpdftex(and
its friendspdflatex,pdfxetex, etc.), but it's designed to work with anysoftware-generatedPDF files (i.e. you shouldn't expect it to work with
scanned PDFs). Some examples includetroff/groff, Adobe InDesign, Microsoft
Word, and probably more.Please see thehomepagefor a detailed introduction.Installationpdf.tocgen is written in Python 3. It is known to work with Python 3.7 to 3.11
on Linux, Windows, and macOS (On BSDs, you probably need to build PyMuPDF
yourself). Use$pipinstall-Updf.tocgento install the latest version systemwide. Alternatively, usepipxor$pipinstall-U--userpdf.tocgento install it for the current user. I would recommend the latter approach to
avoid messing up the package manager on your system.If you are using an Arch-based Linux distro, the package is also available onAUR. It can be installed using any AUR helper, for exampleyay:$ yay -S pdf.tocgenWorkflowThe design of pdf.tocgen is influenced by theUnix philosophy. I
intentionally separated pdf.tocgen to 3 separate programs. They work together,
but each of them is useful on their own.pdfxmeta: extract the metadata (font attributes, positions) of headings to
build arecipefile.pdftocgen: generate a table of contents from the recipe.pdftocio: import the table of contents to the PDF document.You should readthe exampleon the homepage for a proper introduction,
but the basic workflow follows like this.First, usepdfxmetato search for the metadata of headings, and generateheading filtersusing the automatic setting$pdfxmeta-ppage-a1in.pdf"Section">>recipe.toml
$pdfxmeta-ppage-a2in.pdf"Subsection">>recipe.tomlNote thatpageneeds to be replaced by the page number of the search keyword.The outputrecipe.tomlfile would contain several heading filters, each of
which specifies the attribute of a heading at a particular level should have.An example recipe file would look like this:[[heading]]level=1greedy=truefont.name="Times-Bold"font.size=19.92530059814453[[heading]]level=2greedy=truefont.name="Times-Bold"font.size=11.9552001953125Then pass the recipe topdftocgento generate a table of contents,$pdftocgenin.pdf<recipe.toml"Preface" 5"Bottom-up Design" 5"Plan of the Book" 7"Examples" 9"Acknowledgements" 9"Contents" 11"The Extensible Language" 14"1.1 Design by Evolution" 14"1.2 Programming Bottom-Up" 16"1.3 Extensible Software" 18"1.4 Extending Lisp" 19"1.5 Why Lisp (or When)" 21"Functions" 22"2.1 Functions as Data" 22"2.2 Defining Functions" 23"2.3 Functional Arguments" 26"2.4 Functions as Properties" 28"2.5 Scope" 29"2.6 Closures" 30"2.7 Local Functions" 34"2.8 Tail-Recursion" 35"2.9 Compilation" 37"2.10 Functions from Lists" 40"Functional Programming" 41"3.1 Functional Design" 41"3.2 Imperative Outside-In" 46"3.3 Functional Interfaces" 48"3.4 Interactive Programming" 50[--snip--]which can be directly imported to the PDF file usingpdftocio,$pdftocgenin.pdf<recipe.toml|pdftocio-oout.pdfin.pdfOr if you want to edit the table of contents before importing it,$pdftocgenin.pdf<recipe.toml>toc
$vimtoc# edit$pdftocioin.pdf<tocEach of the three programs has some extra functionalities. Use the-hoption
to see all the options you could pass in.Command examplesBecause of the modularity of design, each program is useful on its own, despite
being part of the pipeline. This section will provide some more examples on how
you could use them. Feel free to come up with more.pdftociopdftocioshould best demonstrate this point, this program can do a lot on its
own.To display existing table of contents in a PDF tostdout:$pdftociodoc.pdf"Level 1 heading 1" 1"Level 2 heading 1" 1"Level 3 heading 1" 2"Level 3 heading 2" 3"Level 2 heading 2" 4"Level 1 heading 2" 5To write existing table of contents in a PDF to a file namedtoc:$pdftociodoc.pdf>tocTo write atocfile back todoc.pdf:$pdftociodoc.pdf<tocTo specify the name of output PDF:$pdftocio-oout.pdfdoc.pdf<tocTo copy the table of contents fromdoc1.pdftodoc2.pdf:$pdftocio-vdoc1.pdf|pdftociodoc2.pdfNote that the-vflag helps preserve the vertical
positions of headings during the copy.To print the table of contents for reading:$pdftocio-Hdoc.pdfLevel 1 heading 1 ··· 1Level 2 heading 1 ··· 1Level 3 heading 1 ··· 2Level 3 heading 2 ··· 3Level 2 heading 2 ··· 4Level 1 heading 2 ··· 5pdftocgenIf you have obtained an existing recipercp.tomlfordoc.pdf, you could
apply it and print the outline tostdoutby$pdftocgendoc.pdf<rcp.toml"Level 1 heading 1" 1"Level 2 heading 1" 1"Level 3 heading 1" 2"Level 3 heading 2" 3"Level 2 heading 2" 4"Level 1 heading 2" 5To output the table of contents to a file calledtoc:$pdftocgendoc.pdf<rcp.toml>tocTo import the generated table of contents to the PDF file, and output
todoc_out.pdf:$pdftocgendoc.pdf<rcp.toml|pdftocio-odoc_out.pdfdoc.pdfTo print the generated table of contents for reading:$pdftocgen-Hdoc.pdf<rcp.tomlLevel 1 heading 1 ··· 1Level 2 heading 1 ··· 1Level 3 heading 1 ··· 2Level 3 heading 2 ··· 3Level 2 heading 2 ··· 4Level 1 heading 2 ··· 5If you want to include the vertical position in a page for each heading, use the-vflag$pdftocgen-vdoc.pdf<rcp.toml"Level 1 heading 1" 1 306.947998046875"Level 2 heading 1" 1 586.3488159179688"Level 3 heading 1" 2 586.5888061523438"Level 3 heading 2" 3 155.66879272460938"Level 2 heading 2" 4 435.8687744140625"Level 1 heading 2" 5 380.78875732421875pdftociocan understand the vertical position in the output to generate table
of contents entries that link to the exact position of the heading, instead of
the top of the page.$pdftocgen-vdoc.pdf<rcp.toml|pdftociodoc.pdfNote that the default output ofpdftociohere isdoc_out.pdf.pdfxmetaTo search forAnaphoricin the entire PDF:$pdfxmetaonlisp.pdf"Anaphoric"14. Anaphoric Macros:font.name = "Times-Bold"font.size = 9.962599754333496font.color = 0x000000font.superscript = falsefont.italic = falsefont.serif = truefont.monospace = falsefont.bold = truebbox.left = 308.6400146484375bbox.top = 307.1490478515625bbox.right = 404.33282470703125bbox.bottom = 320.9472351074219[--snip--]To output the result as a heading filter with the automatic settings,$pdfxmeta-a1onlisp.pdf"Anaphoric"[[heading]]#14.AnaphoricMacroslevel = 1greedy = truefont.name = "Times-Bold"font.size = 9.962599754333496#font.size_tolerance=1e-5#font.color=0x000000#font.superscript=false#font.italic=false#font.serif=true#font.monospace=false#font.bold=true#bbox.left=308.6400146484375#bbox.top=307.1490478515625#bbox.right=404.33282470703125#bbox.bottom=320.9472351074219#bbox.tolerance=1e-5[--snip--]which can be directly write to a recipe file:$pdfxmeta-a1onlisp.pdf"Anaphoric">>recipe.tomlTo case-insensitive search forAnaphoricin the entire PDF:$pdfxmeta-ionlisp.pdf"Anaphoric"to compile-time. Chapter 14 introduces anaphoric macros, which allow you to:font.name = "Times-Roman"font.size = 9.962599754333496font.color = 0x000000font.superscript = falsefont.italic = falsefont.serif = truefont.monospace = falsefont.bold = falsebbox.left = 138.60000610351562bbox.top = 295.6583557128906bbox.right = 459.0260009765625bbox.bottom = 308.948486328125[--snip--]Use regular expression to case-insensitive search search forAnaphoricin the
entire PDF:$pdfxmetaonlisp.pdf"[Aa]naphoric"to compile-time. Chapter 14 introduces anaphoric macros, which allow you to:font.name = "Times-Roman"font.size = 9.962599754333496font.color = 0x000000font.superscript = falsefont.italic = falsefont.serif = truefont.monospace = falsefont.bold = falsebbox.left = 138.60000610351562bbox.top = 295.6583557128906bbox.right = 459.0260009765625bbox.bottom = 308.948486328125[--snip--]To search only on page 203:$pdfxmeta-p203onlisp.pdf"anaphoric"anaphoric if, called:font.name = "Times-Roman"font.size = 9.962599754333496font.color = 0x000000font.superscript = falsefont.italic = falsefont.serif = truefont.monospace = falsefont.bold = falsebbox.left = 138.60000610351562bbox.top = 283.17822265625bbox.right = 214.81094360351562bbox.bottom = 296.4683532714844[--snip--]To dump the entire page of 203:$pdfxmeta-p203onlisp.pdf190:font.name = "Times-Roman"font.size = 9.962599754333496font.color = 0x000000font.superscript = falsefont.italic = falsefont.serif = truefont.monospace = falsefont.bold = falsebbox.left = 138.60000610351562bbox.top = 126.09941101074219bbox.right = 153.54388427734375bbox.bottom = 139.38951110839844[--snip--]To dump the entire PDF document:$pdfxmetaonlisp.pdfi:font.name = "Times-Roman"font.size = 9.962599754333496font.color = 0x000000font.superscript = falsefont.italic = falsefont.serif = truefont.monospace = falsefont.bold = falsebbox.left = 458.0400085449219bbox.top = 126.09941101074219bbox.right = 460.8096008300781bbox.bottom = 139.38951110839844[--snip--]DevelopmentIf you want to modify the source code or contribute anything, first installpoetry, which is a dependency and package manager for Python used
by pdf.tocgen. Then run$poetryinstallin the root directory of this repository to set up development dependencies.If you want to test the development version of pdf.tocgen, use thepoetry runcommand:$poetryrunpdfxmetain.pdf"pattern"Alternatively, you could also use the$poetryshellcommand to open up a virtual environment and run the development version
directly:(pdf.tocgen)$pdfxmetain.pdf"pattern"Before you send a patch or pull request, make sure the unit test passes by
running:$maketestGUI front endIf you are a Emacs user, you could install Daniel Nicolai'stoc-modepackage as a GUI front end for pdf.tocgen, though it offers many more
functionalities, such as extracting (printed) table of contents from a PDF
file. Note that it uses pdf.tocgen under the hood, so you still need to install
pdf.tocgen before using toc-mode as a front end for pdf.tocgen.Licensepdf.tocgen itself a is free software. The source code of pdf.tocgen is licensed
under the GNU GPLv3 license. However, the recipes in therecipesdirectory is
separately licensed under theCC BY-NC-SA 4.0 Licenseto prevent any
commercial usage, and thus not included in the distribution.pdf.tocgen is based onPyMuPDF, licensed under the GNU GPLv3
license, which is again based onMuPDF, licensed under the GNU AGPLv3
license. A copy of the AGPLv3 license is included in the repository.If you want to make any derivatives based on this project, please follow the
terms of the GNU GPLv3 license.