3
# Modify reStructuredText 'image' directives by adding a percentage 'width'
4
# attribute so that the images are scaled to fit on the page when the document
5
# is renderd to LaTeX, and add a center alignment.
7
# Also convert references to PNG images to use PDF files generated from SVG
10
# Without the explicit size specification, the images are ridiculously huge and
11
# most extend far off the right side of the page.
13
# Copyright (C) 2009 Colin D Bennett
15
# This program is free software; you can redistribute it and/or modify
16
# it under the terms of the GNU General Public License as published by
17
# the Free Software Foundation; either version 2 of the License, or
18
# (at your option) any later version.
20
# This program is distributed in the hope that it will be useful,
21
# but WITHOUT ANY WARRANTY; without even the implied warranty of
22
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
# GNU General Public License for more details.
25
# You should have received a copy of the GNU General Public License
26
# along with this program; if not, write to the Free Software
27
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
34
from subprocess import call
38
IMAGE_DIRECTIVE_PATTERN = re.compile(ur'^..\s+image::\s+(.*)\s+$')
39
DIRECTIVE_ELEMENT_PATTERN = re.compile(ur'^\s+:[^:]+:\s+')
41
class Converter(object):
42
def __init__(self, srcdir, destdir):
44
self.destdir = destdir
46
# Process .txt files in sourcedir, generating output in destdir.
47
def process_files(self):
48
for filename in os.listdir(self.srcdir):
49
# Process all text files in the current directory.
50
if filename.endswith('.txt'):
51
inpath = os.path.join(self.srcdir, filename)
52
outpath = os.path.join(self.destdir, filename)
53
self._process_file(inpath, outpath)
55
def _process_file(self, inpath, outpath):
56
infile = open(inpath, 'r')
57
outfile = open(outpath, 'w')
60
if foundimg and DIRECTIVE_ELEMENT_PATTERN.match(line) is None:
62
print('Fixing image directive')
63
# The preceding image directive has no elements.
64
outfile.write(' :width: 85%\n')
65
outfile.write(' :align: center\n')
68
image_fixer = ImageFixer(self.srcdir, self.destdir)
69
image_fixer_lambda = lambda match: image_fixer.substitute_pdf_image(match)
70
line = IMAGE_DIRECTIVE_PATTERN.sub(image_fixer_lambda, line)
71
directive_match = IMAGE_DIRECTIVE_PATTERN.match(line)
72
if directive_match is not None:
73
image_src = directive_match.group(1)
75
print('Image ' + image_src + ' in ' + filename
76
+ ': ' + line.strip())
83
class ImageFixer(object):
84
def __init__(self, srcdir, destdir):
86
self.destdir = destdir
88
def substitute_pdf_image(self, match):
89
prefix = match.string[:match.start(1)]
90
newname = self.convert_image_to_pdf(match.group(1))
91
suffix = match.string[match.end(1):]
92
return prefix + newname + suffix
94
def replace_extension(self, path, newext):
95
if path.endswith(newext):
96
raise Exception("File '" + path + "' already has extension '"
102
return path[:dot] + newext
104
# Possibly use an SVG alternative to a PNG image, converting the SVG image
105
# to a PDF first. Whether or not a conversion is made, the image to use is
106
# written to the destination directory and the path to use in the RST #
107
# source is returned.
108
def convert_image_to_pdf(self, filename):
109
# Make the directory structure for the image in the destination dir.
110
image_dirname = os.path.dirname(filename)
112
image_dirpath = os.path.join(self.destdir, image_dirname)
113
if not os.path.exists(image_dirpath):
114
os.mkdir(image_dirpath)
116
# Decide how to handle this image.
117
if filename.endswith('.png'):
118
# See if there is a vector alternative.
119
svgfile = self.replace_extension(filename, '.svg')
120
svgpath = os.path.join(self.srcdir, svgfile)
121
if os.path.exists(svgpath):
123
print('Using SVG alternative to PNG')
124
# Convert SVG to PDF with Inkscape.
125
pdffile = self.replace_extension(filename, '.pdf')
126
pdfpath = os.path.join(self.destdir, pdffile)
127
if call(['/usr/bin/inkscape',
128
'--export-pdf=' + pdfpath, svgpath]) != 0:
129
raise Exception("Conversion to pdf failed")
132
# No conversion, just copy the file.
133
srcpath = os.path.join(self.srcdir, filename)
134
destpath = os.path.join(self.destdir, filename)
135
shutil.copyfile(srcpath, destpath)
138
if __name__ == '__main__':
139
IN_DIR_OPT = '--in-dir='
140
OUT_DIR_OPT = '--out-dir='
145
print('Usage: ' + argv[0] + ' ' + IN_DIR_OPT + 'INDIR '
146
+ OUT_DIR_OPT + 'OUTDIR')
148
print('This will convert all .txt files in INDIR into file in OUTDIR')
149
print('while adjusting the use of images and possibly converting SVG')
150
print('images to PDF files so LaTeX can include them.')
154
if arg == '-v' or arg == '--verbose':
156
elif arg.startswith(IN_DIR_OPT):
157
srcdir = arg[len(IN_DIR_OPT):]
158
elif arg.startswith(OUT_DIR_OPT):
159
destdir = arg[len(OUT_DIR_OPT):]
161
print('Invalid argument ' + arg)
164
if srcdir is None or destdir is None:
165
print('Please specify the ' + IN_DIR_OPT + ' and '
166
+ OUT_DIR_OPT + ' options.')
169
if not os.path.exists(destdir):
171
Converter(srcdir, destdir).process_files()
173
# vim: set ts=4 sw=4 et: