boxwood 2.9.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "boxwood",
3
- "version": "2.9.0",
3
+ "version": "2.10.0",
4
4
  "description": "Compile HTML templates into JS",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -103,61 +103,96 @@ function Markdown(params, children) {
103
103
  const lines = children
104
104
  .trim()
105
105
  .split("\n")
106
- .map((line) => line.trim())
107
- .filter(Boolean)
106
+ .filter((line) => line.trim().length > 0)
107
+ .map((line) => {
108
+ // Preserve leading spaces for indentation tracking
109
+ const trimmed = line.trim()
110
+ const leadingSpaces = line.length - line.trimStart().length
111
+ return { text: trimmed, indent: leadingSpaces }
112
+ })
108
113
 
109
114
  const items = lines
110
- .map((line) => {
111
- if (UNORDERED_MARKERS.some((marker) => line.startsWith(marker))) {
112
- const content = line.substring(2)
115
+ .map(({ text, indent }) => {
116
+ if (UNORDERED_MARKERS.some((marker) => text.startsWith(marker))) {
117
+ const content = text.substring(2)
113
118
  if (!content) return null
114
- return { type: "li", list: "ul", content }
119
+ return { type: "li", list: "ul", content, indent }
115
120
  }
116
121
 
117
- if (ORDERED_LIST_REGEXP.test(line)) {
118
- const content = line.replace(ORDERED_LIST_REGEXP, "")
122
+ if (ORDERED_LIST_REGEXP.test(text)) {
123
+ const content = text.replace(ORDERED_LIST_REGEXP, "")
119
124
  if (!content) return null
120
- return { type: "li", list: "ol", content }
125
+ return { type: "li", list: "ol", content, indent }
121
126
  }
122
127
 
123
128
  for (const { prefix, type } of HEADINGS) {
124
- if (line.startsWith(prefix)) {
125
- return { type, content: line.substring(prefix.length) }
129
+ if (text.startsWith(prefix)) {
130
+ return { type, content: text.substring(prefix.length), indent }
126
131
  }
127
132
  }
128
133
 
129
- if (line.startsWith("> ")) {
130
- return { type: "blockquote", content: line.substring(2) }
134
+ if (text.startsWith("> ")) {
135
+ return { type: "blockquote", content: text.substring(2), indent }
131
136
  }
132
137
 
133
- return { type: "p", content: line }
138
+ return { type: "p", content: text, indent }
134
139
  })
135
140
  .filter(Boolean)
136
141
 
137
142
  const nodes = []
138
143
  let i = 0
139
144
 
140
- while (i < items.length) {
141
- const item = items[i]
145
+ function parseList(startIndex, parentIndent) {
146
+ const list = []
147
+ let currentIndex = startIndex
148
+ const parentListType = items[startIndex].list
142
149
 
143
- if (item.type === "li") {
144
- const list = []
145
- const parent = item.list
146
-
147
- while (
148
- i < items.length &&
149
- items[i].type === "li" &&
150
- items[i].list === parent
151
- ) {
152
- list.push(Li(params, format(items[i].content)))
153
- i++
150
+ while (currentIndex < items.length) {
151
+ const item = items[currentIndex]
152
+
153
+ // Stop if not a list item or indent is less than expected
154
+ if (item.type !== "li" || item.indent < parentIndent) {
155
+ break
154
156
  }
155
157
 
156
- if (parent === "ul") {
157
- nodes.push(Ul(params, list))
158
- } else if (parent === "ol") {
159
- nodes.push(Ol(params, list))
158
+ // Stop if indent matches but list type differs
159
+ if (item.indent === parentIndent && item.list !== parentListType) {
160
+ break
161
+ }
162
+
163
+ // Skip items with greater indent (they belong to nested lists)
164
+ if (item.indent > parentIndent) {
165
+ break
160
166
  }
167
+
168
+ // Process current item at the correct indent level
169
+ const content = [format(item.content)]
170
+ currentIndex++
171
+
172
+ // Check if next item is a nested list
173
+ const nextItem = items[currentIndex]
174
+ if (nextItem?.type === "li" && nextItem.indent > item.indent) {
175
+ const nestedResult = parseList(currentIndex, nextItem.indent)
176
+ content.push(nestedResult.list)
177
+ currentIndex = nestedResult.nextIndex
178
+ }
179
+
180
+ list.push(Li(params, content))
181
+ }
182
+
183
+ const listElement =
184
+ parentListType === "ul" ? Ul(params, list) : Ol(params, list)
185
+
186
+ return { list: listElement, nextIndex: currentIndex }
187
+ }
188
+
189
+ while (i < items.length) {
190
+ const item = items[i]
191
+
192
+ if (item.type === "li") {
193
+ const result = parseList(i, item.indent)
194
+ nodes.push(result.list)
195
+ i = result.nextIndex
161
196
  } else if (item.type === "blockquote") {
162
197
  const lines = []
163
198