cmake-pandocology
cmake-pandocology copied to clipboard
Compile documents using Pandoc under the CMake build system
PANDOCOLOGY
"Pandocology" is a CMake module that allows you to generate documents using pandoc. It is very much modeled after UseLATEX, and is meant to make the process of going from source to final product as easy as possible, so you can focus on writing instead of compiling.
To see a document sample take a took to pandocology sample
Requirements
- Pandoc
- LaTeX
- latexmk
Installation
Simply place the file "pandocology.cmake
" and cmspandoc.cmake
in a place where
CMake can find it, i.e., somewhere on your CMake module path.
For example, given a typical CMake project organized as:
project/
cmake/Modules/
src/
ou might place the file "pandocology.cmake
in "project/cmake/Modules
", and then add a line like the following either in the top-level "CMakeLists.txt
" or any other "CMakeLists.txt
" processed before the commands provided by "Pandocology" are needed:
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules")
In my own case, I have cloned this entire repository as a submodule of my project module:
$ cd cmake/Modules
$ git submodule add https://github.com/jeetsukumaran/cmake-pandocology.git
Then, I added the following line to my top-level "CMakeLists.txt
":
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/cmake-pandocology")
Once you have added the file to your project working tree, and made sure that CMake knows how to find it by updating the CMake module path, then as with any other CMake module, you need to source or include it in the "CmakeLists.txt
" file in which you are going to use it:
INCLUDE(pandocology)
Basic Usage
The primary command offered by "Pandocology" is "add_document()
".
This command takes, at a mininum, three arguments: a target name, an output file name which specifies the output file (and, by inspection of the extension, the output file format), and at least one source file specifed by the "SOURCES
" argument.
So, for example, if you had a Markdown format input file (say, "opus.md
") that you wanted to convert to Rich Text Format, then the following is a minimal "CMakeLists.txt
" to do that.
LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules/cmake-pandocology")
INCLUDE(pandocology)
add_document(
TARGET opus
OUTPUT_FILE opus.rtf
SOURCES opus.md
)
Once the project is built, the result "opus.rtf
" will end up in the "product
" subdirectory of the build directory.
You can change the output directory by using the "PRODUCT_DIRECTORY
" argument:
add_document(
TARGET opus
OUTPUT_FILE opus.rtf
SOURCES opus.md
PRODUCT_DIRECTORY opus_output_directory
)
Deprecated syntax for backwards compatibility:
add_document(
opus.rtf
SOURCES opus.md
PRODUCT_DIRECTORY opus_output_directory
)
Passing Directives to "pandoc
"
You have access to the full complexity of the Pandoc compiler through the "PANDOC_DIRECTIVES
" argument, which will pass everything to the underlying "pandoc
" program. So, for example, to generate a PDF with some custom options:
add_document(
TARGET opus
OUTPUT_FILE opus.pdf
SOURCES opus.md
PANDOC_DIRECTIVES -t latex
--smart
--self-contained
--toc
--listings
)
Including Static Resources
In many cases your inputs are going to be more than just the primary source document: images, CSS stylesheets, BibTeX bibliography database files, stylesheets, templates etc.
All these secondary files or inputs that are not the primary input to the "pandoc
" program, but are required to compile the main document, are known as "resources".
These resources can be specified on a file-by-file basis using the "RESOURCE_FILES
" argument and on a directory-by-directory basis using the "RESOURCE_DIRS
" argument (note that all paths are relative to the current source directory):
add_document(
TARGET opus
OUTPUT_FILE opus.pdf
SOURCES opus.md
RESOURCE_FILES references.bib custom.template.latex journal.csl
RESOURCE_DIRS figures/ maps/
PANDOC_DIRECTIVES -t latex
--smart
--self-contained
--toc
--listings
--template custom.template.latex
--filter pandoc-citeproc
--csl journal.csl
--bibliography references.bib
)
IMPORTANT NOTE: When adding resources on a directory-basis using the RESOURCE_DIRS
argument, all the resources that are in that directory at the time cmake
is run are added as dependencies. The CMake system does not provide a way to monitor directories for changes, only files. Thus, if you add (or remove) files from any of the directories specified by the RESOURCE_DIRS
argument, you will have to run cmake ..
again to make sure that the build system adds (or removes) these files from the build specifications.
Including Content After the Reference Section
One quirk of "pandoc
" is that the bibliography/reference section is necessarily the last part of the main document body: you cannot (easily and organically) have any sections, such as an appendix, after the reference section.
The work-around is to create these post-reference sections as a separate document, independentally process them using "pandoc
", and then use the "--include-after-body
" directive to include them in the main document.
You can support this workflow using Pandocology as follows:
add_document(
TARGET appendices
OUTPUT_FILE appendices.tex
SOURCES appendices.md
RESOURCE_DIRS appendix-figs
PANDOC_DIRECTIVES -t latex
NO_EXPORT_PRODUCT
)
add_document(
TARGET opus
OUTPUT_FILE opus.pdf
SOURCES opus.md
RESOURCE_FILES references.bib custom.template.latex journal.csl
RESOURCE_DIRS figures/ maps/
PANDOC_DIRECTIVES -t latex
--smart
--listings
--template custom.template.latex
--filter pandoc-citeproc
--csl journal.csl
--bibliography references.bib
--include-after-body=appendices.tex
DEPENDS appendices
)
The first instruction asks Pandocology to build the LaTeX document "appendices.tex
" from the (Markdown) source, "appendices.md
", making to sure include the files in the subdirectory, "appendix-figs
".
The argument "NO_EXPORT_PRODUCT
" tells Pandocology that while we want the file "appendices.tex
" built, but not exported to the final output directory (i.e., "product
" or as specified by the "PRODUCT_DIRECTORY
" argument).
Pandocology makes sure that all build products are built in the current binary source directory so that they are available to other builds within the project, and only copies the final result to the output/product directory.
By specifying "NO_EXPORT_PRODUCT
", we are suppressing the final step, and thus we have the file, "appendices.tex
" available in the source directory to be pulled in by the build for "opus.tex
", but not exported to the final product directory where it will just be noise.
The second instruction builds the primary output that we are interested in, i.e., "opus.pdf
", from the (Markdown) source "opus.md
".
Note how we specify the "--include-after-body=appendices.tex
" argument to "pandoc
", to make sure the Pandoc compiler pulls in the generated TeX file into the main document.
In addition, we also list "appendices
" as a dependency using the "DEPENDS
" argument.
This results in Pandocology informing the CMake build system that "appendices.tex
" will be used in the building of "opus.pdf
".
This is how we make sure that built or generated resources are available in the right place at the right time (as opposed to the "RESOURCE_FILES
" and "RESOURCE_DIRS
" arguments, which make sure that static resources get to the right places at the right time).
Of course, as before, we make sure to specify all the static resources that this document needs (e.g. the bibliography file, the templates, the images in the "figures/
" and "maps/
" subdirectories).
Creating an Archive Bundle for Submission
With some output formats that are themselves source formats requiring further processing (e.g., LaTeX), you may want to create an self-contained archive that includes not only the output document, but also additional resources that the output document may need for further processing.
You can do this by specifying the "EXPORT_ARCHIVE
" flag, which will create a compressed archive of the final file as well as all the static resource files, the static resource directories, and the generated resource dependencies:
add_document(
TARGET appendices
OUTPUT_FILE appendices.tex
SOURCES appendices.md
RESOURCE_DIRS appendix-figs
PANDOC_DIRECTIVES -t latex
NO_EXPORT_PRODUCT
)
add_document(
TARGET opus
OUTPUT_FILE opus.tex
SOURCES opus.md
RESOURCE_FILES references.bib custom.template.latex journal.csl
RESOURCE_DIRS figures/ maps/
PANDOC_DIRECTIVES -t latex
--smart
--listings
--template custom.template.latex
--filter pandoc-citeproc
--csl journal.csl
--bibliography references.bib
--include-after-body=appendices.tex
DEPENDS appendices
EXPORT_ARCHIVE
)
In the above case, once run, the output directory will not only have the primary Pandoc-compilation output, "opus.tex
", but also a BZIP-compressed and TAR'd archive, "opus.tbz
", which includes the file "opus.tex
" and all the resources specified by the "RESOURCE_FILES
" and "RESOURCE_DIRS
" arguments, as well as the resources specified in by the "DEPENDS
" argument.
If you want just the archive (which include the primary product, i.e., "opus.tex
" in the example above), and not the primary file to be created in the output directory, then specify "EXPORT_ARCHIVE
" and "NO_EXPORT_PRODUCT
" together. The former creates the archive and the latter suppresses the creation of a separate (and perhaps, for your purposes, redundant) output.
add_document(
TARGET opus
OUTPUT_FILE opus.tex
SOURCES opus.md
RESOURCE_FILES references.bib custom.template.latex journal.csl
RESOURCE_DIRS figures/ maps/
PANDOC_DIRECTIVES -t latex
--smart
--listings
--template custom.template.latex
--filter pandoc-citeproc
--csl journal.csl
--bibliography references.bib
--include-after-body=appendices.tex
DEPENDS appendices
NO_EXPORT_PRODUCT
EXPORT_ARCHIVE
)
Generating Both a PDF and the TeX, and Creating an Archive Bundle for Submission
Many journals require that you submit both a PDF as well as a TeX source, and, in the latter, may require that all source files needed to TeX the source are also included. The way to do this using Pandocology is to:
- Specify that the primary output is LaTeX that you want an archive exported that bundles the LaTeX file plus all the resources and dependencies by using the "
EXPORT_ARCHIVE
" argument. - Specify that you want the primary output to be post-processed into a PDF using the "
EXPORT_PDF
" argument. - Suppress the creation of the primary LaTeX output (since it is already in the archive bundle) by using the "
NO_EXPORT_PRODUCT
" argument.
add_document(
TARGET appendices
OUTPUT_FILE appendices.tex
SOURCES appendices.md
RESOURCE_DIRS appendix-figs
PANDOC_DIRECTIVES -t latex
NO_EXPORT_PRODUCT
)
add_document(
TARGET opus
OUTPUT_FILE opus.tex
SOURCES opus.md
RESOURCE_FILES references.bib custom.template.latex journal.csl
RESOURCE_DIRS figs
PANDOC_DIRECTIVES -t latex
--smart
--listings
--template custom.template.latex
--filter pandoc-citeproc
--csl journal.csl
--bibliography references.bib
--include-after-body=appendices.tex
DEPENDS appendices
NO_EXPORT_PRODUCT
EXPORT_ARCHIVE
EXPORT_PDF
)
If the above is run, the output directory will have two files: "opus.pdf
" and "opus.tbz
".
The former is the PDF of the document while the latter is the LaTeX file plus all resources needed to generate the PDF.
Working with Pure TeX and LaTeX Source Files: Using Pandocology without using Pandoc
The Pandocology module provides some build functionality that might be desirable even if you are not actually using or want to use Pandoc.
For example, the resource management feature, the ability to bundle all source and resource files into an archive, the ability to specify an output directory, and so on.
If you have a a TeX or a LaTeX project, and you want to generate the final PDF's without using Pandoc but still want to use Pandocology to manage the build process so that you have access to these extra features of Pandocology, you can specify the DIRECT_TEX_TO_PDF
flag, which can be used in conjunction with any other options described previously (though, of course, some options such as PANDOC_DIRECTIVES
make no sense in this context and will be ignored):
add_document(
TARGET opus
OUTPUT_FILE opus.pdf
SOURCES opus.tex
RESOURCE_FILES opus.bib figures.tex sysbio.bst
RESOURCE_DIRS figs
DIRECT_TEX_TO_PDF
EXPORT_ARCHIVE
)
As can be seen, all resources and resource directories (as well as dependencies) are specified as before.
For convenience (mnemonic as much as operational), you can call the function add_tex_document()
instead:
add_tex_document(
TARGET opus
OUTPUT_FILE opus.pdf
SOURCES opus.tex
RESOURCE_FILES opus.bib figures.tex sysbio.bst
RESOURCE_DIRS figs
EXPORT_ARCHIVE
)
In either case, using the direct-tex-to-PDF feature requires that:
- There must be only one source (though an arbitrary number of additional sources included in the main source can be specfied using the "
RESOURCE_FILES
" and "RESOURCE_DIRS
arguments). - The source name (i.e., "
opus.tex
" in the above examples) must have a ".tex
" or ".latex
" extension, and, of course, must be in TeX or LaTeX format. - The target name (i.e., "
opus.pdf
" in the above examples) must have a ".pdf
" extension, and match the source name exactly except for the extension.