Giter Club home page Giter Club logo

rr's Introduction

RR

RR - Railroad Diagram Generator

RR is a generator of syntax diagrams, also known as railroad diagrams. It is a self-contained tool with both a browser-based GUI and a batch mode.

Besides generating diagrams from EBNF rules, RR also can perform some grammar transformation, e.g. factorization and elimination of direct recursion. To some extent this transforms BNF to EBNF, yielding more compact diagrams.

Examples

Here are two examples of generated diagrams (taken from the Python grammar):

if_stmt:

if_stmt

try_stmt:

try_stmt

Grammar syntax

RR accepts grammars in W3C-style EBNF. Some other representations, including some parser generator input notations, can be converted to W3C-style using the ebnf-convert Grammar Converter (note: IPv6-only). This tool is also available on GitHub.

Distribution

RR comes as a .zip, containing a .war file. The .war file can be deployed in servlet containers like Tomcat or Jetty for serving the GUI. This makes up the webapp that is running on the original website, https://www.bottlecaps.de/rr/ui (note: IPv6-only, see Links below for alternatives).

The .war file is a Java "executable war", i.e. it can also be started standalone from command line. Two different tasks can be performed in standalone mode:

  • serving the GUI, e.g.
   java -jar rr.war -gui
  • batch diagram generation, e.g.
   java -jar rr.war grammar.ebnf

For listing the full set of available options, run

   java -jar rr.war

without further command line arguments.

Building RR

For building RR, JDK 11 (or higher) must be available. In the project folder, run this command to build the distribution .zip file:

gradlew

Thanks

This project makes use of

License

RR is released under the Apache 2 License.

Links

The official website for RR is https://www.bottlecaps.de/rr/ui (note: IPv6-only).

Thanks to Vinay Sajip, RR also runs on https://rr.red-dove.com/ui (IPv4 accessible).

rr's People

Contributors

alerque avatar bannmann avatar dependabot[bot] avatar guntherrademacher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rr's Issues

CONVERT fails on a valid JavaCC Grammar

Greetings Gunther.

A certain valid JavaCC Grammar is failing with multiple constructs.
(Although the Grammar is building fine with JavaCC).

Since Convert is not public, I can only escalate this to you.
Thank you in advance for looking into it.
Cheers!

parser_tmp.jjt.zip

Failed to eliminate direct left recursion from this production

Using the RR site to plot a graph, this recursive grammar (which I don't know if is valid input):

whitespace ::= ('space')+ | ('linefeed')+ | ('carriage return')+ | ('horizontal tab')+ | (whitespace)+

generates an exception:

HTTP Status 500 – Internal Server Error
Type Exception Report

Message failed to eliminate direct left recursion from this production:

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

java.lang.RuntimeException: failed to eliminate direct left recursion from this production:
  whitespace
           ::= 'space'+
             | 'linefeed'+
             | 'carriage return'+
             | 'horizontal tab'+
             | whitespace+
result was:
whitespace
           ::= ( 'space'+ | 'linefeed'+ | 'carriage return'+ | 'horizontal tab'+ | whitespace+ ) ( )*
	de.bottlecaps.railroad.webapp.RailroadWebApp.doRequest(RailroadWebApp.java:185)
	de.bottlecaps.railroad.webapp.RailroadServlet.doPost(RailroadServlet.java:31)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

net.sf.saxon.s9api.SaxonApiException: failed to eliminate direct left recursion from this production:
  whitespace
           ::= 'space'+
             | 'linefeed'+
             | 'carriage return'+
             | 'horizontal tab'+
             | whitespace+
result was:
whitespace
           ::= ( 'space'+ | 'linefeed'+ | 'carriage return'+ | 'horizontal tab'+ | whitespace+ ) ( )*
	net.sf.saxon.s9api.XQueryEvaluator.evaluate(XQueryEvaluator.java:433)
	de.bottlecaps.railroad.webapp.RailroadWebApp.doRequest(RailroadWebApp.java:147)
	de.bottlecaps.railroad.webapp.RailroadServlet.doPost(RailroadServlet.java:31)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Root Cause

net.sf.saxon.functions.Error$UserDefinedXPathException: failed to eliminate direct left recursion from this production:
  whitespace
           ::= 'space'+
             | 'linefeed'+
             | 'carriage return'+
             | 'horizontal tab'+
             | whitespace+
result was:
whitespace
           ::= ( 'space'+ | 'linefeed'+ | 'carriage return'+ | 'horizontal tab'+ | whitespace+ ) ( )*
	net.sf.saxon.functions.Error.error(Error.java:66)
	net.sf.saxon.functions.Error.call(Error.java:111)
	net.sf.saxon.expr.FunctionCall.iterate(FunctionCall.java:543)
	net.sf.saxon.expr.Expression.process(Expression.java:948)
	net.sf.saxon.expr.SystemFunctionCall.process(SystemFunctionCall.java:476)
	net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:910)
	net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:729)
	net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:908)
	net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:136)
	net.sf.saxon.expr.ForExpression.lambda$process$0(ForExpression.java:399)
	net.sf.saxon.om.SequenceIterator.forEachOrFail(SequenceIterator.java:135)
	net.sf.saxon.expr.ForExpression.process(ForExpression.java:397)
	net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:738)
	net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:136)
	net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:346)
	net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:292)
	net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:136)
	net.sf.saxon.expr.parser.ExpressionTool.getItemFromProcessMethod(ExpressionTool.java:663)
	net.sf.saxon.expr.instruct.Instruction.evaluateItem(Instruction.java:334)
	net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:959)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:151)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:148)
	net.sf.saxon.expr.instruct.UserFunction.call(UserFunction.java:633)
	net.sf.saxon.expr.UserFunctionCall.callFunction(UserFunctionCall.java:538)
	net.sf.saxon.expr.UserFunctionCall.evaluateItem(UserFunctionCall.java:472)
	net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:959)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:151)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:148)
	net.sf.saxon.expr.LetExpression.eval(LetExpression.java:537)
	net.sf.saxon.expr.LetExpression.evaluateItem(LetExpression.java:559)
	net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:959)
	net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:959)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:151)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:148)
	net.sf.saxon.expr.instruct.UserFunction.call(UserFunction.java:633)
	net.sf.saxon.expr.UserFunctionCall.callFunction(UserFunctionCall.java:538)
	net.sf.saxon.expr.UserFunctionCall.evaluateItem(UserFunctionCall.java:472)
	net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:959)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:151)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:148)
	net.sf.saxon.expr.LetExpression.eval(LetExpression.java:537)
	net.sf.saxon.expr.LetExpression.evaluateItem(LetExpression.java:559)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:151)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:148)
	net.sf.saxon.expr.instruct.UserFunction.call(UserFunction.java:633)
	net.sf.saxon.expr.UserFunctionCall.callFunction(UserFunctionCall.java:538)
	net.sf.saxon.expr.UserFunctionCall.evaluateItem(UserFunctionCall.java:472)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:151)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:148)
	net.sf.saxon.expr.UserFunctionCall.evaluateArguments(UserFunctionCall.java:637)
	net.sf.saxon.expr.UserFunctionCall.evaluateArguments(UserFunctionCall.java:619)
	net.sf.saxon.expr.UserFunctionCall.callFunction(UserFunctionCall.java:513)
	net.sf.saxon.expr.UserFunctionCall.iterate(UserFunctionCall.java:482)
	net.sf.saxon.expr.CardinalityChecker.iterate(CardinalityChecker.java:212)
	net.sf.saxon.expr.LetExpression.iterate(LetExpression.java:519)
	net.sf.saxon.expr.instruct.Choose.iterate(Choose.java:981)
	net.sf.saxon.expr.LetExpression.iterate(LetExpression.java:519)
	net.sf.saxon.value.MemoClosure.makeSequence(MemoClosure.java:86)
	net.sf.saxon.value.MemoClosure.iterate(MemoClosure.java:80)
	net.sf.saxon.expr.UserFunctionCall.iterate(UserFunctionCall.java:482)
	net.sf.saxon.expr.instruct.Choose.iterate(Choose.java:981)
	net.sf.saxon.expr.instruct.Choose.iterate(Choose.java:981)
	net.sf.saxon.expr.instruct.Choose.iterate(Choose.java:981)
	net.sf.saxon.expr.instruct.Choose.iterate(Choose.java:981)
	net.sf.saxon.value.MemoClosure.makeSequence(MemoClosure.java:86)
	net.sf.saxon.value.MemoClosure.iterate(MemoClosure.java:80)
	net.sf.saxon.expr.VariableReference.iterate(VariableReference.java:555)
	net.sf.saxon.expr.SlashExpression.iterate(SlashExpression.java:922)
	net.sf.saxon.functions.Exists$1.effectiveBooleanValue(Exists.java:64)
	net.sf.saxon.expr.instruct.Choose.choose(Choose.java:930)
	net.sf.saxon.expr.instruct.Choose.evaluateItem(Choose.java:958)
	net.sf.saxon.expr.LetExpression.evaluateItem(LetExpression.java:567)
	net.sf.saxon.expr.TailCallLoop.evaluateItem(TailCallLoop.java:121)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:151)
	net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:148)
	net.sf.saxon.expr.TailCallLoop.tailCallDifferentFunction(TailCallLoop.java:189)
	net.sf.saxon.expr.TailCallLoop.iterate(TailCallLoop.java:107)
	net.sf.saxon.value.MemoClosure.makeSequence(MemoClosure.java:86)
	net.sf.saxon.value.MemoClosure.iterate(MemoClosure.java:80)
	net.sf.saxon.expr.UserFunctionCall.iterate(UserFunctionCall.java:482)
	net.sf.saxon.query.XQueryExpression.iterator(XQueryExpression.java:370)
	net.sf.saxon.s9api.XQueryEvaluator.evaluate(XQueryEvaluator.java:428)
	de.bottlecaps.railroad.webapp.RailroadWebApp.doRequest(RailroadWebApp.java:147)
	de.bottlecaps.railroad.webapp.RailroadServlet.doPost(RailroadServlet.java:31)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Note The full stack trace of the root cause is available in the server logs.

The rr site (server) is down

Hi @GuntherRademacher , thanks for this very excellent tool!

I use it for https://github.com/VladimirAlexiev/grammar-diagrams to generate SPARQL, XSPARQL and SHACLC diagrams.
It and https://github.com/GuntherRademacher/ebnf-convert are discussed to be used in upcoming SHACLC standardization:
w3c/shacl#37.

We found that the site http://bottlecaps.de/rr/ui is down.
I checked 5 historic versions at archive.org, but they all return various rendering errors. Could you please take a look? Thanks!

@pchampin Would W3C be willing to host this tool?

Feature Request: Comment all that is not extracted

First, thanks a lot to share this nice job.

I use your tool to describe a grammar that is in between computing and true language. I managed to do almost everything I needed.

But I want to use it as a documentation. I mean, I want to put classical HTML before and after elements.

As far as I've seen, your tool can extract elements from URL. But it removes the rest. You can make your changes and then regenerate but hence, you have to put all your "documentation" back and it's not easy.

It would be great if we could use special markup in our HTML page to keep the content as comments that would be rendered as HTML by your "view diagram".

I mean:

/!*
<h1> Title 1 </h1>
<p> lorem ipsum....</p>
!*/

Grammar ::= Production*
Production ::= NCName '::=' ( Choice | Link )
NCName ::= [http://www.w3.org/TR/xml-names/#NT-NCName]
Choice ::= SequenceOrDifference ( '|' SequenceOrDifference )*

/!*
<h1> Title 2 </h1>
<p> lorem ipsum....</p>
!*/

...

Would render:

<!--RR-begin Here begin an html zone-->
<h1> Title 1 </h1>
<p> lorem ipsum....</p>
<!--RR-end Here end an html zone-->

Rendering of EBNF

<!--RR-begin Here begin an html zone-->
<h1> Title 2 </h1>
<p> lorem ipsum....</p>
<!--RR-end Here end an html zone-->

...

Which in turns could be again extracted to:

/!*
<h1> Title 1 </h1>
<p> lorem ipsum....</p>
!*/

Grammar ::= Production*
Production ::= NCName '::=' ( Choice | Link )
NCName ::= [http://www.w3.org/TR/xml-names/#NT-NCName]
Choice ::= SequenceOrDifference ( '|' SequenceOrDifference )*

/!*
<h1> Title 2 </h1>
<p> lorem ipsum....</p>
!*/

...

It would be so practical to edit and modify our documentation.

Best regards,

Your website (www.bottlecaps.de) seems to be down for users who don't have IPv6 - any plans to fix that?

Thanks very much for this software, it's really useful and looks very nice, too! I've noticed over the past week that I can't access www.bottlecaps.de any more from my home network (which is running IPv4 only - no IPv6 support). I've confirmed that DNS appears to only return an IPv6 address:

$ nslookup www.bottlecaps.de
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
www.bottlecaps.de	canonical name = bottlecaps.dynv6.net.
Name:	bottlecaps.dynv6.net
Address: 2a00:6020:5044:f400:92b1:1cff:fe97:fdae

Do you have any plans to reinstate IPv4 support?

Bad parsing?

This doesn't get well parsed, IIUC:
Byte::= [ #x00 - #xFF ]

Should be a CharCode range. And each CharCode gets expanded to 4 digits.

No way for strings with both single/double quotes inside

Looking the grammar for strings there is now escape sequence for strings that contains both single/double quotes but the W3C grammar does have it:

StringLiteral ::= '"' [^"]* '"' | "'" [^']* "'" /* ws: explicit */
StringLiteral	   ::=   	('"' (PredefinedEntityRef | CharRef | EscapeQuot | [^"&])* '"') | ("'" (PredefinedEntityRef | CharRef | EscapeApos | [^'&])* "'")	/* ws: explicit */
PredefinedEntityRef	   ::=   	"&" ("lt" | "gt" | "amp" | "quot" | "apos") ";"	/* ws: explicit */
EscapeQuot	   ::=   	'""'
EscapeApos	   ::=   	"''"

Direct recursion elimination produces duplicate path

Thanks for this excellent tool. I use it to visualize a SQL grammar. Here's a small excerpt of the grammar to reproduce the problem:

dataType ::=
      oracleBuiltInDatatype
    | ansiSupportedDatatype
    | postgresqlDatatype
    | userDefinedType
    | dataType (LSQB RSQB)+

LSQB ::=  '['
RSQB ::=  ']'

I use the following settings with the current version (8773d49) of the master branch.

image

The result looks like this:

image

I highlighted the duplicate path.

The result looks good when I disable the "Direct recursion elimination" option. Like this:

image

Disabling the option as a workaround is good enough for me.

Maybe a mistake in the 'rr' grammar ?

Trying to implement rr grammar with CocoR https://ssw.jku.at/Research/Projects/Coco/ it seems that there is a mistake in the rr grammar for the production item:

Item                  ::= Primary ( '?' | '*' | '+' )*

If I understood it correctly it should be:

Item                  ::= Primary ( '?' | '*' | '+' )?

Because constructs like this are invalid, isn't it ?

Item                  ::= Primary ( '?' | '*' | '+' )*?+  //zero or more *?+ after ')'

Cheers !

Consider project rename to avoid packaging confilcs

From #27 with is starting to wander off topic...

I'm now looking at packaging rr in adition to ebnf-convert, and it looks like the "rr" name is already staked out by another project not only on Arch Linux but Debian, Ubuntu, Alt Linux, Apertis, Deepin, Duvuan, EPEL, Fedora, Gentoo, Guix, Kali, Nix, openSUSE, Pardus, Void, and many others see repology.

I can rename it in packaging, but again if you would consider either renaming it here or at least suggesting a "sanctioned" alternative name like ebnf-rr, ebnf-railroad (both 100% clear) or perhaps just railroad (a bit sketchy because existing Python and Ruby project exist so package names might still be different with this name but /usr/bin/roalroad would probably be available)? That way any other distros trying to follow suite and documentation about how to run on different platforms could be consistent.

Bug parsing brackets within brackets

Constant ::= [+-\{\}\[\]]

This fails with syntax error. Tried many combinations of \ to escape the characters, none is working correctly.

Grammar doesn't specify (or may be I haven't looked properly) but is there a special way to escape these characters?

Add Index and/or TOC

Greetings.

Please, would it be possible to add an Index and/or TOC to the HTML output in order to navigate in very long HTML files with a lot of productions.

Example: http://manticore-projects.com/JSQLFormatter/syntax.html#

I have post-added this by parsing the XHTML file via XPATH. It works somehow, but yields in an extra step and the heavy JSOUP/SAXON dependencies.

    private static String stripTrailing(String s, String suffix) {
        if (s.endsWith(suffix))
            return s.substring(0, s.length() - suffix.length());
        else
            return s;
    }

    public static void insertTOC(File file) throws IOException {
        System.setProperty(W3CDom.XPathFactoryProperty, "net.sf.saxon.xpath.XPathFactoryImpl");

        Document doc = Jsoup.parse(file, "UTF-8", "", Parser.xmlParser());
        Elements elements = doc.selectXpath("//*[local-name()='a' and not(@href) and @name]");

        ArrayList<String> tocEntries = new ArrayList<>();
        TreeSet<String> indexEntries = new TreeSet<>();

        for (Element link : elements) {
            String key = stripTrailing(link.text(), ":");
            tocEntries.add(key);
            indexEntries.add(key);
        }

        Element tocElement = doc.body().prependElement("H1");
        tocElement.text("Table of Content:");
        tocElement.attr("style", "font-size: 14px; font-weight:bold");

        Element pElement = tocElement.appendElement("p");
        pElement.attr("style", "font-size: 11px; font-weight:normal");
        for (String s : tocEntries) {
            pElement.appendElement("a").attr("href", "#" + s).text(s);
            pElement.appendText(" ");
        }

        Element indexElement = doc.body().prependElement("H1");
        indexElement.text("Index:");
        indexElement.attr("style", "font-size: 14px; font-weight:bold");

        pElement = indexElement.appendElement("p");
        pElement.attr("style", "font-size: 11px; font-weight:normal");
        for (String s : indexEntries) {
            pElement.appendElement("a").attr("href", "#" + s).text(s);
            pElement.appendText(" ");
        }

        FileUtils.writeStringToFile(file, doc.outerHtml(), StandardCharsets.UTF_8);
    }

Dark themes in markdown viewers

Feature request:

When using a dark theme (dark background) in your markdown viewer you can hardly see the stroke color.
It would be great to have:

  • An option stoke color to specify the stroke color.
  • An option background color to specify the color of a non-transparent background.

How to generate font width tables?

Hi @GuntherRademacher, thanks very much for open sourcing this! It's a huge help. If you have a minute, could you shed some light on how you generated the font width tables in Normal.java and Bold.java? (I'd like to swap them out for a different font.) Thanks very much!

Proxy Error after large request

I've encountered a Problem where a request to render my EBNF code led to a Proxy Error on multiple devices for a longer period of time.

I simply asked the server to render a very large EBNF. The request was processed and the result was the as before stated error.

The code i used was something like this:
EBNF Nightmare.txt

Of course, this is just example code. But the server should probably return an error when too large data is sent instead of crashing.

[question] batch mode via http request?

I am using rr in batch mode to process a set of ebnf files as suggested in the readme. java -jar rr.war grammar.ebnf
It works fine but is a little slow when processing many files due to the Java startup time.

Is there a way to POST an ebnf (and maybe options) to the RR server and directly get back the xhtml doc?
I am looking for something similar to the REx web page https://www.bottlecaps.de/rex/

Can't have close square brackets escaped inside ranges

Testing a bash grammar I found that rr doesn't accept close square bracket escaped inside ranges (open square brackets it's OK):

nonsquarebra ::=  [^\[\]]

Output:

lexical analysis failed
while expecting [Whitespace, NCName, StringLiteral, CharCode, '/*ws:explicit*/', '/*ws:definition*/', DocComment, EOF, EquivalenceLookAhead, '$', '&', '(', ')', '*', '+', '-', '.', '/', '<?', '<?ENCORE?>', '<?TOKENS?>', '?', '[', '[^', '|']
at line 1, column 25:
...]...

Slight variation in production leads to "backwards" display

The following production

key_value ::= ( key ( ':' | '=' ) value ( ',' | EOL )? EOL* )*

leads to diagram

ss27

However, adding EOL* to the beginning of the production

key_value ::= EOL* ( key ( ':' | '=' ) value ( ',' | EOL )? EOL* )*

leads to

ss28

which, while not wrong, can confuse the reader because of the right-to-left ordering of key and value in the diagram. Is there a workaround for this? I tried changing some of the options but nothing caused left-to-right display of key and value.

Ability to output just the diagrams

It would be useful for the integration with asciidoctor to have the ability to emit just the diagrams (without xhtml/html content) this would make it practical to integrate rr with a tool like kroki or asciidoctor-diagram.

An option to select which production rule to generate as a single image and the ability to generate multiple rules into one image would also be useful.

Feature request: drop-down diagrams

It would be great to be able to view the whole railroad diagram or choose which production rules to reveal. From:
image
to:
image
by one click, and, if necessary, return it back (to be able to abstract away from primitive and understandable production rules ­- syntax for URLs as example). This will help in cases where a grammar is cumbersome

It would be nice to allow textual annotations in the grammar

A language of any complexity is not just defined by its syntax, but also its semantics. Currently there is no way to annotate (or describe) the grammar rules in natural language.
Consider a rule defining integer literals:

IntegerLiteral = digit+

It is certainly correct, but the reader needs to know that what the maximum allowed literal is. It would be very nice to be able to generate:

IntegerLiteral = digit+
// Integer literals may not exceed unsigned values in 32 bits.

The text in comments should be provided (just like you can do for the actual grammar rule) in the generated HTML.

I realize that you get away with using the -png option and then merging the generated HTML file with the comments, but it is a hassle to maintain.

Do not generate duplicated svg styles

It seems that is possible to not emit the same style in each svg and still been able to view it correctly, saving around 1/4 of the actual xhtml.

---------- src/main/resources/de/bottlecaps/railroad/xq/ast-to-svg.xq ----------
@@ -1053,7 +1054,6 @@ declare function s:convert-to-svg($p as element(g:production), $page-width as xs
     <svg xmlns="http://www.w3.org/2000/svg"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          width="{$width + 1}" height="{$height + 1}">
-      <defs>{s:style($color, $spread)}</defs>
       {
         s:translate(1 - xs:integer($dimensions/@x1), 1 - xs:integer($dimensions/@y1), $rendered)
       }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.