From 22cf37b962326524cf40f420a16cd6c55c12f9e2 Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Fri, 11 Sep 2015 20:21:26 +0200 Subject: [PATCH 01/10] add filter to execute IM commands in code blocks CodeBlocks need to be marked with the '.magick' class like so: ~~~{.magick} Otherwise the codeblock will be ignored. --- _filters/execute_magick.py | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 _filters/execute_magick.py diff --git a/_filters/execute_magick.py b/_filters/execute_magick.py new file mode 100644 index 0000000..c28fb8f --- /dev/null +++ b/_filters/execute_magick.py @@ -0,0 +1,76 @@ +#!/bin/env python + +""" +Pandoc filter to run all imagemagick code in code blocks +""" + +import os +import sys +import hashlib +from pandocfilters import toJSONFilter, Image, CodeBlock, Para +from subprocess import Popen, PIPE + +imagedir = '_images' + +def sha1(x): + return hashlib.sha1(x.encode(sys.getfilesystemencoding())).hexdigest() + +def execute(code): + sys.stderr.write('-'*100 + '\n') + code = remove_slash(code) + for line in code: + sys.stderr.write(line + '\n') + p = Popen(line, close_fds=True, stdout=PIPE, stderr=PIPE, shell=True) + out, err = p.communicate() + if err: + sys.stderr.write(err + '\n') + else: + sys.stderr.write(out + '\n') + +def remove_slash(text): + """ + Joins lines, removing line-extending Backslashes ('\') from the text code + :returns: list of strings + """ + retval = [] + cummulative_line = '' + for line in text.split('\n'): + line = line.strip() + if line.endswith('\\'): + line = line.strip('\\') + cummulative_line += line + else: + cummulative_line += line +# execute(cummulative_line) + retval.append(cummulative_line) + cummulative_line = '' + return retval + +def magick(key, value, format, meta): + if key == 'CodeBlock': + [[ident, classes, keyvals], code] = value + sys.stderr.write('>>>' + str(ident) + '\n') + if 'magick' in classes: + outfile = os.path.join(imagedir, sha1(code)) + if format == "latex": + filetype = "pdf" + else: + filetype = "png" + src = outfile + '.' + filetype + if not os.path.isdir(imagedir): + try: + os.mkdir(imagedir) + sys.stderr.write('Created directory %s' % imagedir) + except OSError: + sys.stderr.write('Could not create directory %s' % imagedir) + return +# sys.stderr.write("classes: " + ','.join(classes) + '\n') +# sys.stderr.write(str(zip(keyvals)) + '\n') + +# sys.stderr.write('Created image ' + src + '\n') + execute(code) + return [CodeBlock(("", [], []), code), Para([Image([], [src, ""])])] + + +if __name__ == "__main__": + toJSONFilter(magick) From 35e828f3be703621e621f35d888c8260b01eaad8 Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Fri, 11 Sep 2015 20:23:02 +0200 Subject: [PATCH 02/10] add .magick class to example file (antialising/index.md) --- antialiasing/index.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/antialiasing/index.md b/antialiasing/index.md index f5851e1..672c88c 100644 --- a/antialiasing/index.md +++ b/antialiasing/index.md @@ -13,7 +13,7 @@ It draws them with an operation call "anti-aliasing". To demonstrate, I'll draw an image on a transparent background, then magnify a small part of the image so you can see what is happening. -~~~ +~~~{.magick} convert -size 80x80 xc:none \ -fill white -draw "circle 40,40 15,20" \ -fill black -draw "line 5,30 78,2" drawn.png @@ -33,7 +33,7 @@ If no anti-aliasing was done, then the edges of all the drawn objects would have Here we draw the image again but this time we asked IM to turn off its automatic anti-aliasing operations, using "`+antialias`". -~~~ +~~~{.magick} convert -size 80x80 xc:none +antialias \ -fill white -draw "circle 40,40 15,20" \ -fill black -draw "line 5,30 78,2" drawn_jaggies.png @@ -96,7 +96,7 @@ Another alternative to drawing circles, which we'll look at in a moment, is to u For example, the normal IM way of drawing a circle produces a lot of grey anti-aliasing colors to give the circle a smooth appearance. -~~~ +~~~{.magick} convert -size 15x15 xc: -fill none -stroke black \ -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_antialiased.gif @@ -106,7 +106,7 @@ convert -size 15x15 xc: -fill none -stroke black \ Simply turning of anti-aliasing however produces circles and lines that are not a nice thin 'bitmap' line. -~~~ +~~~{.magick} convert -size 15x15 xc: -fill none -stroke black +antialias \ -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_aliased.gif @@ -116,7 +116,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ What you need to do is also adjust the "`-strokewidth`" , which defaults to 1 pixel wide, to something smaller, such as 0.5 pixels wide. -~~~ +~~~{.magick} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.5 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_thin_stroke.gif @@ -127,7 +127,7 @@ Better, but not quite right. You can also make the stroke width too small, especially with odd sized radii. -~~~ +~~~{.magick} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_zero_stroke.gif @@ -137,7 +137,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ And here is a good solution for a circle of 5 pixels centered on an integer actual pixel location. -~~~ +~~~{.magick} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.4 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_perfect.gif @@ -153,7 +153,7 @@ Especially a circle that is slightly off center. For example, this circle which is not centered on a pixel, or a pixel boundary, not only has gaps at the top, but is also too thick at the bottom! Yuck! -~~~ +~~~{.magick} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.47 -draw 'translate 7,7.3 circle 0,0 5,0' \ -scale 500% circle_bad_stroke.gif @@ -208,7 +208,7 @@ Consequently flood fill will generally miss the pixels at the very edge of the a For example, here we do a typical flood fill operation. Draw a circle, then try to fill it with a pattern... -~~~ +~~~{.magick} convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill none -stroke red -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -226,7 +226,7 @@ As you can see in the magnified portion of the image, a line of 'off-color' pixe One way to improve this is to pre-fill the areas you intend to fill with a color that matches the pattern you are using. The pattern will still not fill the area fully, but at least it will not look quite so bad. -~~~ +~~~{.magick} convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill black -stroke red -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -241,7 +241,7 @@ convert tile_fill_2.gif -crop 10x10+35+4 +repage -scale 60x60 \ Another way of doing this is to fill the area with your pattern, with a high [Fuzz Factor](../color_basics/#fuzz) , to force the pattern to fill the area completely, right to the very edge, without missing the edge pixels. -~~~ +~~~{.magick} convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill none -stroke red -draw "circle 30,30 5,30" \ -fuzz 35% -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -266,7 +266,7 @@ The problem with this is that as flood fill, by its very nature, does NOT use an You can improve that situation by seperating the image drawing into separate steps. Create a colored circle, fill it, then draw the border. -~~~ +~~~{.magick} convert -size 60x60 xc:lightblue -fill black -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" +tile \ -fill none -stroke red -strokewidth 2 -draw "circle 30,30 5,30" \ @@ -284,7 +284,7 @@ Another is to use a shaped overlay, but that can be a tricky method to work out. Later, I will look at similar modifications to existing images. Of course, if you are drawing the area being flood filled yourself, and not using an existing image, the ideal solution would be to avoid flood fill by by specifying the fill pattern for the original draw operation. -~~~ +~~~{.magick} convert -size 60x60 xc:lightblue -strokewidth 2 \ -tile tile_weave.gif -stroke red -draw "circle 30,30 5,30" \ tile_fill_5.gif From 1444ffafbcdf80bb7bc18171867a154058db6c48 Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Sun, 13 Sep 2015 04:59:57 +0200 Subject: [PATCH 03/10] use _imagedir as output directory of images --- _filters/execute_magick.py | 4 +++- antialiasing/index.md | 40 +++++++++++++++++++------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/_filters/execute_magick.py b/_filters/execute_magick.py index c28fb8f..74c4a39 100644 --- a/_filters/execute_magick.py +++ b/_filters/execute_magick.py @@ -18,6 +18,8 @@ def sha1(x): def execute(code): sys.stderr.write('-'*100 + '\n') code = remove_slash(code) + prev_dir = os.getcwd() + os.chdir(imagedir) for line in code: sys.stderr.write(line + '\n') p = Popen(line, close_fds=True, stdout=PIPE, stderr=PIPE, shell=True) @@ -26,6 +28,7 @@ def execute(code): sys.stderr.write(err + '\n') else: sys.stderr.write(out + '\n') + os.chdir(prev_dir) def remove_slash(text): """ @@ -49,7 +52,6 @@ def remove_slash(text): def magick(key, value, format, meta): if key == 'CodeBlock': [[ident, classes, keyvals], code] = value - sys.stderr.write('>>>' + str(ident) + '\n') if 'magick' in classes: outfile = os.path.join(imagedir, sha1(code)) if format == "latex": diff --git a/antialiasing/index.md b/antialiasing/index.md index 672c88c..a0c53bb 100644 --- a/antialiasing/index.md +++ b/antialiasing/index.md @@ -20,9 +20,9 @@ convert -size 80x80 xc:none \ convert drawn.png -crop 10x10+50+5 +repage -scale 80x80 drawn_mag.png ~~~ -[![\[IM Output\]](drawn.png)](drawn.png) +[![\[IM Output\]](../_images/drawn.png)](../_images/drawn.png) ![==>](../img_www/right.gif) -[![\[IM Output\]](drawn_mag.png)](drawn_mag.png) +[![\[IM Output\]](../_images/drawn_mag.png)](../_images/drawn_mag.png) Now you would think that the above image would have only three colors, 'white', 'black', and 'transparent', as that is all we asked for IM to use. But as you can see, when the image is magnified it has a whole range of colors. @@ -41,9 +41,9 @@ convert drawn_jaggies.png -crop 10x10+50+5 +repage -scale 80x80 \ drawn_jaggies_mag.png ~~~ -[![\[IM Output\]](drawn_jaggies.png)](drawn_jaggies.png) +[![\[IM Output\]](../_images/drawn_jaggies.png)](../_images/drawn_jaggies.png) ![==>](../img_www/right.gif) -[![\[IM Output\]](drawn_jaggies_mag.png)](drawn_jaggies_mag.png) +[![\[IM Output\]](../_images/drawn_jaggies_mag.png)](../_images/drawn_jaggies_mag.png) This time the image really does only have three colors. But the result is not very nice at all. @@ -102,7 +102,7 @@ convert -size 15x15 xc: -fill none -stroke black \ -scale 500% circle_antialiased.gif ~~~ -[![\[IM Output\]](circle_antialiased.gif)](circle_antialiased.gif) +[![\[IM Output\]](../_images/circle_antialiased.gif)](../_images/circle_antialiased.gif) Simply turning of anti-aliasing however produces circles and lines that are not a nice thin 'bitmap' line. @@ -112,7 +112,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ -scale 500% circle_aliased.gif ~~~ -[![\[IM Output\]](circle_aliased.gif)](circle_aliased.gif) +[![\[IM Output\]](../_images/circle_aliased.gif)](../_images/circle_aliased.gif) What you need to do is also adjust the "`-strokewidth`" , which defaults to 1 pixel wide, to something smaller, such as 0.5 pixels wide. @@ -122,7 +122,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ -scale 500% circle_thin_stroke.gif ~~~ -[![\[IM Output\]](circle_thin_stroke.gif)](circle_thin_stroke.gif) +[![\[IM Output\]](../_images/circle_thin_stroke.gif)](../_images/circle_thin_stroke.gif) Better, but not quite right. You can also make the stroke width too small, especially with odd sized radii. @@ -133,7 +133,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ -scale 500% circle_zero_stroke.gif ~~~ -[![\[IM Output\]](circle_zero_stroke.gif)](circle_zero_stroke.gif) +[![\[IM Output\]](../_images/circle_zero_stroke.gif)](../_images/circle_zero_stroke.gif) And here is a good solution for a circle of 5 pixels centered on an integer actual pixel location. @@ -143,7 +143,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ -scale 500% circle_perfect.gif ~~~ -[![\[IM Output\]](circle_perfect.gif)](circle_perfect.gif) +[![\[IM Output\]](../_images/circle_perfect.gif)](../_images/circle_perfect.gif) However, after many experiments I could find no "`-strokewidth`" that works for all radii and centers. Especially a circle that is slightly off center. @@ -159,7 +159,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ -scale 500% circle_bad_stroke.gif ~~~ -[![\[IM Output\]](circle_bad_stroke.gif)](circle_bad_stroke.gif) +[![\[IM Output\]](../_images/circle_bad_stroke.gif)](../_images/circle_bad_stroke.gif) Here is a table of good "`-strokewidth`", to generate a thin single pixel wide circle of specific radius. Note that the best value to use varies depending on if the circle is centered either on an *actual* pixel (such as '` 5 , 5 `'), or on a *half* pixel boundry (such as '` 5.5 , 5.5 `') @@ -218,8 +218,8 @@ convert tile_fill_1.gif -crop 10x10+35+4 +repage -scale 80x80 \ ~~~ -[![\[IM Output\]](tile_fill_1.gif)](tile_fill_1.gif) -[![\[IM Output\]](tile_fill_1_mag.gif)](tile_fill_1_mag.gif) +[![\[IM Output\]](../_images/tile_fill_1.gif)](../_images/tile_fill_1.gif) +[![\[IM Output\]](../_images/tile_fill_1_mag.gif)](../_images/tile_fill_1_mag.gif) As you can see in the magnified portion of the image, a line of 'off-color' pixels was completely missed by the flood fill operation, as the color of these pixels was not quite the same as the area you were filling. @@ -236,8 +236,8 @@ convert tile_fill_2.gif -crop 10x10+35+4 +repage -scale 60x60 \ ~~~ -[![\[IM Output\]](tile_fill_2.gif)](tile_fill_2.gif) -[![\[IM Output\]](tile_fill_2_mag.gif)](tile_fill_2_mag.gif) +[![\[IM Output\]](../_images/tile_fill_2.gif)](../_images/tile_fill_2.gif) +[![\[IM Output\]](../_images/tile_fill_2_mag.gif)](../_images/tile_fill_2_mag.gif) Another way of doing this is to fill the area with your pattern, with a high [Fuzz Factor](../color_basics/#fuzz) , to force the pattern to fill the area completely, right to the very edge, without missing the edge pixels. @@ -251,8 +251,8 @@ convert tile_fill_3.gif -crop 10x10+35+4 +repage -scale 60x60 \ ~~~ -[![\[IM Output\]](tile_fill_3.gif)](tile_fill_3.gif) -[![\[IM Output\]](tile_fill_3_mag.gif)](tile_fill_3_mag.gif) +[![\[IM Output\]](../_images/tile_fill_3.gif)](../_images/tile_fill_3.gif) +[![\[IM Output\]](../_images/tile_fill_3_mag.gif)](../_images/tile_fill_3_mag.gif) > ![](../img_www/reminder.gif)![](../img_www/space.gif) > :REMINDER: @@ -276,8 +276,8 @@ convert tile_fill_4.gif -crop 10x10+35+4 +repage -scale 60x60 \ ~~~ -[![\[IM Output\]](tile_fill_4.gif)](tile_fill_4.gif) -[![\[IM Output\]](tile_fill_4_mag.gif)](tile_fill_4_mag.gif) +[![\[IM Output\]](../_images/tile_fill_4.gif)](../_images/tile_fill_4.gif) +[![\[IM Output\]](../_images/tile_fill_4_mag.gif)](../_images/tile_fill_4_mag.gif) This is one simple way to improve flood fill. Another is to use a shaped overlay, but that can be a tricky method to work out. @@ -292,8 +292,8 @@ convert tile_fill_5.gif -crop 10x10+35+4 +repage -scale 60x60 \ tile_fill_5_mag.gif ~~~ -[![\[IM Output\]](tile_fill_5.gif)](tile_fill_5.gif) -[![\[IM Output\]](tile_fill_5_mag.gif)](tile_fill_5_mag.gif) +[![\[IM Output\]](../_images/tile_fill_5.gif)](../_images/tile_fill_5.gif) +[![\[IM Output\]](../_images/tile_fill_5_mag.gif)](../_images/tile_fill_5_mag.gif) ------------------------------------------------------------------------ From aecb59635d83d4308f89adf12076630ce8f031fb Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Sun, 13 Sep 2015 05:20:19 +0200 Subject: [PATCH 04/10] add filter to Makefile --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 5ccdcd3..cdb0e64 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ all: $(HTML_USAGE_FILES) printf "[PANDOC] %-28s > %s\n" "$<" $@ ${PANDOC} -f markdown -t html5 --mathjax --toc \ --base-header-level=2 --toc-depth=4 \ + --filter _filters/execute_magick.py \ --template=./_templates/page.html -o "$@" "$<" clean: From 1fe39bd7472deefaa22a41c8cd2a895fbb6a4f0f Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Sun, 13 Sep 2015 05:58:52 +0200 Subject: [PATCH 05/10] add some simple checks before executing code --- _filters/execute_magick.py | 46 ++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/_filters/execute_magick.py b/_filters/execute_magick.py index 74c4a39..b9b0ee9 100644 --- a/_filters/execute_magick.py +++ b/_filters/execute_magick.py @@ -10,25 +10,47 @@ from pandocfilters import toJSONFilter, Image, CodeBlock, Para from subprocess import Popen, PIPE -imagedir = '_images' +DEBUG = True + +IMAGEDIR = '_images' + +# List of imagemagick tools; only commands in this list will be allowed to be run by the filter +IM_COMMANDS = ('animate', 'compare', 'composite', 'conjure', 'convert', 'display', 'identify', 'import', 'mogrify', 'montage', 'stream') +IM_IMAGE_TYPES = ('png', 'jpg', 'gif') def sha1(x): return hashlib.sha1(x.encode(sys.getfilesystemencoding())).hexdigest() def execute(code): - sys.stderr.write('-'*100 + '\n') + """ + Executes the code. + Performs some sanity checks first. + """ +# if DEBUG: +# sys.stderr.write('-'*100 + '\n') code = remove_slash(code) prev_dir = os.getcwd() - os.chdir(imagedir) + os.chdir(IMAGEDIR) for line in code: - sys.stderr.write(line + '\n') - p = Popen(line, close_fds=True, stdout=PIPE, stderr=PIPE, shell=True) + if DEBUG: + sys.stderr.write(line + '\n') + commandline = line.split() + if commandline[0] not in IM_COMMANDS: + sys.stderr.write("Not a ImageMagick command: %s\n" % commandline[0]) + return + image_name = commandline[-1] + image_type = os.path.splitext(image_name)[1][1:].lower() + if image_type not in IM_IMAGE_TYPES: + sys.stderr.write("Not a ImageMagick Image Type: %s\n" % image_type) + return + p = Popen(' '.join(commandline), close_fds=True, stdout=PIPE, stderr=PIPE, shell=True) out, err = p.communicate() + if out and DEBUG: + sys.stderr.write(out + '\n') if err: sys.stderr.write(err + '\n') - else: - sys.stderr.write(out + '\n') os.chdir(prev_dir) + return def remove_slash(text): """ @@ -53,18 +75,18 @@ def magick(key, value, format, meta): if key == 'CodeBlock': [[ident, classes, keyvals], code] = value if 'magick' in classes: - outfile = os.path.join(imagedir, sha1(code)) + outfile = os.path.join(IMAGEDIR, sha1(code)) if format == "latex": filetype = "pdf" else: filetype = "png" src = outfile + '.' + filetype - if not os.path.isdir(imagedir): + if not os.path.isdir(IMAGEDIR): try: - os.mkdir(imagedir) - sys.stderr.write('Created directory %s' % imagedir) + os.mkdir(IMAGEDIR) + sys.stderr.write('Created directory %s' % IMAGEDIR) except OSError: - sys.stderr.write('Could not create directory %s' % imagedir) + sys.stderr.write('Could not create directory %s' % IMAGEDIR) return # sys.stderr.write("classes: " + ','.join(classes) + '\n') # sys.stderr.write(str(zip(keyvals)) + '\n') From c1f072683571d2bec5984f2edeeb311e8c2131bc Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Sun, 13 Sep 2015 06:44:16 +0200 Subject: [PATCH 06/10] add comments; describe options 'generate_image' and 'include_image' --- _filters/execute_magick.py | 46 +++++++++++++++++++++++++++++--------- antialiasing/index.md | 26 ++++++++++----------- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/_filters/execute_magick.py b/_filters/execute_magick.py index b9b0ee9..e9b9da9 100644 --- a/_filters/execute_magick.py +++ b/_filters/execute_magick.py @@ -50,7 +50,7 @@ def execute(code): if err: sys.stderr.write(err + '\n') os.chdir(prev_dir) - return + return os.path.join('..', IMAGEDIR, image_name) def remove_slash(text): """ @@ -72,15 +72,35 @@ def remove_slash(text): return retval def magick(key, value, format, meta): + """ + Filter to scan CodeBlocks for ImageMagick code and execute it to generate images. + The following Keys control the behaviour: + generate_image [True|False]: + Code will be executed + include_image [True|False]: + HTML code will be generated to include image. + Needs 'generate_image'. + + Note: Using fenced code blocks + see http://pandoc.org/README.html#fenced-code-blocks + and https://github.com/jgm/pandoc/issues/673 + + Example CodeBlock: + ~~~{generate_image=True include_image=False} + convert -size 80x80 example.png + ~~~ + """ if key == 'CodeBlock': [[ident, classes, keyvals], code] = value - if 'magick' in classes: - outfile = os.path.join(IMAGEDIR, sha1(code)) - if format == "latex": - filetype = "pdf" - else: - filetype = "png" - src = outfile + '.' + filetype + keyvals = dict(keyvals) + if keyvals and keyvals.has_key('generate_image') and keyvals['generate_image']: + + # outfile = os.path.join(IMAGEDIR, sha1(code)) + # if format == "latex": + # filetype = "pdf" + # else: + # filetype = "png" + # src = outfile + '.' + filetype if not os.path.isdir(IMAGEDIR): try: os.mkdir(IMAGEDIR) @@ -92,8 +112,14 @@ def magick(key, value, format, meta): # sys.stderr.write(str(zip(keyvals)) + '\n') # sys.stderr.write('Created image ' + src + '\n') - execute(code) - return [CodeBlock(("", [], []), code), Para([Image([], [src, ""])])] + image = execute(code) + if image: + if keyvals and keyvals.has_key('include_image') and keyvals['include_image']: + return [CodeBlock(("", [], []), code), Para([Image([], [image, "generated my ImageMagick"])])] + else: + return [CodeBlock(("", [], []), code)] + else: + return if __name__ == "__main__": diff --git a/antialiasing/index.md b/antialiasing/index.md index a0c53bb..4d965ba 100644 --- a/antialiasing/index.md +++ b/antialiasing/index.md @@ -13,7 +13,7 @@ It draws them with an operation call "anti-aliasing". To demonstrate, I'll draw an image on a transparent background, then magnify a small part of the image so you can see what is happening. -~~~{.magick} +~~~{generate_image=True include_image=True} convert -size 80x80 xc:none \ -fill white -draw "circle 40,40 15,20" \ -fill black -draw "line 5,30 78,2" drawn.png @@ -33,7 +33,7 @@ If no anti-aliasing was done, then the edges of all the drawn objects would have Here we draw the image again but this time we asked IM to turn off its automatic anti-aliasing operations, using "`+antialias`". -~~~{.magick} +~~~{generate_image=True} convert -size 80x80 xc:none +antialias \ -fill white -draw "circle 40,40 15,20" \ -fill black -draw "line 5,30 78,2" drawn_jaggies.png @@ -96,7 +96,7 @@ Another alternative to drawing circles, which we'll look at in a moment, is to u For example, the normal IM way of drawing a circle produces a lot of grey anti-aliasing colors to give the circle a smooth appearance. -~~~{.magick} +~~~{generate_image=True} convert -size 15x15 xc: -fill none -stroke black \ -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_antialiased.gif @@ -106,7 +106,7 @@ convert -size 15x15 xc: -fill none -stroke black \ Simply turning of anti-aliasing however produces circles and lines that are not a nice thin 'bitmap' line. -~~~{.magick} +~~~{generate_image=True} convert -size 15x15 xc: -fill none -stroke black +antialias \ -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_aliased.gif @@ -116,7 +116,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ What you need to do is also adjust the "`-strokewidth`" , which defaults to 1 pixel wide, to something smaller, such as 0.5 pixels wide. -~~~{.magick} +~~~{generate_image=True} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.5 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_thin_stroke.gif @@ -127,7 +127,7 @@ Better, but not quite right. You can also make the stroke width too small, especially with odd sized radii. -~~~{.magick} +~~~{generate_image=True} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_zero_stroke.gif @@ -137,7 +137,7 @@ convert -size 15x15 xc: -fill none -stroke black +antialias \ And here is a good solution for a circle of 5 pixels centered on an integer actual pixel location. -~~~{.magick} +~~~{generate_image=True} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.4 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_perfect.gif @@ -153,7 +153,7 @@ Especially a circle that is slightly off center. For example, this circle which is not centered on a pixel, or a pixel boundary, not only has gaps at the top, but is also too thick at the bottom! Yuck! -~~~{.magick} +~~~{generate_image=True} convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.47 -draw 'translate 7,7.3 circle 0,0 5,0' \ -scale 500% circle_bad_stroke.gif @@ -208,7 +208,7 @@ Consequently flood fill will generally miss the pixels at the very edge of the a For example, here we do a typical flood fill operation. Draw a circle, then try to fill it with a pattern... -~~~{.magick} +~~~{generate_image=True include_image=False} convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill none -stroke red -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -226,7 +226,7 @@ As you can see in the magnified portion of the image, a line of 'off-color' pixe One way to improve this is to pre-fill the areas you intend to fill with a color that matches the pattern you are using. The pattern will still not fill the area fully, but at least it will not look quite so bad. -~~~{.magick} +~~~{generate_image=True} convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill black -stroke red -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -241,7 +241,7 @@ convert tile_fill_2.gif -crop 10x10+35+4 +repage -scale 60x60 \ Another way of doing this is to fill the area with your pattern, with a high [Fuzz Factor](../color_basics/#fuzz) , to force the pattern to fill the area completely, right to the very edge, without missing the edge pixels. -~~~{.magick} +~~~{generate_image=True} convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill none -stroke red -draw "circle 30,30 5,30" \ -fuzz 35% -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -266,7 +266,7 @@ The problem with this is that as flood fill, by its very nature, does NOT use an You can improve that situation by seperating the image drawing into separate steps. Create a colored circle, fill it, then draw the border. -~~~{.magick} +~~~{generate_image=True} convert -size 60x60 xc:lightblue -fill black -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" +tile \ -fill none -stroke red -strokewidth 2 -draw "circle 30,30 5,30" \ @@ -284,7 +284,7 @@ Another is to use a shaped overlay, but that can be a tricky method to work out. Later, I will look at similar modifications to existing images. Of course, if you are drawing the area being flood filled yourself, and not using an existing image, the ideal solution would be to avoid flood fill by by specifying the fill pattern for the original draw operation. -~~~{.magick} +~~~{generate_image=True} convert -size 60x60 xc:lightblue -strokewidth 2 \ -tile tile_weave.gif -stroke red -draw "circle 30,30 5,30" \ tile_fill_5.gif From 2a8cc1c664d1401a728910932cc714f14dcbe449 Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Sun, 13 Sep 2015 18:16:02 +0200 Subject: [PATCH 07/10] allow printing debug messages in unicode --- _filters/execute_magick.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/_filters/execute_magick.py b/_filters/execute_magick.py index e9b9da9..7545c66 100644 --- a/_filters/execute_magick.py +++ b/_filters/execute_magick.py @@ -17,6 +17,9 @@ # List of imagemagick tools; only commands in this list will be allowed to be run by the filter IM_COMMANDS = ('animate', 'compare', 'composite', 'conjure', 'convert', 'display', 'identify', 'import', 'mogrify', 'montage', 'stream') IM_IMAGE_TYPES = ('png', 'jpg', 'gif') +# Needed for writing unicode to stdout/stderr: +reload(sys) +sys.setdefaultencoding('utf-8') def sha1(x): return hashlib.sha1(x.encode(sys.getfilesystemencoding())).hexdigest() @@ -33,7 +36,7 @@ def execute(code): os.chdir(IMAGEDIR) for line in code: if DEBUG: - sys.stderr.write(line + '\n') + sys.stderr.write(line + u'\n') commandline = line.split() if commandline[0] not in IM_COMMANDS: sys.stderr.write("Not a ImageMagick command: %s\n" % commandline[0]) From 94dde063a83aaebeab8fc879e69da97b7ad1e9ae Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Sun, 13 Sep 2015 18:17:26 +0200 Subject: [PATCH 08/10] don't execute when image already exists --- _filters/execute_magick.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/_filters/execute_magick.py b/_filters/execute_magick.py index 7545c66..6838187 100644 --- a/_filters/execute_magick.py +++ b/_filters/execute_magick.py @@ -10,13 +10,14 @@ from pandocfilters import toJSONFilter, Image, CodeBlock, Para from subprocess import Popen, PIPE -DEBUG = True +DEBUG = False IMAGEDIR = '_images' # List of imagemagick tools; only commands in this list will be allowed to be run by the filter -IM_COMMANDS = ('animate', 'compare', 'composite', 'conjure', 'convert', 'display', 'identify', 'import', 'mogrify', 'montage', 'stream') -IM_IMAGE_TYPES = ('png', 'jpg', 'gif') +IM_COMMANDS = ('animate', 'compare', 'composite', 'conjure', 'convert', 'display', 'identify', 'import', 'mogrify', 'montage', 'stream', 'echo', 'printf') +IM_IMAGE_TYPES = ('png', 'jpg', 'gif', 'tif') + # Needed for writing unicode to stdout/stderr: reload(sys) sys.setdefaultencoding('utf-8') @@ -32,8 +33,6 @@ def execute(code): # if DEBUG: # sys.stderr.write('-'*100 + '\n') code = remove_slash(code) - prev_dir = os.getcwd() - os.chdir(IMAGEDIR) for line in code: if DEBUG: sys.stderr.write(line + u'\n') @@ -43,6 +42,9 @@ def execute(code): return image_name = commandline[-1] image_type = os.path.splitext(image_name)[1][1:].lower() + if os.path.isfile(image_name): + sys.stderr.write("Image already exists: '%s'\n" % image_name) + return os.path.join('..', IMAGEDIR, image_name) if image_type not in IM_IMAGE_TYPES: sys.stderr.write("Not a ImageMagick Image Type: %s\n" % image_type) return @@ -52,7 +54,6 @@ def execute(code): sys.stderr.write(out + '\n') if err: sys.stderr.write(err + '\n') - os.chdir(prev_dir) return os.path.join('..', IMAGEDIR, image_name) def remove_slash(text): @@ -90,7 +91,7 @@ def magick(key, value, format, meta): Example CodeBlock: ~~~{generate_image=True include_image=False} - convert -size 80x80 example.png + convert -size 40x20 xc:red xc:blue -append -rotate 90 append_rotate.gif ~~~ """ if key == 'CodeBlock': @@ -115,7 +116,10 @@ def magick(key, value, format, meta): # sys.stderr.write(str(zip(keyvals)) + '\n') # sys.stderr.write('Created image ' + src + '\n') + prev_dir = os.getcwd() + os.chdir(IMAGEDIR) image = execute(code) + os.chdir(prev_dir) if image: if keyvals and keyvals.has_key('include_image') and keyvals['include_image']: return [CodeBlock(("", [], []), code), Para([Image([], [image, "generated my ImageMagick"])])] From 0ab87b4c971b1fc68014fc0f0f7d5f01c3df0a57 Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Fri, 18 Sep 2015 21:16:36 +0200 Subject: [PATCH 09/10] Revert Makefile & antialiasing/index.md as requested per Eric --- Makefile | 1 - antialiasing/index.md | 66 +++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 34 deletions(-) diff --git a/Makefile b/Makefile index cdb0e64..5ccdcd3 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,6 @@ all: $(HTML_USAGE_FILES) printf "[PANDOC] %-28s > %s\n" "$<" $@ ${PANDOC} -f markdown -t html5 --mathjax --toc \ --base-header-level=2 --toc-depth=4 \ - --filter _filters/execute_magick.py \ --template=./_templates/page.html -o "$@" "$<" clean: diff --git a/antialiasing/index.md b/antialiasing/index.md index 4d965ba..f5851e1 100644 --- a/antialiasing/index.md +++ b/antialiasing/index.md @@ -13,16 +13,16 @@ It draws them with an operation call "anti-aliasing". To demonstrate, I'll draw an image on a transparent background, then magnify a small part of the image so you can see what is happening. -~~~{generate_image=True include_image=True} +~~~ convert -size 80x80 xc:none \ -fill white -draw "circle 40,40 15,20" \ -fill black -draw "line 5,30 78,2" drawn.png convert drawn.png -crop 10x10+50+5 +repage -scale 80x80 drawn_mag.png ~~~ -[![\[IM Output\]](../_images/drawn.png)](../_images/drawn.png) +[![\[IM Output\]](drawn.png)](drawn.png) ![==>](../img_www/right.gif) -[![\[IM Output\]](../_images/drawn_mag.png)](../_images/drawn_mag.png) +[![\[IM Output\]](drawn_mag.png)](drawn_mag.png) Now you would think that the above image would have only three colors, 'white', 'black', and 'transparent', as that is all we asked for IM to use. But as you can see, when the image is magnified it has a whole range of colors. @@ -33,7 +33,7 @@ If no anti-aliasing was done, then the edges of all the drawn objects would have Here we draw the image again but this time we asked IM to turn off its automatic anti-aliasing operations, using "`+antialias`". -~~~{generate_image=True} +~~~ convert -size 80x80 xc:none +antialias \ -fill white -draw "circle 40,40 15,20" \ -fill black -draw "line 5,30 78,2" drawn_jaggies.png @@ -41,9 +41,9 @@ convert drawn_jaggies.png -crop 10x10+50+5 +repage -scale 80x80 \ drawn_jaggies_mag.png ~~~ -[![\[IM Output\]](../_images/drawn_jaggies.png)](../_images/drawn_jaggies.png) +[![\[IM Output\]](drawn_jaggies.png)](drawn_jaggies.png) ![==>](../img_www/right.gif) -[![\[IM Output\]](../_images/drawn_jaggies_mag.png)](../_images/drawn_jaggies_mag.png) +[![\[IM Output\]](drawn_jaggies_mag.png)](drawn_jaggies_mag.png) This time the image really does only have three colors. But the result is not very nice at all. @@ -96,54 +96,54 @@ Another alternative to drawing circles, which we'll look at in a moment, is to u For example, the normal IM way of drawing a circle produces a lot of grey anti-aliasing colors to give the circle a smooth appearance. -~~~{generate_image=True} +~~~ convert -size 15x15 xc: -fill none -stroke black \ -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_antialiased.gif ~~~ -[![\[IM Output\]](../_images/circle_antialiased.gif)](../_images/circle_antialiased.gif) +[![\[IM Output\]](circle_antialiased.gif)](circle_antialiased.gif) Simply turning of anti-aliasing however produces circles and lines that are not a nice thin 'bitmap' line. -~~~{generate_image=True} +~~~ convert -size 15x15 xc: -fill none -stroke black +antialias \ -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_aliased.gif ~~~ -[![\[IM Output\]](../_images/circle_aliased.gif)](../_images/circle_aliased.gif) +[![\[IM Output\]](circle_aliased.gif)](circle_aliased.gif) What you need to do is also adjust the "`-strokewidth`" , which defaults to 1 pixel wide, to something smaller, such as 0.5 pixels wide. -~~~{generate_image=True} +~~~ convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.5 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_thin_stroke.gif ~~~ -[![\[IM Output\]](../_images/circle_thin_stroke.gif)](../_images/circle_thin_stroke.gif) +[![\[IM Output\]](circle_thin_stroke.gif)](circle_thin_stroke.gif) Better, but not quite right. You can also make the stroke width too small, especially with odd sized radii. -~~~{generate_image=True} +~~~ convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_zero_stroke.gif ~~~ -[![\[IM Output\]](../_images/circle_zero_stroke.gif)](../_images/circle_zero_stroke.gif) +[![\[IM Output\]](circle_zero_stroke.gif)](circle_zero_stroke.gif) And here is a good solution for a circle of 5 pixels centered on an integer actual pixel location. -~~~{generate_image=True} +~~~ convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.4 -draw 'translate 7,7 circle 0,0 5,0' \ -scale 500% circle_perfect.gif ~~~ -[![\[IM Output\]](../_images/circle_perfect.gif)](../_images/circle_perfect.gif) +[![\[IM Output\]](circle_perfect.gif)](circle_perfect.gif) However, after many experiments I could find no "`-strokewidth`" that works for all radii and centers. Especially a circle that is slightly off center. @@ -153,13 +153,13 @@ Especially a circle that is slightly off center. For example, this circle which is not centered on a pixel, or a pixel boundary, not only has gaps at the top, but is also too thick at the bottom! Yuck! -~~~{generate_image=True} +~~~ convert -size 15x15 xc: -fill none -stroke black +antialias \ -strokewidth 0.47 -draw 'translate 7,7.3 circle 0,0 5,0' \ -scale 500% circle_bad_stroke.gif ~~~ -[![\[IM Output\]](../_images/circle_bad_stroke.gif)](../_images/circle_bad_stroke.gif) +[![\[IM Output\]](circle_bad_stroke.gif)](circle_bad_stroke.gif) Here is a table of good "`-strokewidth`", to generate a thin single pixel wide circle of specific radius. Note that the best value to use varies depending on if the circle is centered either on an *actual* pixel (such as '` 5 , 5 `'), or on a *half* pixel boundry (such as '` 5.5 , 5.5 `') @@ -208,7 +208,7 @@ Consequently flood fill will generally miss the pixels at the very edge of the a For example, here we do a typical flood fill operation. Draw a circle, then try to fill it with a pattern... -~~~{generate_image=True include_image=False} +~~~ convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill none -stroke red -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -218,15 +218,15 @@ convert tile_fill_1.gif -crop 10x10+35+4 +repage -scale 80x80 \ ~~~ -[![\[IM Output\]](../_images/tile_fill_1.gif)](../_images/tile_fill_1.gif) -[![\[IM Output\]](../_images/tile_fill_1_mag.gif)](../_images/tile_fill_1_mag.gif) +[![\[IM Output\]](tile_fill_1.gif)](tile_fill_1.gif) +[![\[IM Output\]](tile_fill_1_mag.gif)](tile_fill_1_mag.gif) As you can see in the magnified portion of the image, a line of 'off-color' pixels was completely missed by the flood fill operation, as the color of these pixels was not quite the same as the area you were filling. One way to improve this is to pre-fill the areas you intend to fill with a color that matches the pattern you are using. The pattern will still not fill the area fully, but at least it will not look quite so bad. -~~~{generate_image=True} +~~~ convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill black -stroke red -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -236,12 +236,12 @@ convert tile_fill_2.gif -crop 10x10+35+4 +repage -scale 60x60 \ ~~~ -[![\[IM Output\]](../_images/tile_fill_2.gif)](../_images/tile_fill_2.gif) -[![\[IM Output\]](../_images/tile_fill_2_mag.gif)](../_images/tile_fill_2_mag.gif) +[![\[IM Output\]](tile_fill_2.gif)](tile_fill_2.gif) +[![\[IM Output\]](tile_fill_2_mag.gif)](tile_fill_2_mag.gif) Another way of doing this is to fill the area with your pattern, with a high [Fuzz Factor](../color_basics/#fuzz) , to force the pattern to fill the area completely, right to the very edge, without missing the edge pixels. -~~~{generate_image=True} +~~~ convert -size 60x60 xc:lightblue -strokewidth 2 \ -fill none -stroke red -draw "circle 30,30 5,30" \ -fuzz 35% -tile tile_weave.gif -draw "color 30,30 floodfill" \ @@ -251,8 +251,8 @@ convert tile_fill_3.gif -crop 10x10+35+4 +repage -scale 60x60 \ ~~~ -[![\[IM Output\]](../_images/tile_fill_3.gif)](../_images/tile_fill_3.gif) -[![\[IM Output\]](../_images/tile_fill_3_mag.gif)](../_images/tile_fill_3_mag.gif) +[![\[IM Output\]](tile_fill_3.gif)](tile_fill_3.gif) +[![\[IM Output\]](tile_fill_3_mag.gif)](tile_fill_3_mag.gif) > ![](../img_www/reminder.gif)![](../img_www/space.gif) > :REMINDER: @@ -266,7 +266,7 @@ The problem with this is that as flood fill, by its very nature, does NOT use an You can improve that situation by seperating the image drawing into separate steps. Create a colored circle, fill it, then draw the border. -~~~{generate_image=True} +~~~ convert -size 60x60 xc:lightblue -fill black -draw "circle 30,30 5,30" \ -tile tile_weave.gif -draw "color 30,30 floodfill" +tile \ -fill none -stroke red -strokewidth 2 -draw "circle 30,30 5,30" \ @@ -276,15 +276,15 @@ convert tile_fill_4.gif -crop 10x10+35+4 +repage -scale 60x60 \ ~~~ -[![\[IM Output\]](../_images/tile_fill_4.gif)](../_images/tile_fill_4.gif) -[![\[IM Output\]](../_images/tile_fill_4_mag.gif)](../_images/tile_fill_4_mag.gif) +[![\[IM Output\]](tile_fill_4.gif)](tile_fill_4.gif) +[![\[IM Output\]](tile_fill_4_mag.gif)](tile_fill_4_mag.gif) This is one simple way to improve flood fill. Another is to use a shaped overlay, but that can be a tricky method to work out. Later, I will look at similar modifications to existing images. Of course, if you are drawing the area being flood filled yourself, and not using an existing image, the ideal solution would be to avoid flood fill by by specifying the fill pattern for the original draw operation. -~~~{generate_image=True} +~~~ convert -size 60x60 xc:lightblue -strokewidth 2 \ -tile tile_weave.gif -stroke red -draw "circle 30,30 5,30" \ tile_fill_5.gif @@ -292,8 +292,8 @@ convert tile_fill_5.gif -crop 10x10+35+4 +repage -scale 60x60 \ tile_fill_5_mag.gif ~~~ -[![\[IM Output\]](../_images/tile_fill_5.gif)](../_images/tile_fill_5.gif) -[![\[IM Output\]](../_images/tile_fill_5_mag.gif)](../_images/tile_fill_5_mag.gif) +[![\[IM Output\]](tile_fill_5.gif)](tile_fill_5.gif) +[![\[IM Output\]](tile_fill_5_mag.gif)](tile_fill_5_mag.gif) ------------------------------------------------------------------------ From 8cb897aa5eb108f6d823320a3c6cacf35394cb9b Mon Sep 17 00:00:00 2001 From: Holger Dinkel Date: Fri, 18 Sep 2015 21:22:48 +0200 Subject: [PATCH 10/10] Rewrite Docstring to include show same info as Pull Request did --- _filters/execute_magick.py | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/_filters/execute_magick.py b/_filters/execute_magick.py index 6838187..06a01f0 100644 --- a/_filters/execute_magick.py +++ b/_filters/execute_magick.py @@ -78,21 +78,37 @@ def remove_slash(text): def magick(key, value, format, meta): """ Filter to scan CodeBlocks for ImageMagick code and execute it to generate images. - The following Keys control the behaviour: - generate_image [True|False]: - Code will be executed - include_image [True|False]: - HTML code will be generated to include image. - Needs 'generate_image'. - Note: Using fenced code blocks - see http://pandoc.org/README.html#fenced-code-blocks - and https://github.com/jgm/pandoc/issues/673 + Example CodeBlock: + ~~~{generate_image=True include_image=False} + convert -size 40x20 xc:red xc:blue -append -rotate 90 append_rotate.gif + ~~~ + + All images are created in the '_images' directory (might need to be created first) + Existing images will not be overwritten - we might want to add a command to the makefile like clean_images + + The filter will not blindly execute any codeblock, but expects a key/value pair: + + generate_image [True|False] + Another switch enables the automatic generation of HTML code including the tag for the generated image: + + include_image [True|False] Example CodeBlock: + ~~~{generate_image=True include_image=False} convert -size 40x20 xc:red xc:blue -append -rotate 90 append_rotate.gif ~~~ + + Note: Using fenced code blocks + see http://pandoc.org/README.html#fenced-code-blocks + and https://github.com/jgm/pandoc/issues/673 + + Current limitations: + + - Image names need to be unique throughout the whole tree. + - Complex commands, such as using perl/grep/pipes etc. + - Will need to change image location for those examples which already explicitly include the image (ex. examples at the top of the antialising file) """ if key == 'CodeBlock': [[ident, classes, keyvals], code] = value