Skip to content

Syntax diagrams - WIP #93

New issue

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

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

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions assets/css/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,41 @@ html {
scrollbar-gutter: stable;
}

/* Railroad diagrams */
svg.railroad-diagram {
background-color:rgba(0,0,0,0);
}

svg.railroad-diagram path {
stroke-width:3;
stroke:black;
fill: rgba(0,0,0,0);
}

svg.railroad-diagram text {
font:bold 14px monospace;
text-anchor:middle;
}

svg.railroad-diagram text.label{
text-anchor:start;
}

svg.railroad-diagram text.comment{
font:italic 12px monospace;
}

svg.railroad-diagram rect{
stroke-width:3;
stroke: black;
fill: hsl(120,100%,90%);
}
svg.railroad-diagram rect.group-box {
stroke: gray;
stroke-dasharray: 10 5;
fill: none;
}

/* Chroma syntax highlighting
/* Background */
.bg {
Expand Down
22 changes: 2 additions & 20 deletions build/stack/syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,26 +82,8 @@ def syntax(self, **kwargs) -> str:

def diagram(self) -> DiagramItem:
if self._type == ArgumentType.COMMAND:
s = []
i = 0
optionals = []
while i < len(self._arguments):
arg = self._arguments[i].diagram()
if type(arg) is Optional:
optionals.append(arg)
else:
if len(optionals) != 0:
optionals.sort(key=lambda x: x.width)
s += optionals
optionals = []
s.append(arg)
i += 1
if len(optionals) != 0:
optionals.sort(key=lambda x: x.width)
s += optionals

self._stack.append(Sequence(Terminal(self._display)))
for arg in s:
for arg in [arg.diagram() for arg in self._arguments]:
if type(arg) is not Sequence:
items = [arg]
else:
Expand Down Expand Up @@ -176,7 +158,7 @@ def diagram(self) -> str:
d.writeSvg(s.write)
# Hack: strip out the 'width' and 'height' attrs from the svg
s = s.getvalue()
for attr in ['width', 'height']:
for attr in ['height']:
a = f'{attr}="'
x = s.find(a)
y = s.find('"', x + len(a))
Expand Down
26 changes: 22 additions & 4 deletions layouts/commands/single.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{{ define "head" }}
<script src="/js/cli.js" defer></script>
<script src="/js/codetabs.js" defer></script>
<script src="/js/syntax.js" defer></script>
{{ end }}

{{ define "main" }}
Expand Down Expand Up @@ -32,10 +33,27 @@ <h1 class="command-name">
{{ end }}
{{ end }}
{{ if (gt (len $syntax) 0) }}
<div class="font-semibold text-slate-900">Syntax</div>
<pre class="command-syntax">
{{- $syntax -}}
</pre>
<div class="flex gap-2 items-center">
<span class="font-semibold text-slate-900">Syntax</span>
<button id="syntax-button" tabindex="1" class="text-neutral-400 hover:text-slate-100 bg-slate-600 h-6 w-6 p-1 rounded-md" title="Toggle syntax" data-display="syntax" onclick="toggleSyntax(this)">
<svg id="icon-syntax" class="hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M0 0h24v24H0V0z" fill="none"/><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/>
</svg>
<svg id="icon-diagram" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<rect fill="none" height="24" width="24"/><path d="M14,9v2h-3V9H8.5V7H11V1H4v6h2.5v2H4v6h2.5v2H4v6h7v-6H8.5v-2H11v-2h3v2h7V9H14z M6,3h3v2H6V3z M9,21H6v-2h3V21z M9,13H6v-2 h3V13z M19,13h-3v-2h3V13z"/>
</svg>
</button>
</div>
<div class="relative border-2 border-red-600 rounded-lg">
<div id="display-diagram" class="hidden flex justify-center my-2">
{{ with .Resources.GetMatch "syntax.svg" }}{{ ( . | minify).Content | safeHTML }}{{ end }}
</div>
<div id="display-syntax">
<pre>
{{- $syntax -}}
</pre>
</div>
</div>
{{ end }}
<dl class="grid grid-cols-[auto,1fr] gap-x-2 mb-12">
{{ if not (isset .Params "module") }}
Expand Down
31 changes: 31 additions & 0 deletions static/js/syntax.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
function syntaxMode(mode) {
if (mode === 'diagram') {
document.querySelector('#icon-syntax').classList.remove('hidden');
document.querySelector('#display-diagram').classList.remove('hidden');
document.querySelector('#icon-diagram').classList.add('hidden');
document.querySelector('#display-syntax').classList.add('hidden');
} else {
document.querySelector('#icon-diagram').classList.remove('hidden');
document.querySelector('#display-syntax').classList.remove('hidden');
document.querySelector('#icon-syntax').classList.add('hidden');
document.querySelector('#display-diagram').classList.add('hidden');
}
}

function toggleSyntax(evt) {
const diagram = (evt.getAttribute('data-display') === 'diagram');
const attr = diagram ? 'syntax' : 'diagram';
evt.setAttribute('data-display', attr);
syntaxMode(attr);
if (window.localStorage) {
window.localStorage.setItem('selectedSyntax', attr);
}
}

document.addEventListener('DOMContentLoaded', () => {
if (window.localStorage) {
const mode = window.localStorage.getItem('selectedSyntax') || 'syntax';
document.querySelector('#syntax-button').setAttribute('data-display', mode);
syntaxMode(mode);
}
});