Skip to content

Commit ca9df16

Browse files
committed
markdown: beef up XetodocChapter and annotate as @js
1 parent d814f81 commit ca9df16

2 files changed

Lines changed: 140 additions & 128 deletions

File tree

src/markdown/fan/ext/xetodoc/Xetodoc.fan

Lines changed: 0 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -122,134 +122,6 @@ class Xetodoc
122122
// }
123123
}
124124

125-
**************************************************************************
126-
** XetodocChapter
127-
**************************************************************************
128-
129-
**
130-
** XetodocChapter is a simple DOM for the chapter meta and headings tree
131-
** that can be used b/w compilerDoc and xetodoc
132-
**
133-
@NoDoc
134-
class XetodocChapter
135-
{
136-
** Parse a markdown file as a chapter into its meta and headings
137-
static XetodocChapter parse(Str file)
138-
{
139-
meta := Str:Str[:] { ordered = true }
140-
list := XetodocHeading[,]
141-
map := Str:XetodocHeading[:]
142-
143-
// read lines
144-
lines := file.splitLines
145-
146-
// check leading comment for title: xxxx
147-
if (lines.first.trim == "<!--")
148-
{
149-
lines.eachWhile |line|
150-
{
151-
line = line.trim
152-
if (line == "-->") return "break"
153-
colon := line.index(":")
154-
if (colon == null) return null
155-
n := line[0..<colon].trim
156-
v := line[colon+1..-1].trim
157-
meta[n] = v
158-
return null
159-
}
160-
}
161-
162-
// lazily parse just heading lines
163-
proc := HeadingProcessor()
164-
l := XetodocHeading[,]
165-
lines.each |line|
166-
{
167-
if (!line.startsWith("#")) return
168-
169-
// compute level
170-
level := 0
171-
while (level+1 < line.size && line[level] == '#') level++
172-
173-
// create heading instance
174-
text := line[level..-1].trim
175-
anchor := proc.toAnchor(text)
176-
h := XetodocHeading(level, text, anchor)
177-
178-
// add to accumulator collections
179-
list.add(h)
180-
map[h.anchor] = h
181-
}
182-
183-
// now organize into a tree
184-
top := XetodocHeading[,]
185-
list.each |h, i|
186-
{
187-
if (i == 1) { top.add(h); return }
188-
for (j := i-1; j >= 0; --j)
189-
{
190-
if (list[j].level < h.level)
191-
{
192-
parent := list[j]
193-
parent.children.add(h)
194-
return
195-
}
196-
}
197-
top.add(h)
198-
}
199-
200-
return make {
201-
it.meta = meta
202-
it.top = top
203-
it.byId = map
204-
}
205-
}
206-
207-
private new make(|This| f) { f(this) }
208-
209-
Str:Str meta
210-
211-
XetodocHeading[] top
212-
213-
Str:XetodocHeading byId
214-
215-
Void dump()
216-
{
217-
echo("#####")
218-
echo(meta.join("\n"))
219-
echo("---")
220-
top.each |x| { x.dump(0) }
221-
}
222-
223-
static Void main(Str[] args)
224-
{
225-
parse(args[0].toUri.toFile.readAllStr).dump
226-
}
227-
}
228-
229-
@NoDoc
230-
class XetodocHeading
231-
{
232-
new make(Int level, Str text, Str anchor)
233-
{
234-
this.level = level
235-
this.text = text
236-
this.anchor = anchor
237-
}
238-
239-
const Int level
240-
const Str text
241-
const Str anchor
242-
XetodocHeading[] children := [,]
243-
244-
override Str toStr() { "$level | $text.toCode [#$anchor]" }
245-
246-
Void dump(Int indent)
247-
{
248-
echo(Str.spaces(indent) + this)
249-
children.each |kid| { kid.dump(indent+2) }
250-
}
251-
}
252-
253125
**************************************************************************
254126
** WarnProcessor
255127
**************************************************************************
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
//
2+
// Copyright (c) 2026, Brian Frank and Andy Frank
3+
// Licensed under the Academic Free License version 3.0
4+
//
5+
// History:
6+
// 5 Mar 2026 Brian Frank Creation
7+
//
8+
9+
**
10+
** XetodocChapter is a simple DOM for the chapter meta and headings tree
11+
** that can be used b/w compilerDoc and xetodoc
12+
**
13+
@Js @NoDoc
14+
class XetodocChapter
15+
{
16+
** Parse a markdown file as a chapter into its meta and headings
17+
static XetodocChapter parse(Str file)
18+
{
19+
meta := Str:Str[:] { ordered = true }
20+
list := XetodocHeading[,]
21+
map := Str:XetodocHeading[:]
22+
23+
// read lines
24+
lines := file.splitLines
25+
26+
// check leading comment for title: xxxx
27+
if (lines.first.trim == "<!--")
28+
{
29+
lines.eachWhile |line|
30+
{
31+
line = line.trim
32+
if (line == "-->") return "break"
33+
colon := line.index(":")
34+
if (colon == null) return null
35+
n := line[0..<colon].trim
36+
v := line[colon+1..-1].trim
37+
meta[n] = v
38+
return null
39+
}
40+
}
41+
42+
// lazily parse just heading lines
43+
proc := HeadingProcessor()
44+
l := XetodocHeading[,]
45+
lines.each |line|
46+
{
47+
if (!line.startsWith("#")) return
48+
49+
// compute level
50+
level := 0
51+
while (level+1 < line.size && line[level] == '#') level++
52+
53+
// create heading instance
54+
text := line[level..-1].trim
55+
anchor := proc.toAnchor(text)
56+
h := XetodocHeading(level, text, anchor)
57+
58+
// add to accumulator collections
59+
list.add(h)
60+
map[h.anchor] = h
61+
}
62+
63+
// now organize into a tree
64+
top := XetodocHeading[,]
65+
list.each |h, i|
66+
{
67+
if (i == 1) { top.add(h); return }
68+
for (j := i-1; j >= 0; --j)
69+
{
70+
if (list[j].level < h.level)
71+
{
72+
parent := list[j]
73+
parent.children.add(h)
74+
return
75+
}
76+
}
77+
top.add(h)
78+
}
79+
80+
return make {
81+
it.meta = meta
82+
it.top = top
83+
it.byId = map
84+
}
85+
}
86+
87+
private new make(|This| f) { f(this) }
88+
89+
Str:Str meta
90+
91+
Str? title() { meta["title"] }
92+
93+
Str:Str anchorToTextMap() { byId.map |h->Str| { h.text } }
94+
95+
XetodocHeading[] top
96+
97+
Str:XetodocHeading byId
98+
99+
Void dump()
100+
{
101+
echo("#####")
102+
echo(meta.join("\n"))
103+
echo("---")
104+
top.each |x| { x.dump(0) }
105+
}
106+
107+
static Void main(Str[] args)
108+
{
109+
parse(args[0].toUri.toFile.readAllStr).dump
110+
}
111+
}
112+
113+
**************************************************************************
114+
** XetodocHeading
115+
**************************************************************************
116+
117+
@Js @NoDoc
118+
class XetodocHeading
119+
{
120+
new make(Int level, Str text, Str anchor)
121+
{
122+
this.level = level
123+
this.text = text
124+
this.anchor = anchor
125+
}
126+
127+
const Int level
128+
const Str text
129+
const Str anchor
130+
XetodocHeading[] children := [,]
131+
132+
override Str toStr() { "$level | $text.toCode [#$anchor]" }
133+
134+
Void dump(Int indent)
135+
{
136+
echo(Str.spaces(indent) + this)
137+
children.each |kid| { kid.dump(indent+2) }
138+
}
139+
}
140+

0 commit comments

Comments
 (0)