Skip to content

Commit 4f30d5f

Browse files
authored
refactor: streamline anchorization (#766)
1 parent bc06a00 commit 4f30d5f

File tree

72 files changed

+381
-576
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+381
-576
lines changed

js/html_types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export interface AllSymbolsCtx {
6161
export interface AllSymbolsItemCtx {
6262
name: string;
6363
href: string;
64+
anchor: AnchorCtx;
6465
module_doc: ModuleDocCtx;
6566
}
6667

src/html/jsdoc.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub struct MarkdownToHTMLOptions {
149149
pub no_toc: bool,
150150
}
151151

152-
pub type MarkdownStripper = std::rc::Rc<dyn Fn(&str) -> String>;
152+
pub type MarkdownStripper = Rc<dyn Fn(&str) -> String>;
153153

154154
pub fn strip(render_ctx: &RenderContext, md: &str) -> String {
155155
let md = parse_links(md, render_ctx, true);
@@ -284,7 +284,6 @@ pub(crate) fn jsdoc_examples(
284284
#[derive(Debug, Serialize, Deserialize, Clone)]
285285
pub struct ExampleCtx {
286286
pub anchor: AnchorCtx,
287-
pub id: Id,
288287
pub title: String,
289288
pub markdown_title: String,
290289
markdown_body: String,
@@ -294,7 +293,7 @@ impl ExampleCtx {
294293
pub const TEMPLATE: &'static str = "example";
295294

296295
pub fn new(render_ctx: &RenderContext, example: &str, i: usize) -> Self {
297-
let id = IdBuilder::new(render_ctx.ctx)
296+
let id = IdBuilder::new(render_ctx)
298297
.kind(IdKind::Example)
299298
.index(i)
300299
.build();
@@ -311,8 +310,7 @@ impl ExampleCtx {
311310
render_markdown(render_ctx, body.unwrap_or_default(), true);
312311

313312
ExampleCtx {
314-
anchor: AnchorCtx { id: id.clone() },
315-
id,
313+
anchor: AnchorCtx::new(id),
316314
title,
317315
markdown_title,
318316
markdown_body,
@@ -375,13 +373,18 @@ impl ModuleDocCtx {
375373

376374
sections.extend(super::namespace::render_namespace(
377375
partitions_by_kind.into_iter().map(|(title, nodes)| {
376+
let id = IdBuilder::new(render_ctx)
377+
.name(short_path.display_name())
378+
.name(&title)
379+
.build();
380+
381+
render_ctx.toc.add_entry(1, &title, &id);
382+
378383
(
379384
render_ctx.clone(),
380385
Some(SectionHeaderCtx {
381386
title: title.clone(),
382-
anchor: AnchorCtx {
383-
id: super::util::Id::new(title),
384-
},
387+
anchor: AnchorCtx::new(id),
385388
href: None,
386389
doc: None,
387390
}),
@@ -394,7 +397,7 @@ impl ModuleDocCtx {
394397
Self {
395398
deprecated,
396399
sections: super::SymbolContentCtx {
397-
id: Id::new("module_doc"),
400+
id: render_ctx.toc.anchorize("module_doc"),
398401
docs: html,
399402
sections,
400403
},

src/html/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub use pages::generate_symbol_pages_for_module;
3434
pub use render_context::RenderContext;
3535
pub use search::generate_search_index;
3636
pub use symbols::AllSymbolsCtx;
37-
pub use symbols::AllSymbolsItemCtx;
37+
pub use symbols::AllSymbolsEntrypointCtx;
3838
pub use symbols::SymbolContentCtx;
3939
pub use symbols::SymbolGroupCtx;
4040
pub use symbols::namespace;

src/html/pages.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,8 @@ impl IndexCtx {
277277

278278
let title = short_path.display_name();
279279

280-
let anchor = render_ctx.toc.anchorize(title);
281-
render_ctx.toc.add_entry(1, title, &anchor);
280+
let id = render_ctx.toc.anchorize(title);
281+
render_ctx.toc.add_entry(1, title, &id);
282282

283283
util::SectionCtx {
284284
header: Some(SectionHeaderCtx {
@@ -287,9 +287,7 @@ impl IndexCtx {
287287
short_path.as_resolve_kind(),
288288
)),
289289
title: title.to_string(),
290-
anchor: AnchorCtx {
291-
id: util::Id::new(anchor),
292-
},
290+
anchor: AnchorCtx::new(id),
293291
doc,
294292
}),
295293
content: util::SectionContentCtx::Empty,
@@ -307,8 +305,8 @@ impl IndexCtx {
307305
let sections = partitions
308306
.into_keys()
309307
.map(|title| {
310-
let anchor = render_ctx.toc.anchorize(&title);
311-
render_ctx.toc.add_entry(1, &title, &anchor);
308+
let id = render_ctx.toc.anchorize(&title);
309+
render_ctx.toc.add_entry(1, &title, &id);
312310

313311
let doc = ctx
314312
.category_docs
@@ -334,9 +332,7 @@ impl IndexCtx {
334332
UrlResolveKind::Category { category: &title },
335333
)),
336334
title,
337-
anchor: AnchorCtx {
338-
id: util::Id::new(anchor),
339-
},
335+
anchor: AnchorCtx::new(id),
340336
doc,
341337
}),
342338
content: util::SectionContentCtx::Empty,
@@ -401,12 +397,12 @@ impl IndexCtx {
401397
category_docs.get(&title).cloned().flatten()
402398
});
403399

400+
let id = render_ctx.toc.anchorize(&title);
401+
404402
(
405403
render_ctx.clone(),
406404
Some(SectionHeaderCtx {
407-
anchor: AnchorCtx {
408-
id: util::Id::new(title.clone()),
409-
},
405+
anchor: AnchorCtx::new(id),
410406
title,
411407
href: None,
412408
doc,

src/html/render_context.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,12 +351,21 @@ lazy_static! {
351351
}
352352

353353
impl HeadingToCAdapter {
354-
pub fn anchorize(&self, content: &str) -> String {
354+
pub fn anchorize(&self, content: &str) -> super::util::Id {
355355
let mut anchorizer = self.anchorizer.lock().unwrap();
356-
anchorizer.anchorize(content)
356+
super::util::Id::from_raw(anchorizer.anchorize(content))
357357
}
358358

359-
pub fn add_entry(&self, level: u8, content: &str, anchor: &str) {
359+
/// Apply the same GFM sanitization as anchorize but without registering
360+
/// in the deduplication map. Use for IDs referencing anchors on other pages.
361+
pub fn sanitize(&self, content: &str) -> super::util::Id {
362+
let s = REJECTED_CHARS
363+
.replace_all(&content.to_lowercase(), "")
364+
.replace(' ', "-");
365+
super::util::Id::from_raw(s)
366+
}
367+
368+
pub fn add_entry(&self, level: u8, content: &str, anchor: &super::util::Id) {
360369
let mut toc = self.toc.lock().unwrap();
361370
let mut offset = self.offset.lock().unwrap();
362371

@@ -366,7 +375,7 @@ impl HeadingToCAdapter {
366375
toc.push(ToCEntry {
367376
level,
368377
content: content.to_owned(),
369-
anchor: anchor.to_owned(),
378+
anchor: anchor.as_str().to_owned(),
370379
});
371380
}
372381
}

src/html/search.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ pub fn doc_nodes_into_search_index_node(
8686
.unwrap_or_default();
8787

8888
let id = parent_id.unwrap_or_else(|| {
89-
IdBuilder::new(ctx.ctx)
89+
IdBuilder::new(ctx)
9090
.kind(IdKind::Namespace)
9191
.name(&name)
92-
.build()
92+
.build_unregistered()
9393
});
9494

9595
let mut out = vec![SearchIndexNode {

src/html/symbols/class.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ fn render_constructors(
125125
})
126126
.enumerate()
127127
.map(|(i, constructor)| {
128-
let id = IdBuilder::new(ctx.ctx)
128+
let id = IdBuilder::new(ctx)
129129
.kind(IdKind::Constructor)
130130
.index(i)
131131
.build();
@@ -160,7 +160,6 @@ fn render_constructors(
160160

161161
#[derive(Debug, Serialize, Deserialize, Clone)]
162162
pub struct IndexSignatureCtx {
163-
pub id: Id,
164163
pub anchor: AnchorCtx,
165164
pub readonly: bool,
166165
pub params: String,
@@ -307,7 +306,7 @@ fn render_class_accessor(
307306
let getter_or_setter = getter.or(setter).unwrap();
308307

309308
let name = &getter_or_setter.name;
310-
let id = IdBuilder::new(ctx.ctx)
309+
let id = IdBuilder::new(ctx)
311310
.kind(IdKind::Accessor)
312311
.name(name)
313312
.build();
@@ -364,7 +363,7 @@ fn render_class_method(
364363
return None;
365364
}
366365

367-
let id = IdBuilder::new(ctx.ctx)
366+
let id = IdBuilder::new(ctx)
368367
.kind(IdKind::Method)
369368
.name(&method.name)
370369
.index(i)
@@ -402,7 +401,7 @@ fn render_class_property(
402401
class_name: &str,
403402
property: &ClassPropertyDef,
404403
) -> DocEntryCtx {
405-
let id = IdBuilder::new(ctx.ctx)
404+
let id = IdBuilder::new(ctx)
406405
.kind(IdKind::Property)
407406
.name(&property.name)
408407
.build();

src/html/symbols/enum.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ pub(crate) fn render_enum(
2727
let items = members
2828
.into_iter()
2929
.map(|member| {
30-
let id = IdBuilder::new(render_ctx.ctx)
30+
let id = IdBuilder::new(render_ctx)
3131
.kind(IdKind::Enum)
3232
.name(doc_node.get_name())
33-
.component(&member.name)
33+
.name(&member.name)
3434
.build();
3535

3636
let tags = Tag::from_js_doc(&member.js_doc);

src/html/symbols/function.rs

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use std::ops::Deref;
1717

1818
#[derive(Debug, Serialize, Deserialize, Clone)]
1919
struct OverloadRenderCtx {
20-
id: Id,
2120
anchor: AnchorCtx,
2221
name: String,
2322
summary: String,
@@ -69,29 +68,24 @@ impl FunctionCtx {
6968
}
7069
});
7170

72-
let overload_id = IdBuilder::new(ctx.ctx)
71+
let overload_id = IdBuilder::new(ctx)
7372
.kind(IdKind::Function)
7473
.name(doc_node.get_name())
7574
.index(i)
7675
.build();
7776

7877
if overloads_count > 1 {
79-
ctx.toc.add_entry(
80-
0,
81-
&format!("Overload {}", i + 1),
82-
overload_id.as_str(),
83-
);
78+
ctx
79+
.toc
80+
.add_entry(0, &format!("Overload {}", i + 1), &overload_id);
8481
}
8582

8683
functions_content.push(OverloadRenderCtx {
87-
id: overload_id.clone(),
88-
anchor: AnchorCtx {
89-
id: overload_id.clone(),
90-
},
84+
anchor: AnchorCtx::new(overload_id.clone()),
9185
name: doc_node.get_name().to_string(),
9286
summary: render_function_summary(function_def, ctx),
9387
deprecated,
94-
content: render_single_function(ctx, doc_node, overload_id.clone()),
88+
content: render_single_function(ctx, doc_node, overload_id),
9589
});
9690
}
9791

@@ -161,8 +155,7 @@ fn render_single_function(
161155
.enumerate()
162156
.map(|(i, param)| {
163157
let (name, str_name) = crate::html::parameters::param_name(param, i);
164-
let id = IdBuilder::new(ctx.ctx)
165-
.component(&overload_id)
158+
let id = IdBuilder::new_with_parent(ctx, &overload_id)
166159
.kind(IdKind::Parameter)
167160
.name(&str_name)
168161
.build();
@@ -334,8 +327,7 @@ fn render_function_return_type(
334327
) -> Option<DocEntryCtx> {
335328
let return_type = def.return_type.as_ref()?;
336329

337-
let id = IdBuilder::new(render_ctx.ctx)
338-
.component(overload_id.as_str())
330+
let id = IdBuilder::new_with_parent(render_ctx, &overload_id)
339331
.kind(IdKind::Return)
340332
.build();
341333

@@ -367,8 +359,7 @@ fn render_function_throws(
367359
overload_id: Id,
368360
throws_id: usize,
369361
) -> DocEntryCtx {
370-
let id = IdBuilder::new(render_ctx.ctx)
371-
.component(overload_id.as_str())
362+
let id = IdBuilder::new_with_parent(render_ctx, &overload_id)
372363
.kind(IdKind::Throws)
373364
.index(throws_id)
374365
.build();

src/html/symbols/interface.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ pub(crate) fn render_index_signatures(
6767
let mut items = Vec::with_capacity(index_signatures.len());
6868

6969
for (i, index_signature) in index_signatures.iter().enumerate() {
70-
let id = IdBuilder::new(ctx.ctx)
70+
let id = IdBuilder::new(ctx)
7171
.kind(IdKind::IndexSignature)
7272
.index(i)
7373
.build();
@@ -79,8 +79,7 @@ pub(crate) fn render_index_signatures(
7979
.unwrap_or_default();
8080

8181
items.push(IndexSignatureCtx {
82-
id: id.clone(),
83-
anchor: AnchorCtx { id },
82+
anchor: AnchorCtx::new(id),
8483
readonly: index_signature.readonly,
8584
params: render_params(ctx, &index_signature.params),
8685
ts_type,
@@ -110,7 +109,7 @@ pub(crate) fn render_call_signatures(
110109
.iter()
111110
.enumerate()
112111
.map(|(i, call_signature)| {
113-
let id = IdBuilder::new(ctx.ctx)
112+
let id = IdBuilder::new(ctx)
114113
.kind(IdKind::CallSignature)
115114
.index(i)
116115
.build();
@@ -159,7 +158,7 @@ pub(crate) fn render_properties(
159158
let items = properties
160159
.iter()
161160
.map(|property| {
162-
let id = IdBuilder::new(ctx.ctx)
161+
let id = IdBuilder::new(ctx)
163162
.kind(IdKind::Property)
164163
.name(&property.name)
165164
.build();
@@ -234,7 +233,7 @@ pub(crate) fn render_methods(
234233
.iter()
235234
.enumerate()
236235
.map(|(i, method)| {
237-
let id = IdBuilder::new(ctx.ctx)
236+
let id = IdBuilder::new(ctx)
238237
.kind(IdKind::Method)
239238
.name(&method.name)
240239
.index(i)

0 commit comments

Comments
 (0)