# svg railroad diagrams github / tabatkins / railroad-diagrams source https://github.com/tabatkins/railroad-diagrams - https://github.com/tabatkins/railroad-diagrams/blob/gh-pages/railroad.css - https://github.com/tabatkins/railroad-diagrams/blob/gh-pages/railroad.js demo https://tabatkins.github.io/railroad-diagrams/ - https://tabatkins.github.io/railroad-diagrams/generator.html - https://tabatkins.github.io/railroad-diagrams/railroad.css - https://tabatkins.github.io/railroad-diagrams/railroad.js ie. - https://www.json.org/json-en.html - https://www.w3.org/TR/mediaqueries-4/#mq-range-context ## reference https://github.com/tabatkins/railroad-diagrams/blob/gh-pages/README-js.md **components** - *leaves* - `Terminal(text[, {href, title, cls}])` or *a bare string* - `NonTerminal(text[, {href, title, cls}])` - `Comment(text[, {href, title, cls}])` - `Skip()` - `Start({ type, label })` - `End({ type })` - *containers* - `Sequence(...children)` - X `Stack(...children)` - XXX `OptionalSequence(...children)` - `Choice(index, ...children)` - XXX `MultipleChoice(index, type, ...children)` - XXX `HorizontalChoice(...children)` - `Optional(child[, skip])` - `OneOrMore(child[, repeat])` - XXX `AlternatingSequence(option1, option2)` - `ZeroOrMore(child[, repeat[, skip]])` - XXX `Group(child[, label])` reduced - *leaves* - `Terminal( text )` or *a bare string* - `NonTerminal( text )` - `Start({ label })` - *containers* - `Sequence( ...children )` - X `Stack( ...children )` - `Choice( index, ...children )` - `Optional( child [,"skip"] )` - `OneOrMore( child [,join] )` - `ZeroOrMore( child [,join [,"skip"]] )` ```js var root = Diagram; var labl = function( label ) { return Start({ label }); }; var sequ = Sequence; // var pipe = Choice; var pipe = function() { return Choice.apply( null, [ 0, ...arguments ] ); }; var ques = Optional; var star = ZeroOrMore; var plus = OneOrMore; var ws = NonTerminal( 'whitespace' ); var str = NonTerminal( 'string' ); var val = NonTerminal( 'value' ); ``` ## ie. json.org ```js Diagram( Start({ label: "object" }), '{', Choice( 0, ws, OneOrMore( Sequence( // XXX Stack( // XXX Sequence( ws, str, ), // XXX Sequence( // XXX ws, ':', val, ), // XXX ), // XXX ), ',', ), ), '}', ); ``` ... ### object ```js root( labl( "object" ), '{', pipe( ws, plus( sequ( ws, str, ws, ':', val, ), ',', ) ), '}', ); ``` ### array ```js root( labl( 'array' ), '[', pipe( ws, plus( val, ',' ) ), ']', ); ``` ### value ```js root( labl( "value" ), ws, pipe( str, NonTerminal( "number" ), NonTerminal( "object" ), NonTerminal( "array" ), "true", "false", "null", ), ws, ); ``` ### string ```js root( labl( "string" ), "\"", ques( plus( pipe( NonTerminal( "Any codepoint except \" or \\ or control characters" ), sequ( "\\", pipe( "\"", // quotation mark "\\", // reverse solidus "/", // solidus "b", // backspace "f", // formfeed "n", // linefeed "r", // carriage return "t", // horizontal tab sequ( "u", NonTerminal( "4 hex digits" ), ), ), ), ), ), ), "\"", ); ``` ### number ```js root( labl( "number" ), ques( "-" ), pipe( "0", sequ( NonTerminal( "digit 1-9" ), star( NonTerminal( "digit" ) ), ), ), ques( // fraction sequ( ".", plus( NonTerminal( "digit" ) ), ), ), ques( // exponent sequ( pipe( "E", "e" ), ques( pipe( "-", "+" ) ), // pipe( Skip(), "-", "+" ), plus( NonTerminal( "digit" ) ), ), ), ); ``` ### whitespace ```js root( labl( "whitespace" ), star( pipe( NonTerminal( "space" ), NonTerminal( "linefeed" ), NonTerminal( "carriage return" ), NonTerminal( "horizontal tab" ), ), ), ); ```