SVG Tiler is a tool for drawing diagrams on a grid using text or spreadsheets, and then substituting SVG symbols to make a big SVG figure, and optionally convert it to PDF.
To use SVG Tiler, you combine two types of files (possibly multiple of each type):
A drawing file specifies a grid of symbol names (strings) which, combined with one or more mapping files to define the SVG associated with each symbol, compile to a single (tiled) SVG. Drawing files can be specified as ASCII art (where each symbol is limited to a single character), space-separated ASCII art (where symbols are separated by whitespace), or standard CSV/TSV formats such as those exported by Google Sheets or Excel.
These input files are listed on the
svgtiler command line,
with mapping files typically before drawing files.
File types and formats are distinguished automatically by their extension.
svgtiler map1.txt map2.coffee drawing.asc drawings.xls
will generate drawing.svg using the mappings in
and will generate
drawings_<sheet>.svg for each sheet in
In the .txt format for mapping files, each line consists of a symbol name
(either having no spaces, or consisting entirely of a single space),
followed by whitespace, followed by either a block of SVG code
<symbol viewBox="...">...</symbol>) or a filename containing
such a block. For example, here is a mapping of
O to black squares
(space) and empty string to blank squares, all dimensioned
50 × 50:
O <symbol viewBox="0 0 50 50"><rect width="50" height="50"/></symbol> <symbol viewBox="0 0 50 50"></symbol> <symbol viewBox="0 0 50 50"></symbol>
Here is a mapping of the same symbols to external files:
O O.svg blank.svg blank.svg
The object or function should map a symbol name to either
In the last case, the function is called for each occurrence of the symbol,
this bound to a manufactured
Context object, giving you access to
the following properties:
this.keyis the symbol name, or
Contextis out of bounds of the drawing;
this.keycontains the given
this.key.includes(substring)in ECMAScript 2015).
this.iis the row number of the cell of this symbol occurrence (starting at 0);
this.jis the column number of the cell of this symbol occurrence (starting at 0);
this.neighbor(dj, di)returns a new
i + diand column
j + dj. (Note the reversal of coordinates, so that the order passed to
neighborcorresponds to x then y coordinate.) If there is no symbol at that position, you will still get a
this.neighbor(1, 0).includes('-')to check for adjacent symbols that change how this symbol should be rendered.
this.row(di = 0)returns an array of
Contextobjects, one for each symbol in row
i + di(in particular, including
diis the default of
0). For example, you can use the
everymethods on this array to do bulk tests on the row.
this.column(dj = 0)returns an array of
Contextobjects, one for each symbol in column
j + dj.
The .asc format for drawing files represents traditional ASCII art:
each non-newline character represents a one-character symbol name.
For example, here is a simple 5 × 5 ASCII drawing using symbols
OOO O O O OOOOO O O OOO
The .ssv, .csv, and .tsv formats use
delimiter-separated values (DSV)
to specify an array of symbol names. In particular,
formats are exactly those exported by spreadsheet software such as
Google Drive or Excel, enabling you to draw in that software.
The .ssv format is similar, but where the delimiter between symbol names
is arbitrary whitespace.
(Contrast this behavior with .csv which treats every comma as a delimiter.)
This format is nice to work with in a text editor, allowing you to line up
the columns by padding symbol names with extra spaces.
All three formats support quoting according to the usual DSV rules:
any symbol name (in particular, if it has a delimiter or double quote in it)
can be put in double quotes, and double quotes can be produced in the
symbol name by putting
"" (two double quotes) within the quoted string.
Thus, the one-character symbol name
" would be represented by
The .xlsx, .xlsm, .xlsb, .xls (Microsoft Excel), .ods, .fods (OpenDocument), .dif (Data Interchange Format), .prn (Lotus), and .dbf (dBASE/FoxPro) formats support data straight from spreadsheet software. This format is special in that it supports multiple sheets in one file. In this case, the output SVG files have filenames distinguished by an underscore followed by the sheet name.
Given one or more mapping files and a drawing file, SVG Tiler follows a fairly
simple layout algorithm to place the SVG expansions of the symbols into a
single SVG output. Each symbol has a bounding box, either specified by
viewBox of the root element, or automatically computed.
The algorithm places symbols in a single row to align their top edges,
with no horizontal space between them.
The algorithm places rows to align their left edges so that the rows' bounding
boxes touch, with the bottom of one row's bounding box equalling the top of
the next row's bounding box.
This layout algorithm works well if each row has a uniform height and each
column has a uniform width, even if different rows have different heights
and different columns have different widths. But it probably isn't what you
want if symbols have wildly differing widths or heights, so you should set
Each unique symbols gets defined just once (via SVG's
then instantiated (via SVG's
<use>) many times,
resulting in relatively small and efficient SVG outputs.
support on symbols defined by mapping files, even though output is
SVG 1.1 (which does not support z-index): symbol uses get re-ordered to
simulate the correct z order. For example,
<symbol viewBox="0 0 10 10" style="z-index: 2">...</symbol>
will be rendered on top of (later than) all symbols without a
style="z-index:..." specification (which default to a z-index of 0).
Symbols can draw beyond their
(as in normal SVG). Furthermore, the
viewBox of the overall output
drawing can still be computed correctly (larger than the bounding box
of the symbol
viewBoxes) via a special
<symbol viewBox="0 0 10 10" overflowBox="-5 -5 20 20" style="overflow: visible">...</symbol>
defines a symbol that gets laid out as if it occupies the [0, 10] ×
[0, 10] square, but the symbol can draw outside that square, and the overall
drawing bounding box will be set as if the symbol occupies the
[−5, 15] × [−5, 15] square.
Even zero-width and zero-height symbols will get rendered when
style="overflow: visible" is specified, by overriding
Very limited automatic
viewBox setting via bounding box computation
(but see the code for many SVG features not supported).
For example, the SVG
<rect x="-5" y="-5" width="10" height="10"/>
will create a symbol with
viewBox="-5 -5 10 10".
You can automatically convert all exported SVG files into PDF if you have
Inkscape installed, via the
svgtiler -p map.coffee drawings.xls
After installing Node, you can install this tool via
npm install -g svgtiler
The command-line arguments consist mostly of mapping and/or drawing files. The files and other arguments are processed in order, so for example a drawing can use all mapping files specified before it on the command line. If the same symbol is defined by multiple mapping files, later mappings take precedence (overwriting previous mappings).
Here is the output of
This take on SVG Tiler was written by Erik Demaine, in discussions with Jeffrey Bosboom and others, with the intent of subsuming his original SVG Tiler. In particular, the .txt mapping format and .asc drawing format here are nearly identical to the formats supported by the original.