Asciitosvg
DANGER, WILL ROBINSON: THIS REPOSITORY IS IN MAINTENANCE MODE! I will not be continuing feature development or fixing bugs in this codebase. I will continue to review and accept pull requests that do this. Please click the following link to view the actively developed ASCIIToSVG codebase, which is written in Go.
Install / Use
/learn @dhobsd/AsciitosvgREADME
ASCIIToSVG
.-------------------------.
| |
| .---.-. .-----. .-----. |
| | .-. | +--> | | <--| |
| | '-' | | <--| +--> | |
| '---'-' '-----' '-----' |
| ascii 2 svg |
| |
'-------------------------'
https://9vx.org/~dho/a2s/
WARNING
I haven't written PHP in years, and this implementation has numerous drawbacks. I recommend you look into using the Go implementation instead. I will continue to accept, review, and merge PRs to this repository, and (where appropriate) mirror any new functionality in the Go version, but I do not intend to identify new bugs, fux old bugs, or self-author new functionality in this repository.
Introduction
License
ASCIIToSVG is copyright © 2012 Devon H. O'Dell and is distributed under an awesome 2-clause BSD license. All code without explicit copyright retains this license. Any code not adhering to this license is explicit in its own copyright.
What does it do?
ASCIIToSVG is a pretty simple PHP library for parsing ASCII art diagrams and converting them to a pretty SVG output format.
But... why?
There are a few reasons, mostly to do with things I really like:
- I like markdown a lot. If I could write everything in markdown, I probably would.
- I like ASCII art a lot. I've been playing around with drawing ASCII art since I was both a wee lad and a BBS user.
- I like pretty pictures. People say they're worth a thousand words.
So I thought, "What if I could combine all these things and start writing markdown documents for my technical designs -- complete with ASCII art diagrams -- that I could then prettify for presentation purposes?"
Aren't there already things that do this?
Well, yes. There is a project called [ditaa][1] that has this functionality. Sort of. But it's written in Java and it generates PNG output. I needed something that would generate scalable output, and would be a bit easier to integrate into a wiki (like the one in [mtrack][2], which we use at work). We got it integrated, but I ran into a few bugs and rendering nits that I didn't like. Additionally, it takes a long time to shell out the process and JVM to generate the PNG. If you're doing inline edits on an image, you can imagine that this gets to be a heavy load on both the client and server, just from a data transfer perspective alone.
So I reimplemented it in PHP. There are some things it can do better, and I'm aware of a few rendering bugs already, but so far it works better and is more extensible than ditaa, and I'm enjoying it more.
Building ASCIIToSVG
What?! Building?!?! Isn't this PHP?
Well, yes. But some of it is tool-generated. If you check out the code, you will get the latest generated code, don't worry! This information is more for people who want to contribute and need to make changes to the SVG path parser.
You will need [JLexPHP][7] and [lemon-php][8] to build the tokenizer and parser for the SVG paths. (This parser was implemented [from the SVG 1.1 paths BNF][9].) JLexPHP requires the JDK to build; lemon-php requires a C compiler.
You should have the following structure one your repository:
.
├── JLexPHP
├── asciitosvg
└── lemon-php
Simply running make on asciitosvg should be enough to get all the autogenerated
stuff running. It will also update the logo. Please make sure to view the logo and
test files to make sure that you haven't broken any rendering.
Make clean will remove extraneous files that aren't necessary for running; make distclean removes everything autogenerated.
Using ASCIIToSVG
Command Line
A command line utility exists to convert the ASCII file to SVG. You can put
this somewhere inside your $PATH and set its permissions to +x. You can also symlink
to it by adding ln -s /Users/asciitosvg/a2s a2s in /usr/local/bin.
Windows users will have to make their own batch file to run this or remove the first
line. Usage:
Usage: a2s [-i[-|filename]] [-o[-|filename]] [-sx-scale,y-scale]
-h: This usage screen.
-i: Path to input text file. If unspecified, or set to "-" (hyphen),
stdin is used.
-o: Path to output SVG file. If unspecified or set to "-" (hyphen),
stdout is used.
-s: Grid scale in pixels. If unspecified, each grid unit on the X
axis is set to 9 pixels; each grid unit on the Y axis is 16 pixels.
Note that this uses PHP's getopt which handles short options stupidly. You
need to put the actual argument right next to the flag; no space. For
example: a2s -i- -oout.svg -s10,17 would be a valid command line
invocation for this utility.
Class API
There are plenty of comments explaining how everything works (and I'm sure several bugs negating the truth of some of those explanations) in the source file. Basic flow through the API is:
:::php
$asciiDiagram = file_get_contents('some_pretty_art');
$o = new org\dh0\a2s\ASCIIToSVG($asciiDiagram);
$o->setDimensionScale(9, 16);
$o->parseGrid();
file_put_contents('some_pretty_art.svg', $o->render());
I'll put more detailed information in the [wiki][3] and this README as I
have time and inclination to do so.
How Do I Draw?
Enough yammering about the impetus, code, and functionality. I bet you want
to draw something. ASCIIToSVG supports a few different ways to do that. If
you have more questions, take a look at some of the files in the test
subdirectory. (If you have a particularly nice diagram you'd like to see
included for demo, feel free to send it my way!)
Basics: Boxes and Lines
Boxes can be polygons of almost any shape (don't try anything too wacky just yet; I haven't). Horizontal, vertical, and diagonal lines are all supported, giving ASCIIToSVG basically complete support for output from [App::Asciio][4]. Edges of boxes and lines can be drawn by using the following characters:
-or=: Horizontal lines (dash, equals)|or:: Vertical line (pipe, colon)*: Line of ambiguous direction (asterisk)\or/: Diagonal line (backward slash, forward slash)+: Edge of line passing through a box or line corner (plus)
The existence of a : or = edge on a line causes that line to be
rendered as a dashed line.
To draw a box or turn a line, you need to specify corners. The following characters are valid corner characters:
'and.: Quadratic Bézier corners (apostrophe, period)#: Boxed, angular, 90 degree corners for boxes (hash)+: Boxed, angular, 90 degree corners for lines (plus)
The + token is a control point for lines. It denotes an area where a line
intersects another line or traverses a box boundary.
A simple box with 3 rounded corners and a line pointing at it:
#----------.
| | <---------
'----------'
A Quick Note on Diagonals
Diagonal lines cannot be made to form a closed box. If you would like to
make diagrams using parallelograms / diamonds (perhaps for flow charts), it
is recommended that you annotate regular boxes and use custom objects (see
below) instead. Diagonal lines also may not use ' or . smoothed corners.
Basics: Markers
Markers can be attached at the end of a line to give it a nice arrow by using one of the following characters:
<: Left marker (less than)>: Right marker (greater than)^: Up marker (carat)v: Down marker (letter v)
Basics: Text
Text can be inserted at almost any point in the image. Text is rendered in a monospaced font. There aren't many restrictions, but obviously anything you type that looks like it's actually a line or a box is going to be a good candidate for turning into some pretty SVG path. Here is a box with some plain black text in it:
.-------------------------------------.
| Hello here and there and everywhere |
'-------------------------------------'
Basics: Formatting
It's possible to change the format of any boxes / polygons you create. This is done (true to markdown form) by providing a reference on the top left edge of the object, and defining that reference at the bottom of the input. Let me reiterate that the references must be defined at the bottom of the input. An example:
.-------------. .--------------.
|[Red Box] | |[Blue Box] |
'-------------' '--------------'
[Red Box]: {"fill":"#aa4444"}
[Blue Box]: {"fill":"#ccccff"}
Text appearing within a stylized box automatically tries to fix the color contrast if the black text would be too dark on the background. The reference commands can take any valid SVG properties / settings for a [path element][5]. The commands are specified in JSON form, one per line. Reference commands do not accept nested JSON obj
Related Skills
node-connect
344.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
96.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
