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
14 changes: 14 additions & 0 deletions dev-guide/src/grammar.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,19 @@ The [`mdbook-spec`] plugin automatically adds Markdown link definitions for all

In some cases, there might be name collisions with the automatic linking of rule names. In that case, disambiguate with the `grammar-` prefix, such as `[Type][grammar-Type]`. The prefix can also be used when explicitness would aid clarity.

Production names can also be used in link reference definitions to provide custom link text, both with and without the `grammar-` prefix.

```markdown
We accept any [type].

[type]: grammar-Type
```

```markdown
We accept any [type].

[type]: Type
```

[`mdbook-spec`]: tooling/mdbook-spec.md
[Notation]: https://doc.rust-lang.org/nightly/reference/notation.html
4 changes: 4 additions & 0 deletions dev-guide/src/links.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ Link definitions are automatically generated for all grammar production names. S
This attribute uses the [MetaWord] syntax.

Explicit grammar links can have the `grammar-` prefix like [Type][grammar-Type].

Grammar links can also appear in link reference definitions, e.g. [type].

[type]: grammar-Type
```

## Outside book links
Expand Down
41 changes: 41 additions & 0 deletions tools/mdbook-spec/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,47 @@ pub fn insert_grammar(grammar: &Grammar, chapter: &Chapter, diag: &mut Diagnosti
content
}

/// Converts link reference definitions that point to a grammar rule
/// to the correct link.
///
/// For example:
///
/// ```markdown
/// We accept any [token].
///
/// [token]: grammar-Token
/// ```
///
/// This will convert the `[token]` definition to point
/// to the actual link.
///
/// This supports both a `grammar-` prefixed form (e.g.
/// `grammar-Token`) and a bare rule name (e.g. `Token`).
pub fn grammar_link_references(chapter: &Chapter, grammar: &Grammar) -> String {
let current_path = chapter.path.as_ref().unwrap().parent().unwrap();
let for_summary = is_summary(chapter);
crate::MD_LINK_REFERENCE_DEFINITION
.replace_all(&chapter.content, |caps: &Captures<'_>| {
let dest = &caps["dest"];
let name = dest.strip_prefix("grammar-").unwrap_or(dest);
if let Some(production) = grammar.productions.get(name) {
let label = &caps["label"];
let relative = pathdiff::diff_paths(&production.path, current_path).unwrap();
// Adjust paths for Windows.
let relative = relative.display().to_string().replace('\\', "/");
let id = render_markdown::markdown_id(name, for_summary);
if for_summary {
format!("[{label}]: #{id}")
} else {
format!("[{label}]: {relative}#{id}")
}
} else {
caps.get(0).unwrap().as_str().to_string()
}
})
.to_string()
}

/// Creates a map of production name -> relative link path.
fn make_relative_link_map(grammar: &Grammar, chapter: &Chapter) -> HashMap<String, String> {
let current_path = chapter.path.as_ref().unwrap().parent().unwrap();
Expand Down
1 change: 1 addition & 0 deletions tools/mdbook-spec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ impl Preprocessor for Spec {
}
ch.content = admonitions::admonitions(&ch, &mut diag);
ch.content = self.rule_link_references(&ch, &rules);
ch.content = grammar::grammar_link_references(&ch, &grammar);
ch.content = self.auto_link_references(&ch, &rules);
ch.content = self.render_rule_definitions(&ch.content, &tests, &git_ref);
if ch.name == "Test summary" {
Expand Down