Skip to content

Commit e99e829

Browse files
committed
add globals links
1 parent 35bb4f5 commit e99e829

File tree

4 files changed

+92
-28
lines changed

4 files changed

+92
-28
lines changed

crates/lad_backends/mdbook_lad_preprocessor/src/argument_visitor.rs

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,37 @@
11
//! Defines a visitor for function arguments of the `LAD` format.
22
3-
use ladfile::ArgumentVisitor;
3+
use ladfile::{ArgumentVisitor, LadTypeId};
44

55
use crate::markdown::MarkdownBuilder;
66

77
pub(crate) struct MarkdownArgumentVisitor<'a> {
88
ladfile: &'a ladfile::LadFile,
99
buffer: MarkdownBuilder,
10+
linkifier: Box<dyn Fn(LadTypeId, &'a ladfile::LadFile) -> Option<String> + 'static>,
1011
}
1112
impl<'a> MarkdownArgumentVisitor<'a> {
13+
/// Create a new instance of the visitor
1214
pub fn new(ladfile: &'a ladfile::LadFile) -> Self {
1315
let mut builder = MarkdownBuilder::new();
1416
builder.tight_inline().set_escape_mode(false);
1517
Self {
1618
ladfile,
1719
buffer: builder,
20+
linkifier: Box::new(|_, _| None),
1821
}
1922
}
2023

24+
/// Create a new instance of the visitor with a custom linkifier function
25+
pub fn new_with_linkifier<F: Fn(LadTypeId, &'a ladfile::LadFile) -> Option<String> + 'static>(
26+
ladfile: &'a ladfile::LadFile,
27+
linkifier: F,
28+
) -> Self {
29+
let mut without = Self::new(ladfile);
30+
without.linkifier = Box::new(linkifier);
31+
without
32+
}
33+
34+
2135
pub fn build(mut self) -> String {
2236
self.buffer.build()
2337
}
@@ -26,8 +40,11 @@ impl<'a> MarkdownArgumentVisitor<'a> {
2640
impl ArgumentVisitor for MarkdownArgumentVisitor<'_> {
2741
fn visit_lad_type_id(&mut self, type_id: &ladfile::LadTypeId) {
2842
// Write identifier<Generic1TypeIdentifier, Generic2TypeIdentifier>
29-
self.buffer.text(self.ladfile.get_type_identifier(type_id));
30-
if let Some(generics) = self.ladfile.get_type_generics(type_id) {
43+
let generics = self.ladfile.get_type_generics(type_id);
44+
45+
let type_identifier = self.ladfile.get_type_identifier(type_id);
46+
if let Some(generics) = generics {
47+
self.buffer.text(type_identifier);
3148
self.buffer.text('<');
3249
for (i, generic) in generics.iter().enumerate() {
3350
self.visit_lad_type_id(&generic.type_id);
@@ -36,6 +53,15 @@ impl ArgumentVisitor for MarkdownArgumentVisitor<'_> {
3653
}
3754
}
3855
self.buffer.text('>');
56+
} else {
57+
// link the type
58+
let link_value = (self.linkifier)(type_id.clone(), self.ladfile);
59+
let link_display = type_identifier;
60+
if let Some(link_value) = link_value {
61+
self.buffer.link(link_display, link_value);
62+
} else {
63+
self.buffer.text(link_display);
64+
}
3965
}
4066
}
4167

@@ -106,6 +132,23 @@ mod test {
106132
ladfile::parse_lad_file(ladfile).unwrap()
107133
}
108134

135+
136+
#[test]
137+
fn test_linkifier_visitor_creates_links() {
138+
let ladfile = setup_ladfile();
139+
140+
let mut visitor = MarkdownArgumentVisitor::new_with_linkifier(&ladfile, |type_id, ladfile| {
141+
Some
142+
(
143+
format!("root/{}", ladfile.get_type_identifier(&type_id))
144+
)
145+
});
146+
147+
let first_type_id = ladfile.types.first().unwrap().0;
148+
visitor.visit_lad_type_id(first_type_id);
149+
assert_eq!(visitor.buffer.build(), "[EnumType](root/EnumType)");
150+
}
151+
109152
#[test]
110153
fn test_visit_type_id() {
111154
let ladfile = setup_ladfile();

crates/lad_backends/mdbook_lad_preprocessor/src/markdown.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,7 @@ pub enum Markdown {
9494
headers: Vec<String>,
9595
rows: Vec<Vec<String>>,
9696
},
97-
Raw {
98-
text: String,
99-
},
97+
Raw(String),
10098
}
10199

102100
#[allow(dead_code)]
@@ -175,7 +173,7 @@ impl IntoMarkdown for Markdown {
175173

176174
let escaped = if *code {
177175
// this might be a bug in the markdown renderer but we need to escape those for tables
178-
text.clone().replace("|", "\\|")
176+
text.clone()
179177
} else {
180178
escape_markdown(text, builder.escape)
181179
};
@@ -279,7 +277,7 @@ impl IntoMarkdown for Markdown {
279277
header_line, separator_line, rows_lines
280278
));
281279
}
282-
Markdown::Raw { text } => {
280+
Markdown::Raw(text) => {
283281
builder.append(text);
284282
}
285283
}

crates/lad_backends/mdbook_lad_preprocessor/src/sections.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ fn print_type(ladfile: &LadFile, type_: &LadTypeId) -> String {
1616
visitor.build()
1717
}
1818

19+
fn build_escaped_visitor(arg_visitor: MarkdownArgumentVisitor<'_>) -> String {
20+
arg_visitor.build().replace("<", "\\<").replace(">", "\\>").replace("|", "\\|")
21+
}
22+
1923
/// Sections which convert to single markdown files
2024
pub(crate) enum Section<'a> {
2125
Summary {
@@ -205,7 +209,8 @@ impl<'a> Section<'a> {
205209
}
206210
Section::InstancesSummary { ladfile } => {
207211
let instances = ladfile.globals.iter().collect::<Vec<_>>();
208-
vec![SectionItem::InstancesSummary { instances, ladfile}]
212+
let types_directory = linkify_filename(Section::TypeSummary { ladfile }.title());
213+
vec![SectionItem::InstancesSummary { instances, ladfile, types_directory}]
209214
}
210215
Section::TypeSummary { ladfile } => {
211216
let types = ladfile.types.keys().collect::<Vec<_>>();
@@ -299,6 +304,7 @@ pub enum SectionItem<'a> {
299304
InstancesSummary {
300305
ladfile: &'a ladfile::LadFile,
301306
instances: Vec<(&'a Cow<'static, str>, &'a LadInstance)>,
307+
types_directory: String,
302308
},
303309
}
304310

@@ -348,13 +354,13 @@ impl IntoMarkdown for SectionItem<'_> {
348354
SectionItem::Description {
349355
lad_type: description,
350356
} => {
351-
builder.heading(2, "Description").quote(Markdown::Raw {
352-
text: description
357+
builder.heading(2, "Description").quote(Markdown::Raw(
358+
description
353359
.documentation
354360
.as_deref()
355361
.unwrap_or(NO_DOCS_STRING)
356362
.to_owned(),
357-
});
363+
));
358364
}
359365
SectionItem::FunctionsSummary {
360366
functions,
@@ -433,18 +439,22 @@ impl IntoMarkdown for SectionItem<'_> {
433439
}
434440
});
435441
}
436-
SectionItem::InstancesSummary { instances, ladfile } => {
442+
SectionItem::InstancesSummary { instances, ladfile, types_directory } => {
437443
builder.heading(2, "Global Values");
438444
builder.text("Global values that are accessible anywhere inside scripts. You should avoid naming conflicts with these and trying to overwrite or edit them.");
439445
// make a table of instances as a quick reference, make them link to instance details sub-sections
440446

441447
// first build a non-static instance table
442448
let instances = instances.iter().map(|(k,v)| {
443449
let name = k.to_string();
444-
let mut arg_visitor = MarkdownArgumentVisitor::new(ladfile);
450+
let types_directory = types_directory.clone();
451+
let mut arg_visitor = MarkdownArgumentVisitor::new_with_linkifier(ladfile, move |lad_type_id, ladfile| {
452+
let printed_type = linkify_filename(print_type(ladfile, &lad_type_id));
453+
Some(format!("./{types_directory}/{printed_type}.md"))
454+
});
445455
arg_visitor.visit(&v.type_kind);
446-
447-
(v.is_static, name, arg_visitor.build())
456+
let escaped = build_escaped_visitor(arg_visitor);
457+
(v.is_static, name, escaped)
448458
}).collect::<Vec<_>>();
449459

450460
builder.heading(3, "Instances");
@@ -454,7 +464,7 @@ impl IntoMarkdown for SectionItem<'_> {
454464
for (_, name, instance) in instances.iter().filter(|(a,_,_)| !*a) {
455465
builder.row(markdown_vec![
456466
Markdown::new_paragraph(name).code(),
457-
Markdown::new_paragraph(instance).code()
467+
Markdown::Raw(instance.clone())
458468
]);
459469
}
460470
});
@@ -466,20 +476,20 @@ impl IntoMarkdown for SectionItem<'_> {
466476
for (_, name, instance) in instances.iter().filter(|(a,_,_)| *a) {
467477
builder.row(markdown_vec![
468478
Markdown::new_paragraph(name).code(),
469-
Markdown::new_paragraph(instance).code()
479+
Markdown::Raw(instance.clone())
470480
]);
471481
}
472482
});
473483
}
474484
SectionItem::FunctionDetails { function, ladfile } => {
475485
// we don't escape this, this is already markdown
476-
builder.quote(Markdown::Raw {
477-
text: function
486+
builder.quote(Markdown::Raw(
487+
function
478488
.documentation
479489
.as_deref()
480490
.unwrap_or(NO_DOCS_STRING)
481491
.to_owned(),
482-
});
492+
));
483493

484494
builder.heading(4, "Arguments");
485495
builder.list(
@@ -521,12 +531,12 @@ fn lad_argument_to_list_elem(
521531
Markdown::new_paragraph(":"),
522532
Markdown::new_paragraph(markdown).code(),
523533
Markdown::new_paragraph("-"),
524-
Markdown::Raw {
525-
text: arg
534+
Markdown::Raw(
535+
arg
526536
.documentation
527537
.as_deref()
528538
.unwrap_or(NO_DOCS_STRING)
529539
.to_owned()
530-
}
540+
)
531541
]
532542
}
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
# Globals
22

3-
## Globals
3+
## Global Values
4+
5+
Global values that are accessible anywhere inside scripts\. You should avoid naming conflicts with these and trying to overwrite or edit them\.
6+
7+
### Instances
8+
9+
Instances containing actual accessible values\.
10+
11+
| Instance | Type |
12+
| --- | --- |
13+
| `my_non_static_instance` | Vec\<[UnitType](./types/unittype.md)\> |
14+
| `map` | HashMap\<[String](./types/string.md), [String](./types/string.md) \| [String](./types/string.md)\> |
15+
16+
### Static Instances
17+
18+
Static type references, existing for the purpose of typed static function calls\.
419

520
| Instance | Type |
621
| --- | --- |
7-
| `my_static_instance` | `StructType<usize>` |
8-
| `my_non_static_instance` | `Vec<UnitType>` |
9-
| `map` | `HashMap<String, String | String>` |
22+
| `my_static_instance` | StructType\<[usize](./types/usize.md)\> |

0 commit comments

Comments
 (0)