summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Rackham <srackham@methods.co.nz>2012-03-01 12:55:30 +1300
committerStuart Rackham <srackham@methods.co.nz>2012-03-01 12:55:30 +1300
commit61975c3b86dd74329ad645ab6417a157570941e9 (patch)
treef3b59c99c1120fbf43a0ebd18b005a7840d8074a
parent61f951e338a6425298aa3ae4c5a46eb2a77ffa89 (diff)
downloadasciidoc-61975c3b86dd74329ad645ab6417a157570941e9.tar.gz
- FIXED: All Python filters are executed with the same Python
interpreter that executes the asciidoc parent (previously filters were hardwired to execute the 'python' interpreter). This prevents Python mixups (see http://groups.google.com/group/asciidoc/browse_thread/thread/14e8fcb289a135b/3af3b4e57b827c78?lnk=gst&q=archlinux#3af3b4e57b827c78 - FIXED: Leaky file handles in a2x and music and latex filters which created incompatibility problems for Jython. See http://stackoverflow.com/questions/1832528/is-close-necessary-when-using-iterator-on-a-python-file-object - FIXED: Jython AsciiDoc API (asciidocapi.py) StringIO incompatibility. There is still an outstanding Jython related asciidocapi bug that occurs when using a cStringIO output file: Jython throws an error when non-ascii characters are found in included CSS or JavaScript files (e.g. slidy.css), this only happens if you are executing asciidoc via the asciidocapi and you are using a StringIO output file (as opposed to a real file).
-rwxr-xr-xa2x.py61
-rw-r--r--asciidoc.conf4
-rwxr-xr-xasciidoc.py39
-rw-r--r--doc/asciidoc.txt1
-rwxr-xr-xfilters/latex/latex2png.py22
-rwxr-xr-xfilters/music/music2png.py28
-rw-r--r--html5.conf10
-rwxr-xr-xtests/testasciidoc.py9
-rw-r--r--xhtml11-quirks.conf2
-rw-r--r--xhtml11.conf10
10 files changed, 129 insertions, 57 deletions
diff --git a/a2x.py b/a2x.py
index 83cfbec..498d729 100755
--- a/a2x.py
+++ b/a2x.py
@@ -144,6 +144,20 @@ def find_executable(file_name):
result = _find_executable(file_name)
return result
+def write_file(filename, data, mode='w'):
+ f = open(filename, mode)
+ try:
+ f.write(data)
+ finally:
+ f.close()
+
+def read_file(filename, mode='r'):
+ f = open(filename, mode)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
def shell_cd(path):
verbose('chdir %s' % path)
if not OPTIONS.dry_run:
@@ -236,19 +250,20 @@ def find_resources(files, tagname, attrname, filter=None):
if isinstance(files, str):
files = [files]
result = []
- for f in files:
- verbose('finding resources in: %s' % f)
+ for filename in files:
+ verbose('finding resources in: %s' % filename)
if OPTIONS.dry_run:
continue
parser = FindResources()
# HTMLParser has problems with non-ASCII strings.
# See http://bugs.python.org/issue3932
- mo = re.search(r'^<\?xml.* encoding="(.*?)"', open(f).readline())
+ contents = read_file(filename)
+ mo = re.search(r'\A<\?xml.* encoding="(.*?)"', contents)
if mo:
encoding = mo.group(1)
- parser.feed(open(f).read().decode(encoding))
+ parser.feed(contents.decode(encoding))
else:
- parser.feed(open(f).read())
+ parser.feed(contents)
parser.close()
result = list(set(result)) # Drop duplicate values.
result.sort()
@@ -259,12 +274,12 @@ def copy_files(files, src_dir, dst_dir):
'''
Copy list of relative file names from src_dir to dst_dir.
'''
- for f in files:
- f = os.path.normpath(f)
- if os.path.isabs(f):
+ for filename in files:
+ filename = os.path.normpath(filename)
+ if os.path.isabs(filename):
continue
- src = os.path.join(src_dir, f)
- dst = os.path.join(dst_dir, f)
+ src = os.path.join(src_dir, filename)
+ dst = os.path.join(dst_dir, filename)
if not os.path.exists(dst):
if not os.path.isfile(src):
warning('missing file: %s' % src)
@@ -323,10 +338,14 @@ def get_source_options(asciidoc_file):
result = []
if os.path.isfile(asciidoc_file):
options = ''
- for line in open(asciidoc_file):
- mo = re.search(r'^//\s*a2x:', line)
- if mo:
- options += ' ' + line[mo.end():].strip()
+ f = open(asciidoc_file)
+ try:
+ for line in f:
+ mo = re.search(r'^//\s*a2x:', line)
+ if mo:
+ options += ' ' + line[mo.end():].strip()
+ finally:
+ f.close()
parse_options()
return result
@@ -435,8 +454,12 @@ class A2X(AttrDict):
if self.resource_manifest:
if not os.path.isfile(self.resource_manifest):
die('missing --resource-manifest: %s' % self.resource_manifest)
- for r in open(self.resource_manifest):
- self.resources.append(r.strip())
+ f = open(self.resource_manifest)
+ try:
+ for r in f:
+ self.resources.append(r.strip())
+ finally:
+ f.close()
for r in self.resources:
r = os.path.expanduser(r)
r = os.path.expandvars(r)
@@ -710,7 +733,7 @@ class A2X(AttrDict):
f = os.path.normpath(f)
if f not in ['content.opf']:
resource_files.append(f)
- opf = xml.dom.minidom.parseString(open(opf_file).read())
+ opf = xml.dom.minidom.parseString(read_file(opf_file))
manifest_files = []
manifest = opf.getElementsByTagName('manifest')[0]
for el in manifest.getElementsByTagName('item'):
@@ -731,7 +754,7 @@ class A2X(AttrDict):
item.setAttribute('media-type', mimetype)
manifest.appendChild(item)
if count > 0:
- open(opf_file, 'w').write(opf.toxml())
+ write_file(opf_file, opf.toxml())
def to_epub(self):
self.to_docbook()
@@ -763,7 +786,7 @@ class A2X(AttrDict):
try:
# Create and add uncompressed mimetype file.
verbose('archiving: mimetype')
- open('mimetype','w').write('application/epub+zip')
+ write_file('mimetype', 'application/epub+zip')
zip.write('mimetype', compress_type=zipfile.ZIP_STORED)
# Compress all remaining files.
for (p,dirs,files) in os.walk('.'):
diff --git a/asciidoc.conf b/asciidoc.conf
index 45a3be2..03c0934 100644
--- a/asciidoc.conf
+++ b/asciidoc.conf
@@ -519,7 +519,7 @@ emphasis-style=tags="emphasis"
strong-style=tags="strong"
monospaced-style=tags="monospaced"
header-style=tags="header"
-asciidoc-style=tags="asciidoc",subs=(),filter='python "{asciidoc-file}" -b {backend} {asciidoc-args}{lang? -a "lang={lang}@"}{icons? -a icons -a "iconsdir={iconsdir}"}{imagesdir? -a "imagesdir={imagesdir}"}{data-uri? -a data-uri} -a "indir={indir}"{trace? -a "trace={trace}"}{blockname? -a "blockname={blockname}"} -s -'
+asciidoc-style=tags="asciidoc",subs=(),filter='"{python}" "{asciidoc-file}" -b {backend} {asciidoc-args}{lang? -a "lang={lang}@"}{icons? -a icons -a "iconsdir={iconsdir}"}{imagesdir? -a "imagesdir={imagesdir}"}{data-uri? -a data-uri} -a "indir={indir}"{trace? -a "trace={trace}"}{blockname? -a "blockname={blockname}"} -s -'
[tabledef-nested]
# Same as [tabledef-default] but with different delimiter and separator.
@@ -533,7 +533,7 @@ emphasis-style=tags="emphasis"
strong-style=tags="strong"
monospaced-style=tags="monospaced"
header-style=tags="header"
-asciidoc-style=tags="asciidoc",subs=(),filter='python "{asciidoc-file}" -b {backend} {asciidoc-args}{lang? -a "lang={lang}@"}{icons? -a icons -a "iconsdir={iconsdir}"}{imagesdir? -a "imagesdir={imagesdir}"}{data-uri? -a data-uri} -a "indir={indir}"{trace? -a "trace={trace}"}{blockname? -a "blockname={blockname}"} -s -'
+asciidoc-style=tags="asciidoc",subs=(),filter='"{python}" "{asciidoc-file}" -b {backend} {asciidoc-args}{lang? -a "lang={lang}@"}{icons? -a icons -a "iconsdir={iconsdir}"}{imagesdir? -a "imagesdir={imagesdir}"}{data-uri? -a data-uri} -a "indir={indir}"{trace? -a "trace={trace}"}{blockname? -a "blockname={blockname}"} -s -'
#----------------------------------------
# Common block and macro markup templates
diff --git a/asciidoc.py b/asciidoc.py
index 953cae0..1b516be 100755
--- a/asciidoc.py
+++ b/asciidoc.py
@@ -799,14 +799,13 @@ def filter_lines(filter_cmd, lines, attrs={}):
message.warning('filter not found: %s' % cmd)
if found:
filter_cmd = '"' + found + '"' + mo.group('tail')
- if sys.platform == 'win32':
- # Windows doesn't like running scripts directly so explicitly
- # specify interpreter.
- if found:
- if cmd.endswith('.py'):
- filter_cmd = 'python ' + filter_cmd
- elif cmd.endswith('.rb'):
- filter_cmd = 'ruby ' + filter_cmd
+ if found:
+ if cmd.endswith('.py'):
+ filter_cmd = '"%s" %s' % (document.attributes['python'],
+ filter_cmd)
+ elif cmd.endswith('.rb'):
+ filter_cmd = 'ruby ' + filter_cmd
+
message.verbose('filtering: ' + filter_cmd)
try:
p = subprocess.Popen(filter_cmd, shell=True,
@@ -885,7 +884,11 @@ def system(name, args, is_macro=False, attrs=None):
message.warning('%s: non-zero exit status' % syntax)
try:
if os.path.isfile(tmp):
- lines = [s.rstrip() for s in open(tmp)]
+ f = open(tmp)
+ try:
+ lines = [s.rstrip() for s in f]
+ finally:
+ f.close()
else:
lines = []
except Exception:
@@ -954,7 +957,11 @@ def system(name, args, is_macro=False, attrs=None):
elif not is_safe_file(args):
message.unsafe(syntax)
else:
- result = [s.rstrip() for s in open(args)]
+ f = open(args)
+ try:
+ result = [s.rstrip() for s in f]
+ finally:
+ f.close()
if result:
result = subs_attrs(result)
result = separator.join(result)
@@ -2745,8 +2752,7 @@ class List(AbstractBlock):
AbstractBlock.__init__(self)
self.CONF_ENTRIES += ('type','tags')
self.PARAM_NAMES += ('tags',)
-#ZZZ listdef?
- # tabledef conf file parameters.
+ # listdef conf file parameters.
self.type=None
self.tags=None # Name of listtags-<tags> conf section.
# Calculated parameters.
@@ -4157,8 +4163,12 @@ class Reader1:
message.verbose('include1: ' + fname, linenos=False)
# Store the include file in memory for later
# retrieval by the {include1:} system attribute.
- config.include1[fname] = [
- s.rstrip() for s in open(fname)]
+ f = open(fname)
+ try:
+ config.include1[fname] = [
+ s.rstrip() for s in f]
+ finally:
+ f.close()
return '{include1:%s}' % fname
else:
# This is a configuration dump, just pass the macro
@@ -5880,6 +5890,7 @@ def asciidoc(backend, doctype, confiles, infile, outfile, options):
else:
raise EAsciiDoc,'missing configuration file: %s' % f
try:
+ document.attributes['python'] = sys.executable
for f in config.filters:
if not config.find_config_dir('filters', f):
raise EAsciiDoc,'missing filter: %s' % f
diff --git a/doc/asciidoc.txt b/doc/asciidoc.txt
index dadd961..20d02d9 100644
--- a/doc/asciidoc.txt
+++ b/doc/asciidoc.txt
@@ -4598,6 +4598,7 @@ predefined intrinsic attributes:
{notitle} do not display the document title
{outdir} document output directory name (note 2)
{outfile} output file name (note 2)
+ {python} the full path name of the Python interpreter executable
{rdquo} Right double quote character (note 7)
{reftext} running block xreflabel generated by BlockId elements
{revdate} document revision date (from document header)
diff --git a/filters/latex/latex2png.py b/filters/latex/latex2png.py
index 65945a6..3cae7c9 100755
--- a/filters/latex/latex2png.py
+++ b/filters/latex/latex2png.py
@@ -90,6 +90,20 @@ def print_verbose(line):
if verbose:
print_stderr(line)
+def write_file(filename, data, mode='w'):
+ f = open(filename, mode)
+ try:
+ f.write(data)
+ finally:
+ f.close()
+
+def read_file(filename, mode='r'):
+ f = open(filename, mode)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
def run(cmd):
global verbose
if verbose:
@@ -117,12 +131,12 @@ def latex2png(infile, outfile, dpi, modified):
checksum = md5.new(tex).digest()
md5_file = os.path.splitext(outfile)[0] + '.md5'
if os.path.isfile(md5_file) and os.path.isfile(outfile) and \
- checksum == open(md5_file,'rb').read():
+ checksum == read_file(md5_file,'rb'):
skip = True
else:
if not os.path.isfile(infile):
raise EApp, 'input file does not exist: %s' % infile
- tex = open(infile).read()
+ tex = read_file(infile)
if modified and os.path.isfile(outfile) and \
os.path.getmtime(infile) <= os.path.getmtime(outfile):
skip = True
@@ -131,7 +145,7 @@ def latex2png(infile, outfile, dpi, modified):
return
tex = '%s\n%s\n%s\n' % (TEX_HEADER, tex.strip(), TEX_FOOTER)
print_verbose('tex:\n%s' % tex)
- open(texfile, 'w').write(tex)
+ write_file(texfile, tex)
saved_pwd = os.getcwd()
os.chdir(outdir)
try:
@@ -152,7 +166,7 @@ def latex2png(infile, outfile, dpi, modified):
os.remove(f)
if 'md5_file' in locals():
print_verbose('writing: %s' % md5_file)
- open(md5_file,'wb').write(checksum)
+ write_file(md5_file, checksum, 'wb')
def usage(msg=''):
if msg:
diff --git a/filters/music/music2png.py b/filters/music/music2png.py
index 9f1cda0..011cd1d 100755
--- a/filters/music/music2png.py
+++ b/filters/music/music2png.py
@@ -70,6 +70,20 @@ def print_verbose(line):
if verbose:
print_stderr(line)
+def write_file(filename, data, mode='w'):
+ f = open(filename, mode)
+ try:
+ f.write(data)
+ finally:
+ f.close()
+
+def read_file(filename, mode='r'):
+ f = open(filename, mode)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
def run(cmd):
global verbose
if not verbose:
@@ -90,19 +104,20 @@ def music2png(format, infile, outfile, modified):
if infile == '-':
source = sys.stdin.read()
checksum = md5.new(source).digest()
- f = os.path.splitext(outfile)[0] + '.md5'
+ filename = os.path.splitext(outfile)[0] + '.md5'
if modified:
- if os.path.isfile(f) and os.path.isfile(outfile) and \
- checksum == open(f,'rb').read():
+ if os.path.isfile(filename) and os.path.isfile(outfile) and \
+ checksum == read_file(filename,'rb'):
skip = True
- open(f,'wb').write(checksum)
+ else:
+ write_file(filename, checksum, 'wb')
else:
if not os.path.isfile(infile):
raise EApp, 'input file does not exist: %s' % infile
if modified and os.path.isfile(outfile) and \
os.path.getmtime(infile) <= os.path.getmtime(outfile):
skip = True
- source = open(infile).read()
+ source = read_file(infile)
if skip:
print_verbose('skipped: no change: %s' % outfile)
return
@@ -111,7 +126,8 @@ def music2png(format, infile, outfile, modified):
format = 'ly'
else:
format = 'abc'
- open('%s.%s' % (basefile,format), 'w').write(source) # Temp source file.
+ # Write temporary source file.
+ write_file('%s.%s' % (basefile,format), source)
abc = basefile + '.abc'
ly = basefile + '.ly'
png = basefile + '.png'
diff --git a/html5.conf b/html5.conf
index daeef7d..b463036 100644
--- a/html5.conf
+++ b/html5.conf
@@ -81,7 +81,7 @@ latexmath-style=template="latexmathblock",subs=()
<a class="image" href="{link}">
{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"}>
{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"} src="data:image/{eval:os.path.splitext(r'{target}')[1][1:]};base64,
-{data-uri#}{sys3:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}">
+{data-uri#}{sys3:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}">
{link#}</a>
</span>
@@ -91,7 +91,7 @@ latexmath-style=template="latexmathblock",subs=()
<a class="image" href="{link}">
{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}>
{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} src="data:image/{eval:os.path.splitext(r'{target}')[1][1:]};base64,
-{data-uri#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}">
+{data-uri#}{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}">
{link#}</a>
</div>
<div class="title">{caption={figure-caption} {counter:figure-number}. }{title}</div>
@@ -150,7 +150,7 @@ ifndef::data-uri[]
endif::data-uri[]
ifdef::data-uri[]
<img alt="{index}" src="data:image/png;base64,
-{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{index}.png}")}"}">
+{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{index}.png}")}"}">
endif::data-uri[]
endif::icons[]
@@ -213,7 +213,7 @@ ifndef::data-uri[]
item=<tr><td><img src="{iconsdir}/callouts/{listindex}.png" alt="{listindex}"></td><td>|</td></tr>
endif::data-uri[]
ifdef::data-uri[]
-item=<tr><td><img alt="{listindex}" src="data:image/png;base64, {sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{listindex}.png}")}"}"></td><td>|</td></tr>
+item=<tr><td><img alt="{listindex}" src="data:image/png;base64, {sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{listindex}.png}")}"}"></td><td>|</td></tr>
endif::data-uri[]
text=|
endif::icons[]
@@ -378,7 +378,7 @@ template::[quoteblock]
<td class="icon">
{data-uri%}{icons#}<img src="{icon={iconsdir}/{name}.png}" alt="{caption}">
{data-uri#}{icons#}<img alt="{caption}" src="data:image/png;base64,
-{data-uri#}{icons#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/{name}.png}")}"}">
+{data-uri#}{icons#}{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/{name}.png}")}"}">
{icons%}<div class="title">{caption}</div>
</td>
<td class="content">
diff --git a/tests/testasciidoc.py b/tests/testasciidoc.py
index aa185f1..679ad35 100755
--- a/tests/testasciidoc.py
+++ b/tests/testasciidoc.py
@@ -21,7 +21,14 @@ __version__ = '0.1.1'
__copyright__ = 'Copyright (C) 2009 Stuart Rackham'
-import os, sys, re, StringIO, difflib
+import os, sys, re, difflib
+
+if sys.platform[:4] == 'java':
+ # Jython cStringIO is more compatible with CPython StringIO.
+ import cStringIO as StringIO
+else:
+ import StringIO
+
import asciidocapi
diff --git a/xhtml11-quirks.conf b/xhtml11-quirks.conf
index c20376e..7c13366 100644
--- a/xhtml11-quirks.conf
+++ b/xhtml11-quirks.conf
@@ -10,7 +10,7 @@
<a class="image" href="{link}">
{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} />
{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} src="data:image/{eval:os.path.splitext(r'{target}')[1][1:]};base64,
-{data-uri#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}" />
+{data-uri#}{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}" />
{link#}</a>
</div>
<div class="image-title">{caption={figure-caption} {counter:figure-number}: }{title}</div>
diff --git a/xhtml11.conf b/xhtml11.conf
index ce5fa19..c1ebb91 100644
--- a/xhtml11.conf
+++ b/xhtml11.conf
@@ -80,7 +80,7 @@ latexmath-style=template="latexmathblock",subs=()
<a class="image" href="{link}">
{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"} />
{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"} src="data:image/{eval:os.path.splitext(r'{target}')[1][1:]};base64,
-{data-uri#}{sys3:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}" />
+{data-uri#}{sys3:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}" />
{link#}</a>
</span>
@@ -90,7 +90,7 @@ latexmath-style=template="latexmathblock",subs=()
<a class="image" href="{link}">
{data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} />
{data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} src="data:image/{eval:os.path.splitext(r'{target}')[1][1:]};base64,
-{data-uri#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}" />
+{data-uri#}{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{imagesdir=}",r"{target}")}"}" />
{link#}</a>
</div>
<div class="title">{caption={figure-caption} {counter:figure-number}. }{title}</div>
@@ -131,7 +131,7 @@ ifndef::data-uri[]
endif::data-uri[]
ifdef::data-uri[]
<img alt="{index}" src="data:image/png;base64,
-{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{index}.png}")}"}" />
+{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{index}.png}")}"}" />
endif::data-uri[]
endif::icons[]
@@ -194,7 +194,7 @@ ifndef::data-uri[]
item=<tr><td><img src="{iconsdir}/callouts/{listindex}.png" alt="{listindex}" /></td><td>|</td></tr>
endif::data-uri[]
ifdef::data-uri[]
-item=<tr><td><img alt="{listindex}" src="data:image/png;base64, {sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{listindex}.png}")}"}" /></td><td>|</td></tr>
+item=<tr><td><img alt="{listindex}" src="data:image/png;base64, {sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/callouts/{listindex}.png}")}"}" /></td><td>|</td></tr>
endif::data-uri[]
text=|
endif::icons[]
@@ -359,7 +359,7 @@ template::[quoteblock]
<td class="icon">
{data-uri%}{icons#}<img src="{icon={iconsdir}/{name}.png}" alt="{caption}" />
{data-uri#}{icons#}<img alt="{caption}" src="data:image/png;base64,
-{data-uri#}{icons#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/{name}.png}")}"}" />
+{data-uri#}{icons#}{sys:"{python}" -u -c "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join(r"{indir={outdir}}",r"{icon={iconsdir}/{name}.png}")}"}" />
{icons%}<div class="title">{caption}</div>
</td>
<td class="content">