v / cmd / tools / vdoc / document / node.v
115 lines · 106 sloc · 2.75 KB · 46447f1262986910fe68dbb4a47b743b3656910f
Raw
1module document
2
3import os
4
5pub const should_sort = os.getenv_opt('VDOC_SORT') or { 'true' }.bool()
6
7pub fn (nodes []DocNode) find(symname string) !DocNode {
8 for node in nodes {
9 if node.name == symname {
10 return node
11 }
12 }
13 return error('symbol not found')
14}
15
16// arrange sorts the DocNodes based on their symbols and names.
17pub fn (mut nodes []DocNode) arrange() {
18 if !should_sort {
19 return
20 }
21 mut kinds := []SymbolKind{}
22 for v in nodes {
23 if v.kind !in kinds {
24 kinds << v.kind
25 }
26 }
27 kinds.sort_with_compare(compare_sym_kinds)
28 mut res := []DocNode{}
29 for k in kinds {
30 mut kind_nodes := nodes.filter(it.kind == k)
31 kind_nodes.sort(a.name < b.name)
32 res << kind_nodes
33 }
34 nodes = res.clone()
35}
36
37fn compare_sym_kinds(a &SymbolKind, b &SymbolKind) int {
38 ak := int(*a)
39 bk := int(*b)
40 return match true {
41 ak < bk { -1 }
42 ak > bk { 1 }
43 else { 0 }
44 }
45}
46
47// arr() converts the map into an array of `DocNode`.
48pub fn (cnts map[string]DocNode) arr() []DocNode {
49 mut contents := cnts.values()
50 contents.arrange()
51 return contents
52}
53
54// merge_comments returns a `string` with the combined contents of `DocNode.comments`.
55pub fn (dc DocNode) merge_comments() string {
56 return merge_doc_comments(dc.comments)
57}
58
59// merge_comments_without_examples returns a `string` with the
60// combined contents of `DocNode.comments` - excluding any examples.
61pub fn (dc DocNode) merge_comments_without_examples() string {
62 mut sans_examples := []DocComment{cap: dc.comments.len}
63 for i := 0; i < dc.comments.len; i++ {
64 if dc.comments[i].is_example() {
65 continue
66 }
67 if dc.comments[i].is_multi_line_example() {
68 i++
69 if i == dc.comments.len || !dc.comments[i].has_triple_backtick() {
70 eprintln('${dc.file_path}:${dc.pos.line_nr}: warning: expected code block after empty example line:')
71 eprintln('// ```')
72 if i < dc.comments.len {
73 eprintln('Found:')
74 eprintln('//' + dc.comments[i].text[1..])
75 }
76 }
77 i++
78 for i < dc.comments.len && !dc.comments[i].has_triple_backtick() {
79 i++
80 }
81 } else {
82 sans_examples << dc.comments[i]
83 }
84 }
85 return merge_doc_comments(sans_examples)
86}
87
88// examples returns a `[]string` containing examples parsed from `DocNode.comments`.
89pub fn (dn DocNode) examples() []string {
90 mut output := []string{}
91 for i := 0; i < dn.comments.len; i++ {
92 comment := dn.comments[i]
93 if comment.is_example() {
94 output << comment.example()
95 } else if comment.is_multi_line_example() {
96 i++
97 if i + 2 < dn.comments.len && dn.comments[i].has_triple_backtick() {
98 i++
99 mut ml_ex := ''
100 for i < dn.comments.len && !dn.comments[i].has_triple_backtick() {
101 if ml_ex.len > 0 {
102 ml_ex += '\n'
103 }
104 s := dn.comments[i].text
105 if s.len > 2 {
106 ml_ex += s[2..]
107 }
108 i++
109 }
110 output << ml_ex
111 }
112 }
113 }
114 return output
115}
116