Skip to content
Merged
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
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

77 changes: 15 additions & 62 deletions theme/reference.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
/* Custom CSS for the Rust Specification. */

/* Per-theme variables. */
:root {
--railroad-background-color: hsl(30, 20%, 95%);
--railroad-background-image:
linear-gradient(to right, rgba(30, 30, 30, .05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(30, 30, 30, .05) 1px, transparent 1px);
--railroad-path-stroke: black;
--railroad-rect-stroke: black;
--railroad-rect-fill: hsl(-290, 70%, 90%);
}
.light {
--alert-note-color: #0969da;
--alert-warning-color: #9a6700;
Expand Down Expand Up @@ -45,14 +36,6 @@
.coal, .navy, .ayu {
--grammar-comment-color: lch(from var(--quote-bg) calc(l + 50) 0 0);
--inline-code-color: var(--grammar-comment-color);
--railroad-background-color: hsl(230, 10%, 20%);
--railroad-background-image:
linear-gradient(to right, rgba(150, 150, 150, .05) 1px, transparent 1px),
linear-gradient(to bottom, rgba(150, 150, 150, .05) 1px, transparent 1px);
--railroad-path-stroke: hsl(200, 10%, 60%);
--railroad-text-fill: hsl(230, 30%, 80%);
--railroad-rect-stroke: hsl(200, 10%, 50%);
--railroad-rect-fill: hsl(230, 20%, 20%);
}

/*
Expand Down Expand Up @@ -686,55 +669,25 @@ main > .rule {
display: none;
}

svg.railroad {
background-color: var(--railroad-background-color);
background-size: 15px 15px;
background-image: var(--railroad-background-image);
}

svg.railroad rect.railroad_canvas {
stroke-width: 0px;
fill: none;
}

svg.railroad path {
stroke-width: 3px;
stroke: var(--railroad-path-stroke);
fill: none;
}

svg.railroad .debug {
stroke-width: 1px;
stroke: red;
}

svg.railroad text {
font: 14px monospace;
text-anchor: middle;
fill: var(--railroad-text-fill);
}

svg.railroad .nonterminal text {
font-weight: bold;
}

svg.railroad text.comment {
font: italic 12px monospace;
}
/*
The theme-specific railroad backgrounds intentionally match mdBook's page
backgrounds. Offset only their lightness here so embedded diagrams remain
visually distinct while retaining each theme's hue and saturation. The Light
railroad theme already provides this contrast itself.

svg.railroad rect {
stroke-width: 3px;
stroke: var(--railroad-rect-stroke);
fill: var(--railroad-rect-fill);
Including `html` makes these selectors more specific than the stylesheets
embedded by mdbook-spec.
*/
html.rust svg.railroad {
background-color: hsl(from var(--bg) h s calc(l - 5));
}

svg.railroad g.labeledbox>rect {
stroke-width: 1px;
stroke: grey;
stroke-dasharray: 5px;
fill: rgba(90, 90, 150, .1);
html.coal svg.railroad,
html.navy svg.railroad,
html.ayu svg.railroad {
background-color: hsl(from var(--bg) h s calc(l + 5));
}

/* Styling specific to the Reference's negative-lookahead railroad node. */
svg.railroad g.exceptbox > rect {
fill:rgba(245, 160, 125, .1);
}
2 changes: 1 addition & 1 deletion tools/mdbook-spec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mdbook-markdown = "0.5.1"
mdbook-preprocessor = "0.5.1"
once_cell = "1.19.0"
pathdiff = "0.2.1"
railroad = { version = "0.3.7", default-features = false }
railroad = { version = "0.3.9", default-features = false }
regex = "1.12.2"
semver = "1.0.21"
serde_json = "1.0.113"
Expand Down
11 changes: 10 additions & 1 deletion tools/mdbook-spec/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,16 @@ pub fn insert_grammar(grammar: &Grammar, chapter: &Chapter, diag: &mut Diagnosti
.unwrap();
}
}
content

// Inject the stylesheets for railroad diagrams if necessary
if content.contains("class=\"railroad\"") {
format!(
"<style type=\"text/css\">\n{}\n</style>\n\n{content}",
render_railroad::themed_stylesheets()
)
} else {
content
}
}

/// Converts link reference definitions that point to a grammar rule
Expand Down
41 changes: 41 additions & 0 deletions tools/mdbook-spec/src/grammar/render_railroad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,30 @@ const CHOICE_MAX_ROWS_PER_COLUMN: usize = 5;
/// use as many rows as necessary
const CHOICE_MAX_COLUMNS: usize = 4;

/// Returns the railroad stylesheets, scoped to their corresponding mdBook themes.
///
/// mdBook selects a theme by placing its lowercase name on the root element. Scoping
/// each railroad stylesheet to that class lets the diagrams follow theme changes at
/// runtime without duplicating the styles in every SVG.
pub(super) fn themed_stylesheets() -> String {
const THEMES: [(&str, Stylesheet); 5] = [
("light", Stylesheet::Light),
("rust", Stylesheet::Rust),
("coal", Stylesheet::Coal),
("navy", Stylesheet::Navy),
("ayu", Stylesheet::Ayu),
];

let mut css = String::new();
for (theme, stylesheet) in THEMES {
let selector = format!(".{theme} svg.railroad");
// Re-scope the selectors in each stylesheet, so they are scoped only to the selected theme
let scoped = stylesheet.stylesheet().replace("svg.railroad", &selector);
writeln!(css, "/* mdBook {theme} theme. */\n{scoped}").unwrap();
}
css
}

pub fn render_railroad(
grammar: &Grammar,
cx: &RenderCtx,
Expand Down Expand Up @@ -448,6 +472,23 @@ mod tests {
})
}

#[test]
fn railroad_stylesheets_are_scoped_to_mdbook_themes() {
let css = themed_stylesheets();

for theme in ["light", "rust", "coal", "navy", "ayu"] {
assert!(
css.contains(&format!(".{theme} svg.railroad {{")),
"missing stylesheet for the {theme} theme"
);
}
assert!(
css.lines()
.all(|line| !line.trim_start().starts_with("svg.railroad")),
"railroad styles must not leak into the other mdBook themes"
);
}

// -- RepeatRange tests --

#[test]
Expand Down
Loading