ENH: Added utility to check completeness of installation
[freefoam.git] / data / utilities / foamPNGMathFilter.py.in
blob0d1f3a8a7e99cf21af3d46d7b0f72b2246de4f97
1 #!@PYTHON_EXECUTABLE@
2 #-------------------------------------------------------------------------------
3 # ______ _ ____ __ __
4 # | ____| _| |_ / __ \ /\ | \/ |
5 # | |__ _ __ ___ ___ / \| | | | / \ | \ / |
6 # | __| '__/ _ \/ _ ( (| |) ) | | |/ /\ \ | |\/| |
7 # | | | | | __/ __/\_ _/| |__| / ____ \| | | |
8 # |_| |_| \___|\___| |_| \____/_/ \_\_| |_|
10 # FreeFOAM: The Cross-Platform CFD Toolkit
12 # Copyright (C) 2008-2010 Michael Wild <themiwi@users.sf.net>
13 # Gerber van der Graaf <gerber_graaf@users.sf.net>
14 #-------------------------------------------------------------------------------
15 # License
16 # This file is part of FreeFOAM.
18 # FreeFOAM is free software; you can redistribute it and/or modify it
19 # under the terms of the GNU General Public License as published by the
20 # Free Software Foundation; either version 2 of the License, or (at your
21 # option) any later version.
23 # FreeFOAM is distributed in the hope that it will be useful, but WITHOUT
24 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 # for more details.
28 # You should have received a copy of the GNU General Public License
29 # along with FreeFOAM; if not, write to the Free Software Foundation,
30 # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #-------------------------------------------------------------------------------
33 # Script
34 # foamPNGMathFilter.py
36 #------------------------------------------------------------------------------
38 """Usage:
39 foamPNGMathFilter.py [-D dpi] [-m <mathdir>] [-o <outfile>] [<infile>]
41 Filters the AsciiDoc source file read from standard input (or `<infile>` if
42 specified) and replaces all inline and block maths by PNG images generated
43 using `latex` and `dvipng`. The filtered source is written to standard output
44 or (`<outfile>` if specified). The created images are either written to the
45 `math` directory in the current working directory, or if an output file has
46 been specified, in the directory containing the output file. The `-m` option
47 overrides this choice. The file is named `math_<md5sum>.png`.
49 Options
50 -------
51 -D Specify the resolution of the output images. Refer to dvipng(1)
52 -m Overrides the default output directory for the generated graphics
53 -o <outfile> Specifies that the output should be written to `<outfile>`
54 instead of the standard output
56 """
58 # Suppress warning: "the md5 module is deprecated; use hashlib instead"
59 import warnings
60 warnings.simplefilter('ignore',DeprecationWarning)
62 import md5
63 import os
64 import os.path
65 import re
66 import shutil
67 import subprocess
68 import sys
69 import tempfile
70 sys.path.insert(0, '@FOAM_PYTHON_DIR@')
71 from FreeFOAM.compat import *
73 # argument parsing
74 args = sys.argv[1:]
75 dpiopt = '-D 120'
76 mathdir = None
77 outname = None
78 while len(args):
79 # process options
80 if args[0] == '-D':
81 if len(args) < 2:
82 echo('ERROR: -D option requires argument', file=sys.stderr)
83 sys.exit(1)
84 dpiopt = ' '.join(args[0:2])
85 del args[0:2]
86 continue
87 if args[0] == '-m':
88 if len(args) < 2:
89 echo('ERROR: -m option requires argument', file=sys.stderr)
90 sys.exit(1)
91 mathdir = args[1]
92 del args[0:2]
93 continue
94 if args[0] == '-o':
95 if len(args) < 2:
96 echo('ERROR: -o option requires argument', file=sys.stderr)
97 sys.exit(1)
98 outname = args[1]
99 del args[0:2]
100 continue
101 if args[0] != '-':
102 break
103 else:
104 echo('ERROR: Unknown option "%s"'%args[0], file=sys.stderr)
105 sys.exit(1)
107 if len(args) == 1:
108 infile = open(args[0], 'rt')
109 elif not len(args):
110 infile = sys.stdin
111 else:
112 echo('ERROR: Only one non-option argument allowed', file=sys.stderr)
113 sys.exit(1)
115 if outname:
116 outdir = os.path.dirname(outname)
117 if not os.path.isdir(outdir):
118 os.makedirs(outdir)
119 outfile = open(outname, 'wt')
120 else:
121 outfile = sys.stdout
122 outdir = os.getcwd()
124 if not mathdir:
125 mathdir = os.path.join(outdir, 'math')
127 absmathdir = os.path.isabs(mathdir) and mathdir or os.path.join(pwd, mathdir)
128 #relmathdir = os.path.relpath(mathdir, outdir)
130 LATEXHEAD = r'''
131 \documentclass[12pt]{article}
132 \usepackage[utf8x]{inputenc}
133 \usepackage{amsmath}
134 \usepackage{amsthm}
135 \usepackage{amssymb}
136 \usepackage{amsfonts}
137 \usepackage{bm}
138 \input{@FOAM_DATA_DIR@/asciidoc/dblatex/foam-macros.sty}
139 \pagestyle{empty}
140 \begin{document}
143 LATEXSEP = r'''
144 \clearpage
147 LATEXFOOT = r'''
148 \end{document}
151 regexes = {
152 'inlinemacro': re.compile(
153 r'(?su)[\\]?(?P<name>math):(?P<subslist>\S*?)\[(?P<mathtext>.*?)'
154 + r'(?<!\\)\]'),
155 'blockmacro': re.compile(
156 r'(?su)[\\]?(?P<name>math)::(?P<subslist>\S*?)\[(?P<mathtext>.*?)'
157 + r'(?<!\\)\]'),
158 'block': re.compile(
159 r'(?sum)^\[(?P<name>math)\]\n(?:\+{4,})\n(?P<mathtext>.*?)\n'
160 + r'(?:\+{4,})$'),
163 lines = ''.join(infile.readlines())
165 matches = []
166 for name, regex in regexes.iteritems():
167 for m in regex.finditer(lines):
168 mathtext = m.group('mathtext')
169 h = md5.new(name+dpiopt+mathtext).hexdigest()
170 matches.append({
171 'match' : m,
172 'name' : name,
173 'mathtext' : mathtext,
174 'begin' : m.start(),
175 'end' : m.end(),
176 'hash' : h,
177 'outname' : 'math_%s.png'%h
180 matches.sort(key=lambda x: x['begin'], reverse=True)
182 latextext = ''
183 hashes = {}
184 idx = 1
185 for m in matches:
186 #imname = os.path.join(relmathdir, m['outname'])
187 imname = os.path.join(absmathdir, m['outname'])
188 mathtext = m['mathtext']
189 if m['name'] in 'inlinemacro blockmacro'.split():
190 sep = ':'
191 cleanmathtext = mathtext.replace(r'\]', ']')
192 if m['name'] == 'inlinemacro':
193 cleanmathtext = '$%s$'%cleanmathtext
194 else:
195 sep += ':'
196 replacement = 'math%s%s[%s]'%(sep,imname,mathtext)
197 elif m['name'] == 'block':
198 cleanmathtext = mathtext
199 replacement = '[math,%s]\n++++++\n%s\n++++++'%(imname,mathtext)
201 lines = lines[:m['begin']]+replacement+lines[m['end']:]
202 if not m['hash'] in hashes and not os.path.isfile(
203 os.path.join(absmathdir,m['outname'])):
204 hashes[m['hash']] = {
205 'idx' : idx,
206 'tmpname' : 'math%d.png'%idx,
207 'outname' : m['outname'],
208 'mathtext' : cleanmathtext,
210 idx += 1
211 latextext += cleanmathtext + LATEXSEP
213 if len(latextext):
214 pwd = os.getcwd()
215 tmpdir = None
216 latextext = LATEXHEAD + latextext + LATEXFOOT
217 try:
218 if not os.path.isdir(absmathdir):
219 os.makedirs(absmathdir)
220 tmpdir = tempfile.mkdtemp()
221 os.chdir(tmpdir)
222 open('math.tex', 'wt').write(latextext)
223 subprocess.check_call([
224 '@LATEX_EXECUTABLE@',
225 '--interaction=nonstopmode', 'math.tex'],
226 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
227 subprocess.check_call([
228 '@DVIPNG_EXECUTABLE@',
229 '-T', 'tight', '-z9', dpiopt, 'math.dvi'],
230 stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
231 for d in hashes.itervalues():
232 os.rename(d['tmpname'], os.path.join(absmathdir, d['outname']))
233 finally:
234 os.chdir(pwd)
235 if tmpdir is not None:
236 shutil.rmtree(tmpdir)
238 outfile.write(lines)
240 # ------------------------- vim: set sw=3 sts=3 et: --------------- end-of-file