Using scons to generate latex source files and compile pdf

可紊 提交于 2020-01-25 09:52:07

问题


I am working on a book. The chapters are stored in markdown files. I use pandoc to generate the LaTeX-Files of the chapters. Here is the structure of the project:

  • Book/Manuscript: contains the markdown files
  • Book/Editions/PDF/tex: contains the generated LaTeX files
  • Book/Editions/PDF/Layout_1/: first layout of the book
  • Book/Editions/PDF/Layout_2/: second layout of the book

I would like to use scons to generate the latex files and to call LaTeX to compile the PDFs.

scons set up

Book/SConstruct:

The SConstruct script defines only where subsequent scripts may find the chapters of the book:

manuscript = Environment()
Manuscript.Replace(MARKDOWN_FILES = Glob('Manuscript/*.md'))

SConscript('Editions/PDF/SConscript', exports='manuscript')

Book/Editions/PDF/SConscript:

This script defines the LaTeX environment:

Import('manuscript')

PDF = Environment()

PDF.Replace(PDFLATEX='lualatex')

Export('PDF')

SConscript('tex/SConscript')

SConscript('Layout_1/SConscript')

SConscript('Layout_2/SConscript')

Book/Editions/PDF/tex/SConscript

This script uses a generator function to create the LaTeX files:

import os

Import('Manuskript')

# write LaTeX file to Editions/PDF/tex
pandoc_action = 'pandoc -f markdown -o Editions/PDF/tex/{} {}'

def generate_pandoc_action(source, target, env, for_signature):
  # get the name of the target file
    tex_file = target[0].rstr().split(sep='/')[-1]
    return pandoc_action.format(tex_file, source[0])

env = Environment(ENV = os.environ)

markdownToLaTeX = Builder(generator = generate_pandoc_action,
                          suffix='.tex',
                          src_suffix='.md')

env['BUILDERS']['Pandoc'] = markdownToLaTeX

for input in Manuskript['MARKDOWN_FILES']:
    env.Pandoc(input)

I tried several other ways to call pandoc like a custom builder. In any case, the LaTeX files were alway created in directory Book/Manuscript and I had to move or copy them to Editions/PDF/tex.

Book/Editions/PDF/Layout_1/SConscript

This script calls lualatex to generate the PDF of the first layout. The script for the second layout looks accordingly.

Import('PDF')
basename = 'layout_'
pdf = PDF.PDF(basename + '.tex')
PDF.Clean(pdf, basename + '.synctex.gz')
Default(pdf)

Problems

First problem

Book/Editions/PDF/tex/SConscript always processes all markdown files in Book/Manuscript even if none of those changed. I tried to use VariantDir to tell the script that it should look for the targets in Book/Editions/PDF/tex/ but whenever I run scons --debug=explain it says:

scons: building `Manuscript/some_chapter.tex' because it doesn't exist

How do I tell scons to generate the targets in Book/Editions/PDF/tex/ and look for them in that directory when it checks whether a target has to be created?

Second problem

Book/Editions/PDF/SConscript does not work as I expected. My expectation was the scons would

  1. enter directory Book/Editions/PDF/tex to generate the LaTeX files from all changed Markdown files
  2. enter directory Book/Editions/PDF/Layout_1 to generate the PDF for the first layout
  3. enter directory Book/Editions/PDF/Layout_2 to generate the PDF for the second layout

But scons only performs the second and the third step and seems to either ignore the first step completely or to decide that it does not have to perform it. Here is the output of scons --debug=explain:

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `Editions/PDF/Layout_1/book.pdf' is up to date.
scons: `Editions/PDF/Layout_2/book.pdf' is up to date.
scons: done building targets.

scons only calls the Pandoc builder if I delete or uncomment the subsequent lines in Book/Editions/PDF/SConscript. For example like this:

SConscript('tex/SConscript')

# SConscript('Layout_1/SConscript')

# SConscript('Layout_2/SConscript')

I do not understand why scons ignores tex/SConscript when the other two scripts are active? What is the problem?

Thanks in advance

Maral


回答1:


You need to specify a target for builders (or have your emitter do it).. Also all files when represented as strings

Try this and see if that helps.

Book/Editions/PDF/tex/SConscript

import os

Import('Manuskript')

env = Environment(ENV = os.environ)

markdownToLaTeX = Builder('pandoc -f markdown -o $TARGET $SOURCE',
                          suffix='.tex',
                          src_suffix='.md')

env['BUILDERS']['Pandoc'] = markdownToLaTeX

for input in Manuskript['MARKDOWN_FILES']:
    # write LaTeX file to Editions/PDF/tex
    target = '#Editions/PDF/tex/'+File(input).file
    env.Pandoc(target, '#Book/'+input)


来源:https://stackoverflow.com/questions/59146944/using-scons-to-generate-latex-source-files-and-compile-pdf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!