|
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | 6 | "log/slog" |
| 7 | + "strings" |
7 | 8 |
|
8 | 9 | "github.com/project-chip/alchemy/asciidoc" |
9 | 10 | "github.com/project-chip/alchemy/asciidoc/parse" |
@@ -133,30 +134,63 @@ func (b *Baller) disco(cxt context.Context, doc *asciidoc.Document) error { |
133 | 134 | } |
134 | 135 |
|
135 | 136 | func (b *Baller) discoBallTopLevelSection(dc *discoContext, top *asciidoc.Section, docType matter.DocType) error { |
136 | | - if b.options.AddXrefstyle && dc.doc == dc.library.Root { |
137 | | - var xrefstyleEntry *asciidoc.AttributeEntry |
138 | | - var topIndex int = -1 |
139 | | - |
140 | | - for i, el := range dc.doc.Elements { |
141 | | - if el == top { |
142 | | - topIndex = i |
143 | | - break |
144 | | - } |
145 | | - if ae, ok := el.(*asciidoc.AttributeEntry); ok && ae.Name == "xrefstyle" { |
146 | | - xrefstyleEntry = ae |
| 137 | + if b.options.XrefStyleOnlyInRoot { |
| 138 | + // Logic: |
| 139 | + // 1. For non-root, no xrefstyle at all anywhere in doc. |
| 140 | + // 2. For root, if it is present somewhere in file, it's ok. If not present, add it after Copyright Notice or before first section. |
| 141 | + |
| 142 | + if dc.doc == dc.library.Root { |
| 143 | + found := false |
| 144 | + for _, el := range dc.doc.Elements { |
| 145 | + if ae, ok := el.(*asciidoc.AttributeEntry); ok && ae.Name == "xrefstyle" { |
| 146 | + found = true |
| 147 | + break |
| 148 | + } |
147 | 149 | } |
148 | | - } |
| 150 | + if !found { |
| 151 | + ae := asciidoc.NewAttributeEntry("xrefstyle") |
| 152 | + ae.Elements = asciidoc.Elements{asciidoc.NewString("basic")} |
| 153 | + |
| 154 | + copyrightIndex := -1 |
| 155 | + topIndex := -1 |
| 156 | + for i, el := range dc.doc.Elements { |
| 157 | + if s, ok := el.(*asciidoc.Section); ok { |
| 158 | + if topIndex == -1 { |
| 159 | + topIndex = i |
| 160 | + } |
| 161 | + name := "" |
| 162 | + if len(s.Title) > 0 { |
| 163 | + if str, ok := s.Title[0].(*asciidoc.String); ok { |
| 164 | + name = str.Value |
| 165 | + } |
| 166 | + } |
| 167 | + if strings.Contains(strings.ToLower(name), "copyright notice") { |
| 168 | + copyrightIndex = i |
| 169 | + break |
| 170 | + } |
| 171 | + } |
| 172 | + } |
149 | 173 |
|
150 | | - if xrefstyleEntry == nil { |
151 | | - ae := asciidoc.NewAttributeEntry("xrefstyle") |
152 | | - ae.Elements = asciidoc.Elements{asciidoc.NewString("basic")} |
153 | | - if topIndex != -1 { |
154 | | - dc.doc.Elements = append(dc.doc.Elements, nil, nil) |
155 | | - copy(dc.doc.Elements[topIndex+2:], dc.doc.Elements[topIndex:]) |
156 | | - dc.doc.Elements[topIndex] = ae |
157 | | - dc.doc.Elements[topIndex+1] = &asciidoc.NewLine{} |
158 | | - } else { |
159 | | - dc.doc.Elements = append(asciidoc.Elements{ae, &asciidoc.NewLine{}}, dc.doc.Elements...) |
| 174 | + if copyrightIndex != -1 { |
| 175 | + dc.doc.Elements = append(dc.doc.Elements[:copyrightIndex+1], append([]asciidoc.Element{&asciidoc.NewLine{}, ae}, dc.doc.Elements[copyrightIndex+1:]...)...) |
| 176 | + } else if topIndex != -1 { |
| 177 | + dc.doc.Elements = append(dc.doc.Elements[:topIndex], append([]asciidoc.Element{ae, &asciidoc.NewLine{}}, dc.doc.Elements[topIndex:]...)...) |
| 178 | + } else { |
| 179 | + dc.doc.Elements = append(asciidoc.Elements{ae, &asciidoc.NewLine{}}, dc.doc.Elements...) |
| 180 | + } |
| 181 | + } |
| 182 | + } else { |
| 183 | + for i := 0; i < len(dc.doc.Elements); i++ { |
| 184 | + el := dc.doc.Elements[i] |
| 185 | + if ae, ok := el.(*asciidoc.AttributeEntry); ok && ae.Name == "xrefstyle" { |
| 186 | + dc.doc.Elements = append(dc.doc.Elements[:i], dc.doc.Elements[i+1:]...) |
| 187 | + i-- |
| 188 | + if i+1 < len(dc.doc.Elements) { |
| 189 | + if _, ok := dc.doc.Elements[i+1].(*asciidoc.NewLine); ok { |
| 190 | + dc.doc.Elements = append(dc.doc.Elements[:i+1], dc.doc.Elements[i+2:]...) |
| 191 | + } |
| 192 | + } |
| 193 | + } |
160 | 194 | } |
161 | 195 | } |
162 | 196 | } |
@@ -191,3 +225,19 @@ func (b *Baller) discoBallTopLevelSection(dc *discoContext, top *asciidoc.Sectio |
191 | 225 | b.postCleanUpStrings(dc.doc, top) |
192 | 226 | return nil |
193 | 227 | } |
| 228 | + |
| 229 | +func (b *Baller) TestHelperDiscoBall(doc *asciidoc.Document, isRoot bool) error { |
| 230 | + lib := &spec.Library{} |
| 231 | + if isRoot { |
| 232 | + lib.Root = doc |
| 233 | + } |
| 234 | + dc := &discoContext{ |
| 235 | + Context: context.Background(), |
| 236 | + doc: doc, |
| 237 | + library: lib, |
| 238 | + potentialDataTypes: make(map[string][]*DataTypeEntry), |
| 239 | + } |
| 240 | + docType := matter.DocTypeCluster |
| 241 | + top := parse.FindFirst[*asciidoc.Section](doc, asciidoc.RawReader, doc) |
| 242 | + return b.discoBallTopLevelSection(dc, top, docType) |
| 243 | +} |
0 commit comments