GuntherRademacher / rr

RR - Railroad Diagram Generator
Apache License 2.0
464 stars 51 forks source link

Ability to output just the diagrams #5

Open lorrden opened 3 years ago

lorrden commented 3 years ago

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.

GuntherRademacher commented 3 years ago

Using option "-png" on command line (or "HTML+PNG" in UI "Download diagram") produces a .zip that has one X.png for each production X.

chtenb commented 2 years ago

Is this also possible for embeddable svg?

chtenb commented 2 years ago

Related: https://github.com/yuzutech/kroki/issues/6

zopsicle commented 2 years ago

You can extract the SVGs from the XHTML file using various XML processing tools. Here is an example Bash script that uses Xidel with XQuery to extract the rule names and then to extract each corresponding SVG (assuming rr was already invoked to generate the XHTML file):

#!/usr/bin/env bash

# This script takes the XHTML file generated by Railroad,
# then extracts each rule’s diagram into its own SVG file.

set -o errexit
set -o nounset
set -o pipefail

if (( $# != 2 )); then
    1>&2 echo "Usage: $0 <in-file> <out-dir>"
    exit 1
fi

in_file=$1
out_dir=$2

# Extract the name of each rule in the grammar.
# This selects the name attribute of the hyperlink preceding the rule’s SVG.
extract_rule_names() {
    xidel "$1"                                                    \
        --input-format xml                                        \
        --xquery '/html/body/svg/preceding-sibling::p[1]/a/@name'
}

# Extract the SVG diagram of the rule.
extract_rule_diagram() {
    xidel "$1"              \
        --input-format xml  \
        --output-format xml \
        --xquery '
            for $svg in /html/body/svg
            where $svg/preceding-sibling::p[1]/a/@name = "'"$2"'"
            return $svg
        '
}

# Find rules, then extract each SVG into a file.
mkdir --parents "$out_dir"
extract_rule_names "$in_file" | while IFS= read -r rule_name; do
    extract_rule_diagram "$in_file" "$rule_name" > "$out_dir/$rule_name.svg"
done
GuntherRademacher commented 1 year ago

Is this also possible for embeddable svg?

v2.0 now can create a .zip containing .svg files, where each .svg is self-contained.