Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Allow railroad diagrams to be specified in JSON and generated with a single invocation #20

Open
rogerdielrton opened this issue May 14, 2014 · 9 comments · May be fixed by #78
Open

Allow railroad diagrams to be specified in JSON and generated with a single invocation #20

rogerdielrton opened this issue May 14, 2014 · 9 comments · May be fixed by #78

Comments

@rogerdielrton
Copy link

Why "ZeroOrMore", "Choice", etc. are nested JS function calls?
Why are you not implemented it as JSON (JS objects)?

@tabatkins
Copy link
Owner

Because JS calls work great for just generating a diagram, and are simpler to write.

l assume you want to pass diagram data around as JSON and then generate a diagram from it afterwards? That seems like a pretty useful thing to do, so I'm okay with adding this functionality.

@rogerdielrton
Copy link
Author

Is just that: the separation of data and program phylosophy.
I create a data structure, manipulate it, and, when finish,
invoke a metohd to generate the diagram from it.

Thanks in advance.

@tabatkins
Copy link
Owner

Keeping this open to track the request.

@tabatkins tabatkins changed the title Railroad metadata as JSON instead of JS funcions Allow railroad diagrams to be specified in JSON and generated with a single invocation May 14, 2014
@ghost
Copy link

ghost commented Apr 7, 2016

I’ve made this little script and it might be helpful (i don’t test all the possibilities).

function createDiagram(node) {
  let stack = [];

  if (Array.isArray(node)) {
    for (let value of node) {
      if (typeof value.value === 'object') {
        if (typeof window[value.type] === 'function') {
          stack.push(window[value.type].apply(null, createDiagram(value.value)));
        }
      } else {
        stack.push.apply(stack, createDiagram.call(this, value));
      }
    }
  } else if (typeof window[node.type] === 'function') {
    stack.push(window[node.type](node.value));
  }

  return stack;
}

Usage

let obj = [
  { type: 'Terminal', value: 'yield' },
  { type: 'Terminal', value: '[' },
  { type: 'NonTerminal', value: 'yield_arg' },
  { type: 'Terminal', value: ']' },
  { type: 'Stack', value: [
    { type: 'Terminal', value: 'stacked!' },
    { type: 'Terminal', value: 'yaaay' }
  ]}
];
let diagram = Diagram.apply(null, createDiagram(obj));

@Paebbels
Copy link

What's the status?

@prantlf
Copy link
Contributor

prantlf commented Apr 26, 2020

While implementing a method parsing the diagram from JSON is straightforward, deciding on the format may need more discussion. For example,. mine got inspired by the JavaScript AST from the ESTree specification.

@prantlf
Copy link
Contributor

prantlf commented Apr 26, 2020

After rewriting all examples from examples.html to YAML (#78 and #80) I became quite fluent in authoring diagrams in YAML. And I also felt that the source format is quite verbose, when using an AST-like approach to the language.

While JSON or YAML are good for machine generation ans consumption, I wonder if it makes sense to have some other DSL for hand-made diagrams, apart from the JavaScript functions. For example:

Sequence:
  Terminal: #
  NonTerminal: Letter, #letter
  Choice:
    NonTerminal: "Letter or _", #letter-or-_
    NonTerminal: Digit, #digit

It would speed up writing diagrams manually, but would anyone learn a new "RRD" language?

@tabatkins
Copy link
Owner

In fact I already have exactly such a DSL for my Bikeshed tool, which I just haven't ported back to the mainline repo yet: code is https://github.com/tabatkins/bikeshed/blob/master/bikeshed/railroadparser.py, docs are https://tabatkins.github.io/bikeshed/#railroad

@Epithumia
Copy link

Seeing as there wasn't much activity here and that what prantlf did was only for js, I took it on myself to make a full-fledged python CLI (https://github.com/Epithumia/pyrailroad) to parse DSL/JSON/YAML source diagrams based on your code, if it's any use for others looking at the issue here.

In the coming days/weeks (my holidays are over very soon, and due to extensive reformatting/sonarqube QC, I can't just diff files and be done, so it'll take a little time to upstream everything), I'll PR some bugfixes/additions I encountered/made in both railroad.py (like the duplicated text elements when using href in Terminal/NonTerminal/Comment) and the bikeshed parser (adding unsupported DiagramItems and allowing urls in the Terminal/NonTerminal/Comment preludes, notably).

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants