1#!/usr/bin/env python3
2# -*- coding: utf8 -*-
3# $Id: rst2pdf.py 5560 2008-05-20 13:00:31Z milde $
4
5# rst2pdf.py
6# ==========
7# ::
8
9"""
10A front end to the Docutils Publisher, producing PDF.
11
12Produces a latex file with the "latex" writer and converts
13it to PDF with the "rubber" building system for LaTeX documents.
14"""
15
16# ``rst2pdf.py`` is a PDF front-end for docutils that is compatible
17# with the ``rst2*.py`` front ends of the docutils_ suite.
18# It enables the generation of PDF documents from a reStructuredText source in
19# one step.
20#
21# It is implemented as a combination of docutils' ``rst2latex.py``
22# by David Goodger and rubber_ by Emmanuel Beffara.
23#
24# Copyright: © 2008 Günter Milde
25#            Licensed under the `Apache License, Version 2.0`_
26#            Provided WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND
27#
28# Changelog
29# ---------
30#
31# =====  ==========  =======================================================
32# 0.1    2008-05-20  first attempt
33# =====  ==========  =======================================================
34#
35# ::
36
37_version = 0.1
38
39
40# Imports
41# =======
42# ::
43
44#from pprint import pprint # for debugging
45import os
46
47# Docutils::
48
49try:
50    import locale
51    locale.setlocale(locale.LC_ALL, '')
52except:
53    pass
54
55from docutils.core import default_usage, default_description, Publisher
56
57# Rubber (rubber is not installed in the PYTHONPATH)::
58
59import sys
60sys.path.append("/usr/share/rubber")
61
62try:
63    import rubber.cmdline
64    import rubber.cmd_pipe
65except ImportError:
66    print("Cannot find the rubber modules, rubber not installed correctly.")
67    sys.exit(1)
68
69# Generate the latex file
70# =======================
71#
72# We need to replace the <destination> by a intermediate latex file path.
73# The most reliable way to get the value of <destination> is to
74# call the Publisher "by hand", and query its settings.
75#
76# Modeled on the publish_cmdline() function of docutils.core
77#
78# Default values::
79
80reader = None
81reader_name = 'standalone'
82parser = None
83parser_name = 'restructuredtext'
84writer = None
85writer_name = 'pseudoxml'
86settings = None
87settings_spec = None
88settings_overrides = None
89config_section = None
90enable_exit_status = 1
91argv = None
92usage = default_usage
93description = default_description
94
95# Argument values given to publish_cmdline() in rst2latex.py::
96
97description = ('Generates PDF documents from standalone reStructuredText '
98               'sources using the "latex" Writer and the "rubber" '
99               'building system for LaTeX documents.  ' + default_description)
100writer_name = 'latex'
101
102# Set up the publisher::
103
104pub = Publisher(reader, parser, writer, settings=settings)
105pub.set_components(reader_name, parser_name, writer_name)
106
107# Parse the command line args
108# (Publisher.publish does this in a try statement)::
109
110pub.process_command_line(argv, usage, description, settings_spec,
111                         config_section, **(settings_overrides or {}))
112# pprint(pub.settings.__dict__)
113
114# Get source and destination path::
115
116source = pub.settings._source
117destination = pub.settings._destination
118# print source, destination
119
120# Generate names for the temporary files and set ``destination`` to temporary
121# latex file:
122#
123# make_name() from rubber.cmd_pipe checks that no existing file is
124# overwritten. If we are going to support rubbers ``--inplace`` and ``--into``
125# options, the chdir() must occure before this point to have the check in the
126# right directory. ::
127
128tmppath = rubber.cmd_pipe.make_name()
129texpath = tmppath + ".tex"
130pdfpath = tmppath + ".pdf"
131
132pub.settings._destination = texpath
133
134# Now do the rst -> latex conversion::
135
136pub.publish(argv, usage, description, settings_spec, settings_overrides,
137            config_section=config_section, enable_exit_status=enable_exit_status)
138
139
140# Generating the PDF document with rubber
141# =======================================
142#
143#
144# rubber_ has no documentet API for programmatic use. We simualate a command
145# line call and pass command line arguments (see man: rubber-pipe) in an array::
146
147rubber_argv = ["--pdf",    # use pdflatex to produce PDF
148               "--short",   # Display LaTeX’s error messages one error per line.
149               texpath
150               ]
151
152# Get a TeX processing class instance and do the latex->pdf conversion::
153
154tex_processor = rubber.cmdline.Main()
155tex_processor(rubber_argv)
156
157# Rename output to _destination or print to stdout::
158
159if destination is None:
160    with open(pdfpath) as pdffile:
161        print(pdffile.read())
162else:
163    os.rename(pdfpath, destination)
164
165# Clean up (remove intermediate files)
166#
167# ::
168
169tex_processor(["--clean"] + rubber_argv)
170os.remove(texpath)
171
172
173# .. References
174#
175# .. _docutils: http://docutils.sourceforge.net/
176# .. _rubber: http://www.pps.jussieu.fr/~beffara/soft/rubber/
177# .. _Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
178#
179