3

Is there a programmatic way of converting a set of LaTeX symbols into a set of svg files using the font files directly? In particular, I would like to create svg files for some of the symbols that are listed in the comprehensive LaTeX symbol list, i.e., http://anorien.csc.warwick.ac.uk/mirrors/CTAN/info/symbols/comprehensive/symbols-a4.pdf And if I were to chose one of these packages of symbols and get all the directories and files (atm/, tfm/, etc) from e.g. http://tug.ctan.org/fonts/linearA/, could I use these dirs and files directly and covert all the symbols defined therein to svg.

I suppose I am looking for something like:

 magic_convert_fonts_to_svg --input_dir font_package_dir/ --output all_symbols_in_package.svg  

I understand that there may be more manual ways of doing this involving e.g. dvisvgm (http://dvisvgm.bplaced.net/), but I would like to know if there is a straightforward automatic way of convert from font files directly.

3 Answers 3

2

You can loop over all glyphs in the font, print each of them on separate page, generate a dvi file and convert it to svg using dvisvgm. We can automate it using Lua script which takes a font name and some other options as argument. fonttosvg.lua:

kpse.set_program_name "luatex"
local lapp = require "lapp-mk4"

local args = lapp [[
Convert TeX font to SVG
-s,--scale (default 1) Glyph scaling
<fontname> (string)
]]

local fontname = args.fontname

if fontname == nil then
  print "Missing font name"
  os.exit()
end

local latex = io.popen("dviluatex -jobname=".. fontname, "w")

latex:write(string.format([[
\font\sample=%s at 48pt
\nopagenumbers
\count55=0
\newif\ifvalidchar
\loop\ifnum\count55<256
  \validchartrue
  \setbox0=\hbox{\sample\char\count55}
  \ifdim\wd0=0pt\relax
    \ifdim\ht0=0pt\relax
     \ifdim\dp0=0pt\relax
       \global\validcharfalse
     \fi
    \fi
  \fi
  \ifvalidchar
    \box0
    \vfill\eject
  \fi
  \advance\count55 by1\relax
\repeat
\bye
]], fontname))
latex:close()

os.execute(string.format("dvisvgm -b none -t 0,2 -n -p 1- -c %s  %s.dvi", args.scale, fontname))

this script writes plain TeX document which loops over all possible characters in the tfm file and writes each existing character to standalone page. dvisvgm then traces glyph curves (-n option) and save each character in file fontname-pagenumber.svg.

For example if we want to create svgs for linearA font, we can call the script as following:

texlua fonttosvg.lua -s 3 LinearA

LinearA if name of the tfm file provided by the package, -s option is used to scale the svg files. Some resulting glyph:

enter image description here

1
  • Amazing! Thank you! It is exactly what I need.
    – mjandrews
    Mar 9, 2016 at 12:04
2

Alternatively to Michal's nice solution, you can also use the little command-line program font2svg. It's a quick hack written in C++. It takes the path to a font file as an argument and creates separate SVG files for each glyph. For example,

font2svg /path/to/LinearA.pfb

creates the files LinearA-0001.svg,...,LinearA-0178.svg.

The program works with all vector fonts supported by FreeType and doesn't require any TeX files.

1
  • Another excellent tool. I just ran it on Linux (making a few changes to Makefile) and it did the job perfectly.
    – mjandrews
    Mar 9, 2016 at 17:10
1

FontForge can export the glyph outlines as SVG files.

Interactive way: Open a font, then select and open a glyph. The outline is exported to SVG via the menu item File->Export.

FontForge can also be scripted with Python if the bindings for Python are installed. The following script exports the glyphs of a font to SVG files with names consisting of the font name, Unicode/encoding number and glyph name.

#!/usr/bin/env python
import argparse
import fontforge

def parse_command_line_options():
    parser = argparse.ArgumentParser(
        description='Export font glyphs as SVG files via fontforge.')
    parser.add_argument(
        'font_file_name',
        metavar='FONT',
        help='font file name')
    return parser.parse_args()

def generate_file_name(glyph):
    sep = '-'
    # Font name
    file_name = glyph.font.fontname
    file_name += sep
    # Unicode or encoding number
    if glyph.unicode >= 0:
        file_name += 'U+' + format(glyph.unicode, '04X')
        file_name += sep
    elif glyph.encoding >= 0:
        file_name += '0x' + format(glyph.encoding, '02X')
        file_name += sep
    # Glyph name
    file_name += glyph.glyphname
    # Extension
    file_name += '.svg'
    return file_name

def export_glyphs(font_file_name):
    font = fontforge.open(font_file_name)
    glyphs = font.selection.byGlyphs.all()
    for glyph in glyphs:
        svg_file_name = generate_file_name(glyph)
        if glyph.isWorthOutputting:
            glyph.export(svg_file_name)
            print(svg_file_name)

def main():
    args = parse_command_line_options()
    export_glyphs(args.font_file_name)

if __name__ == "__main__":
    main()

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .