Skip to content

v3.0.0

Compare
Choose a tag to compare
@edemaine edemaine released this 25 Dec 13:54
· 38 commits to main since this release
  • Major rewrite to improve usage and add a ton of features, including Maketiles, stacked symbols in a single tile, automatically dynamic map functions, arbitrary pre/postprocessing, global underlays/overlays, <def>s support, better SVG cropping, improved performance, and smaller SVG outputs.
  • New "Maketile" feature for setting default svgtiler command-line arguments (replacing the need for Makefiles and make). (#84, #99)
    • Maketile.args can specify default command-line arguments, as if they were in a shell. In particular, you can use glob patterns like **/*.asc, quotes and backslash escapes, and comments via #. Unlike shells, you can freely use multiple lines.
    • Maketile.js or Maketile.coffee can export make (or export default) with a function that runs svgtiler with computed arguments.
      • svgtiler(...args) is like running svgtiler on the command line with the specified arguments. String arguments are parsed as in .args, while Array arguments are treated as is without further processing. You can also pass in already loaded Drawing, Mapping, or Style objects.
      • You can write multiple make rules (chosen on the command line) by wrapping functions in an object or Map (similar to mapping files), or write a generic function that takes the rule name as an argument.
      • You can loop over files matching a glob pattern via svgtiler.glob, and check for additional glob pattern matches via svgtiler.match.
    • If you specify an actual file (mapping and/or drawing), default Maketiles get ignored.
    • You can still specify additional arguments to add to what's run by the Maketile, e.g. svgtiler -v.
    • You can specify a differently named Maketile via --maketile.
  • Other command-line changes: (#84, #99)
    • Specifying a directory name on the command line recurses into that directory, running the Maketile within.
    • -O lets you override the generated output filename stem (sans extension), including specifying patterns like prefix_*_suffix (#84)
    • -s key=value sets share.key to the string "value", as shorthand for creating a mapping file that sets share.
    • ( ... ) contains mapping files, -s share settings, and other command-line options to within the parentheses.
    • --bg color for specifying background color. (#57)
    • --use-data adds data-{key,i,j,k} attributes to <use> tags. (#48)
    • --use-href uses href attributes instead of xlink:href
    • --clean for deleting files that would be generated.
    • Support multiple single-dash arguments like -pP as shorthand for -p -P.
    • -v/--verbose option to help debug e.g. Babel processing.
  • Generalized mappings (#13)
    • All function mappings are now automatically dynamic; no need to wrap in a second layer of function.
    • For efficiency, you can force a function (or any mapping) to be treated as static (dependent only on key, not e.g. neighbors) via svgtiler.static wrapper.
    • Function mappings get context as a second argument (after key) in addition to this, which is helpful for passing context around or when using => arrow functions (which can't receive this). Current context can also be found via getContext().
    • Mapping can defined by Map or WeakMap as alternative to raw object.
    • Sequential composition mapping via new Mappings map1, map2 applies both maps and takes the first match, as if two maps were specified on the command line. (#89)
    • Can nest functions, objects, Maps, Mappings, or Arrays (see below) arbitrarily deep.
  • Tiles can stack multiple <symbol>s on top of each other, by returning an array of SVG content from a mapping function (#33). The first non-null symbol defines defines the tile size.
    • Each <symbol> can have its own z-index, for proper component stacking.
    • Deduplication of the individual <symbol>s makes for smaller SVG output.
    • Parallel composition mapping via [map1, map2] applies both maps and stacks one on top of the other (depending on z-index). (#83)
  • <symbol>s in mappings no longer need viewBox; you can simply specify width and height and the viewBox will default to 0 0 width height. You can also specify both and it behaves as in SVG. (#44)
  • boundingBox is the new name for the overflowBox attribute (though the old name is still supported). The box can now be smaller than the layout box (specified via width/height or viewBox), which trims the overall bounding box when possible (#86). Technically this is a BREAKING CHANGE if your overflowBox is smaller than the layout box, but this is what it ought to happen then.
  • .js/.coffee mapping files can now have many new exports:
    • init is useful for applying side effects to the shared object; it runs once per "load" of the mapping file, with mapping files always initing in command-line order (but sometimes more than once to restore an old state).
    • preprocess lets you scan and/or modify the tile keys in a drawing (#79)
    • postprocess lets you draw global content after tiles have been rendered (#81)
    • The mapping object can be exported as map, as a more descriptive name than default.
    • For the final expression to be implicitly exported as the default, it must be an object expression (literal) or function expression; in particular, it cannot be an assignment or function call. Potentially BREAKING CHANGE, but fixes the behavior in many other files.
  • You can specify a background fill (drawn via a big backing rectangle) via the --bg command-line option, or via svgtiler.background(color). (#57) This is a helpful special case of postprocessing.
  • Tiles causing errors in your .js/.coffee code now render as a warning symbol, and will no longer prevent the rest of the drawing from rendering. This makes it easier to see where your mapping code is crashing, and helps you write mappings incrementally. (#49)
  • Drawing file behavior tweaks (BREAKING CHANGES)
    • Lines in ASCII art and CSV/TSV/SSV files are automatically normalized to have the same length, by appending blank strings ('') to short lines (same as XLSX files were). You can get the old behavior via --uneven. (#85)
    • A blank sheet name in a spreadsheet file no longer has _ in the generated filename.
    • If a spreadsheet file has only one sheet and it has a nonblank name, it will be in the generated filename.
  • Examples
    • New grid-graph example, including <marker> demonstration
    • Chess examples with attack graph via postprocess
    • Tilt example modernized to use Preact
    • Improve mario example to use tile arrays to reduce duplication and demonstrate background feature.
    • Modernize to new generalized mappings, e.g. avoiding excess function wrappers and using svgtiler.static
  • API changes:
    • renderDOM (and other render methods) now take mappings and styles as part of general settings object, instead of as separate arguments. These mappings and styles are now automatically cast into Mapping and Style objects if needed. But mappings can no longer be a map object; it needs to be of the form {map: ...} (or {default: ...}), just like what would be import *ed from a mapping file. BREAKING CHANGES
    • svgtiler.def lets you build markers, gradients, clip masks, etc. with automatically generated IDs, with automatic deduplication and removal of unused defs, and makes it easy to reference them. (#38)
    • svgtiler.id lets you build unique IDs, e.g. to re-use a graphical object (#38). (svgtiler.def also uses this internally.)
    • svgtiler.add(svg) to add SVG content to the current rendering, e.g., in a preprocess or postprocess function. This also enables adding metadata like <title> (#94).
    • svgtiler.require(filename) loads a file (including drawings like ASCII art or spreadsheets, mappings, etc.) as if it were on the command line, producing a Mapping, Drawing, Drawings, Style, Args, or SVGFile object.
    • svgtiler.needVersion for specifying version constraints on SVG Tiler, e.g. svgtiler.needVersion('3.x') in your Maketile.coffee. (#99)
    • svgtiler.getContext() to find the current Context for a tile rendering, so you don't need to pass it through to auxiliary functions. svgtiler.runWithContext() allows you to override the result of svgtiler.getContext().
    • Context has new at method for absolute indexing (#78) and set method for modifying keys (#69)
    • Context no longer has symbols or symbol attributes (as cells are now rendered one at a time, instead of all ahead of time).
    • Context object now shared throughout each drawing, so you could store extra drawing-specific data there.
    • Context has render attribute pointing to current Render instance, in addition to drawing attribute pointer to current Drawing instance.
    • Drawing keys are now allowed to be objects other than Strings, e.g., via preprocessing or when creating manually via new Drawing.
    • Drawing has new at, get, and set methods.
    • Drawing's main attribute renamed from data to keys, and Mapping's main attribute renamed from data to map. (#88)
    • Drawing has new margins and unevenLengths attributes for understanding what happened during margin trimming and uneven length fixing.
    • Mapping's module attribute renamed to exports.
    • New Render class represents a rendering task for one Drawing, including all render parameters (e.g. drawing, mappings, and styles).
      • xMin, xMax, yMin, yMax, width, height, and layers attributes which are useful in preprocess and postprocess.
      • id method for generating unique IDs; svgtiler.id calls this.
      • def method for including <defs> content; svgtiler.def calls this.
      • add method for adding SVG content; svgtiler.add calls this.
      • makeDOM, makeSVG, makeTeX replace old renderSVGDOM, renderSVG, and renderTeX methods of Drawing.
      • svgtiler.getRender() to find the current Render job, so you don't need to pass it through to auxiliary functions. svgtiler.runWithRender() to override.
    • New Tile and SVGSymbol classes: Tile represents an expanded (and possibly parsed) tile at a specific location, while SVGSymbol represents the parsed SVG <symbol> content (which can be used by many tiles). These replace Symbol, StaticSymbol, and DynamicSymbol classes. (In particular, avoids name conflict with JS's Symbol.)
    • The constructors for Drawing, Mapping, and Style and their subclasses now make it much easier to create the equivalent of drawing, mapping, and style files without actual files. For most subclasses X of Input, new X(data, options) generally takes the file contents as the first argument. For example, new ASCIIMapping(asc) will now parse an ASCII file, and new StylusStyle(content) will now parse Stylus content.
    • Mappings and Styles are now just Array subclasses. Instead of Mappings.from([map1, map2]), you now just use new Mappings(map1, map2).
    • New Driver class representing command-line-style drivers, with inheritance of options from the parent, to support proper recursion.
    • svgtiler.getDriver() to find the current Driver; svgtiler.runWithDriver() allows you to override the result of svgtiler.getDriver().
  • Optimizations
    • Tile caching/deduplication is now global to each rendering, not local to each dynamic Symbol (#50), enabling re-use when multiple tile keys expand to the same SVG.
    • Tiles with empty SVG content no longer render <symbol>s or <use>s. This can vastly reduce SVG outputs with blank space. (In one case, I got an 82% reduction.)
    • Generated <use> tags usually avoid repeating width and height. (I've seen this reduce large examples with many tiles by ~35%.)
    • Preact VDOM converted more efficiently to internal xmldom, speeding up use of Precat by around 7x. (#82)
    • Inlined images use shorter ids.
  • Bug fixes
    • No longer override existing width/height attributes in <image>s.
    • Remove z-index from style attribute to produce valid SVG.
    • Prevent mappings accidentally matching tile keys constructor and toString.
    • Fix TeX generation when SVG didn't need to rebuild, and when there was an unrecognized symbol.
    • Fix renderDOM accidentally using one element's settings for future elements too.
    • Fixes for running in browser, including Preact VDOM

Full Changelog: v2.4.1...v3.0.0