From 8838648858532a8f1c323f25f37a72c4d2eba496 Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Sun, 16 Dec 2012 14:38:21 +0100 Subject: [PATCH] Add script for automatic toolbar image creation. Manually created toolbar images are needed in many cases, but for simple symbols automatically generated ones are better than nothing. --- development/Makefile.am | 2 + development/tools/generate_symbols_images.lyx | 107 ++++++++++++++ development/tools/generate_symbols_images.py | 139 ++++++++++++++++++ src/mathed/MathFactory.cpp | 2 + 4 files changed, 250 insertions(+) create mode 100644 development/tools/generate_symbols_images.lyx create mode 100644 development/tools/generate_symbols_images.py diff --git a/development/Makefile.am b/development/Makefile.am index f05fc108c3..63d67af02b 100644 --- a/development/Makefile.am +++ b/development/Makefile.am @@ -14,6 +14,8 @@ EXTRA_DIST = coding/Rules coding/Recommendations \ LyX-Mac-binary-release.sh \ tools/convert_kmap.py \ tools/gen_lfuns.py \ +tools/generate_symbols_images.lyx \ +tools/generate_symbols_images.py \ tools/generate_symbols_list.py \ tools/unicodesymbols.py \ tools/x-font \ diff --git a/development/tools/generate_symbols_images.lyx b/development/tools/generate_symbols_images.lyx new file mode 100644 index 0000000000..43886648f4 --- /dev/null +++ b/development/tools/generate_symbols_images.lyx @@ -0,0 +1,107 @@ +#LyX 2.1 created this file. For more info see http://www.lyx.org/ +\lyxformat 453 +\begin_document +\begin_header +\textclass article +\begin_preamble +\usepackage[active]{preview} +\end_preamble +\use_default_options true +\maintain_unincluded_children false +\language english +\language_package default +\inputencoding auto +\fontencoding global +\font_roman default +\font_sans default +\font_typewriter default +\font_math auto +\font_default_family default +\use_non_tex_fonts false +\font_sc false +\font_osf false +\font_sf_scale 100 +\font_tt_scale 100 +\graphics default +\default_output_format default +\output_sync 0 +\bibtex_command default +\index_command default +\paperfontsize 11 +\spacing single +\use_hyperref false +\papersize default +\use_geometry false +\use_package amsmath 1 +\use_package amssymb 1 +\use_package esint 1 +\use_package mathdots 1 +\use_package mathtools 1 +\use_package mhchem 1 +\use_package stmaryrd 1 +\use_package undertilde 1 +\cite_engine basic +\cite_engine_type numerical +\biblio_style plain +\use_bibtopic false +\use_indices false +\paperorientation portrait +\suppress_date false +\justification true +\use_refstyle 1 +\index Index +\shortcut idx +\color #008000 +\end_index +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\paragraph_indentation default +\quotes_language english +\papercolumns 1 +\papersides 1 +\paperpagestyle default +\tracking_changes false +\output_changes false +\html_math_output 0 +\html_css_as_file 0 +\html_be_strict false +\end_header + +\begin_body + +\begin_layout Standard +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +begin{preview} +\end_layout + +\end_inset + + +\begin_inset Formula $a$ +\end_inset + + +\begin_inset ERT +status open + +\begin_layout Plain Layout + + +\backslash +end{preview} +\end_layout + +\end_inset + + +\end_layout + +\end_body +\end_document diff --git a/development/tools/generate_symbols_images.py b/development/tools/generate_symbols_images.py new file mode 100644 index 0000000000..1ba21f8859 --- /dev/null +++ b/development/tools/generate_symbols_images.py @@ -0,0 +1,139 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- + +# file generate_symbols_images.py +# This file is part of LyX, the document processor. +# Licence details can be found in the file COPYING. + +# author Georg Baum + +# Full author contact details are available in file CREDITS + +# This script generates a toolbar image for each missing math symbol +# It needs the template document generate_symbols_images.lyx, which must +# contain the placeholder formula '$a$' for generating the png image via +# preview.sty and dvipng. +# The created images are not always optimal, therefore the existing manually +# created images should never be replaced by automatically created ones. + + +import os, re, string, sys, subprocess, tempfile, shutil +import Image + +def usage(prog_name): + return ("Usage: %s lyxexe outputpath\n" % prog_name) + + +def error(message): + sys.stderr.write(message + '\n') + sys.exit(1) + + +def getlist(lyxexe, lyxfile): + """ Call LyX and get a list of symbols from mathed debug output. + This way, we can re-use the symbols file parser of LyX, and do not + need to reimplement it in python. """ + + # The debug is only generated if lyxfile contains a formula + cmd = "%s %s -dbg mathed -x lyx-quit" % (lyxexe, lyxfile) + proc = subprocess.Popen(cmd, shell=True, stderr=subprocess.PIPE) + (stdout, stderr) = proc.communicate() + regexp = re.compile(r'.*: read symbol \'(\S+)\s+inset:\s+(\S+)') + # These insets are more complex than simply symbols, so the images need to + # be created manually + skipinsets = ['big', 'font', 'matrix', 'mbox', 'oldfont', 'ref', 'space'] + symbols = [] + for line in stderr.split('\n'): + m = regexp.match(line) + if m: + inset = m.group(2) + if not inset in skipinsets: + symbols.append(m.group(1)) + return symbols + + +def createimage(name, path, template, lyxexe, tempdir): + """ Create the image file for symbol name in path. """ + + if name == '|': + filename = 'vert' + elif name == '/': + filename = 'slash' + elif name == '\\': + filename = 'backslash' + elif name == '*': + filename = 'ast' + elif name.startswith('lyx'): + print 'Skipping ' + name + return + else: + skipchars = ['|', '/', '\\', '*', '!', '?', ':', ';', '^', '<', '>'] + for i in skipchars: + if name.find(i) >= 0: + print 'Skipping ' + name + return + filename = name + pngname = os.path.join(path, filename + '.png') + if os.path.exists(pngname): + print 'Skipping ' + name + return + print 'Generating ' + name + lyxname = os.path.join(tempdir, filename) + lyxfile = open(lyxname + '.lyx', 'wt') + lyxfile.write(template.replace('$a$', '$\\' + name + '$')) + lyxfile.close() + cmd = "%s %s.lyx -e dvi" % (lyxexe, lyxname) + proc = subprocess.Popen(cmd, shell=True) + proc.wait() + if proc.returncode != 0: + print 'Error in DVI creation for ' + name + return + # The magnifaction factor is calculated such that we get an image of + # height 18 px for most symbols and document font size 11. Then we can + # add a small border to get the standard math image height of 20 px. + cmd = "dvipng %s.dvi -bg Transparent -D 115 -o %s" % (lyxname, pngname) + proc = subprocess.Popen(cmd, shell=True) + proc.wait() + if proc.returncode != 0: + print 'Error in PNG creation for ' + name + return + image = Image.open(pngname) + (width, height) = image.size + if width < 20 and height < 20: + if width == 19 and height == 19: + padded = Image.new('RGBA', (width+1, height+1), (0, 0, 0, 0)) + padded.paste(image, (0, 0)) + elif width == 19: + padded = Image.new('RGBA', (width+1, height+2), (0, 0, 0, 0)) + padded.paste(image, (0, 1)) + elif height == 19: + padded = Image.new('RGBA', (width+2, height+1), (0, 0, 0, 0)) + padded.paste(image, (1, 0)) + else: + padded = Image.new('RGBA', (width+2, height+2), (0, 0, 0, 0)) + padded.paste(image, (1, 1)) + padded.convert(image.mode) + padded.save(pngname, "PNG") + + +def main(argv): + + if len(argv) == 3: + (base, ext) = os.path.splitext(argv[0]) + symbols = getlist(argv[1], base) + lyxtemplate = base + '.lyx' + templatefile = open(base + '.lyx', 'rt') + template = templatefile.read() + templatefile.close() + tempdir = tempfile.mkdtemp() + for i in symbols: + createimage(i, argv[2], template, argv[1], tempdir) + shutil.rmtree(tempdir) + else: + error(usage(argv[0])) + + return 0 + + +if __name__ == "__main__": + main(sys.argv) diff --git a/src/mathed/MathFactory.cpp b/src/mathed/MathFactory.cpp index 160196c643..d41d4558cc 100644 --- a/src/mathed/MathFactory.cpp +++ b/src/mathed/MathFactory.cpp @@ -222,6 +222,8 @@ void initSymbols() else theMathWordList[tmp.name] = tmp; + // If you change the following output, please adjust + // development/tools/generate_symbols_images.py. LYXERR(Debug::MATHED, "read symbol '" << to_utf8(tmp.name) << " inset: " << to_utf8(tmp.inset) << " draw: " << int(tmp.draw.empty() ? 0 : tmp.draw[0])