@tonguetoquill/collection 0.1.11 → 0.1.13
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": "@tonguetoquill/collection",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/nibsbin/tonguetoquill-collection.git"
|
|
@@ -33,10 +33,9 @@
|
|
|
33
33
|
"publishConfig": {
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"@quillmark/registry": "^0.5.3"
|
|
38
|
-
},
|
|
36
|
+
"dependencies": {},
|
|
39
37
|
"devDependencies": {
|
|
38
|
+
"@quillmark/registry": "^0.5.3",
|
|
40
39
|
"@quillmark/wasm": "^0.39.0"
|
|
41
40
|
}
|
|
42
41
|
}
|
|
@@ -131,8 +131,11 @@
|
|
|
131
131
|
let is_continuation = nest_level > 0 and not is_first_par
|
|
132
132
|
|
|
133
133
|
PAR_BUFFER.update(pars => {
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
pars.push((
|
|
135
|
+
content: text([#p.body]),
|
|
136
|
+
nest_level: nest_level,
|
|
137
|
+
kind: if is_heading { "heading" } else if is_continuation { "continuation" } else { "par" },
|
|
138
|
+
))
|
|
136
139
|
pars
|
|
137
140
|
})
|
|
138
141
|
|
|
@@ -146,7 +149,11 @@
|
|
|
146
149
|
// Collect tables — captured as-is without paragraph numbering
|
|
147
150
|
show table: t => context {
|
|
148
151
|
PAR_BUFFER.update(pars => {
|
|
149
|
-
pars.push((
|
|
152
|
+
pars.push((
|
|
153
|
+
content: t,
|
|
154
|
+
nest_level: -1,
|
|
155
|
+
kind: "table",
|
|
156
|
+
))
|
|
150
157
|
pars
|
|
151
158
|
})
|
|
152
159
|
t
|
|
@@ -197,25 +204,16 @@
|
|
|
197
204
|
// Use place() to prevent hidden content from affecting layout flow
|
|
198
205
|
place(hide(first_pass))
|
|
199
206
|
|
|
200
|
-
//Second pass: consume par buffer
|
|
207
|
+
// Second pass: consume par buffer
|
|
201
208
|
//
|
|
202
|
-
// PAR_BUFFER item
|
|
203
|
-
// item.
|
|
204
|
-
// item.
|
|
205
|
-
// item.
|
|
206
|
-
// item.at(3) — is_table : bool, true if item is a table element
|
|
207
|
-
// item.at(4) — is_continuation : bool, true if this is a continuation block
|
|
208
|
-
// within a multi-block list item
|
|
209
|
-
let ITEM_IS_TABLE = 3
|
|
210
|
-
let ITEM_IS_CONTINUATION = 4
|
|
209
|
+
// PAR_BUFFER item dictionary layout:
|
|
210
|
+
// item.content — the paragraph body or table element
|
|
211
|
+
// item.nest_level — nesting depth (−1 for tables)
|
|
212
|
+
// item.kind — "par", "heading", "table", or "continuation"
|
|
211
213
|
context {
|
|
212
214
|
let heading_buffer = none
|
|
213
|
-
//
|
|
214
|
-
|
|
215
|
-
let par_count = PAR_BUFFER.get().filter(item =>
|
|
216
|
-
not item.at(ITEM_IS_TABLE, default: false)
|
|
217
|
-
and not item.at(ITEM_IS_CONTINUATION, default: false)
|
|
218
|
-
).len()
|
|
215
|
+
// Only top-level paragraphs count for AFH 33-337 §2 numbering purposes
|
|
216
|
+
let par_count = PAR_BUFFER.get().filter(item => item.kind == "par").len()
|
|
219
217
|
let items = PAR_BUFFER.get()
|
|
220
218
|
let total_count = items.len()
|
|
221
219
|
|
|
@@ -231,45 +229,49 @@
|
|
|
231
229
|
let i = 0
|
|
232
230
|
for item in items {
|
|
233
231
|
i += 1
|
|
234
|
-
let
|
|
232
|
+
let kind = item.kind
|
|
233
|
+
let item_content = item.content
|
|
235
234
|
|
|
236
|
-
//
|
|
237
|
-
if
|
|
238
|
-
|
|
239
|
-
render-memo-table(item.at(0))
|
|
235
|
+
// Buffer headings for prepend to the next rendered element
|
|
236
|
+
if kind == "heading" {
|
|
237
|
+
heading_buffer = item_content
|
|
240
238
|
continue
|
|
241
239
|
}
|
|
242
240
|
|
|
243
|
-
|
|
244
|
-
let nest_level = item.at(1)
|
|
245
|
-
let is_heading = item.at(2)
|
|
246
|
-
let is_continuation = item.at(ITEM_IS_CONTINUATION, default: false)
|
|
247
|
-
|
|
248
|
-
// Prepend heading as bolded sentence
|
|
241
|
+
// Prepend buffered heading to the next non-heading element
|
|
249
242
|
if heading_buffer != none {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
243
|
+
if kind == "table" {
|
|
244
|
+
// Tables cannot have inline text prepended; emit heading as
|
|
245
|
+
// a standalone bold line above the table
|
|
246
|
+
blank-line()
|
|
247
|
+
strong[#heading_buffer.]
|
|
248
|
+
heading_buffer = none
|
|
249
|
+
} else {
|
|
250
|
+
item_content = [#strong[#heading_buffer.] #item_content]
|
|
251
|
+
heading_buffer = none
|
|
252
|
+
}
|
|
255
253
|
}
|
|
256
254
|
|
|
255
|
+
// Format based on element kind
|
|
256
|
+
let nest_level = item.nest_level
|
|
257
257
|
let final_par = {
|
|
258
|
-
if
|
|
258
|
+
if kind == "table" {
|
|
259
|
+
render-memo-table(item_content)
|
|
260
|
+
} else if kind == "continuation" {
|
|
259
261
|
// Continuation block within a multi-block list item:
|
|
260
262
|
// indent to align with preceding numbered paragraph's text, no new number.
|
|
261
263
|
// level-counts still holds the value of the preceding numbered paragraph.
|
|
262
264
|
if auto-numbering {
|
|
263
|
-
format-continuation-par(
|
|
265
|
+
format-continuation-par(item_content, nest_level, level-counts)
|
|
264
266
|
} else if nest_level > 0 {
|
|
265
|
-
format-continuation-par(
|
|
267
|
+
format-continuation-par(item_content, nest_level - 1, level-counts)
|
|
266
268
|
} else {
|
|
267
|
-
|
|
269
|
+
item_content
|
|
268
270
|
}
|
|
269
271
|
} else if auto-numbering {
|
|
270
272
|
if par_count > 1 {
|
|
271
273
|
// Apply paragraph numbering per AFH 33-337 §2
|
|
272
|
-
let par = format-numbered-par(
|
|
274
|
+
let par = format-numbered-par(item_content, nest_level, level-counts)
|
|
273
275
|
// Advance counter for this level and reset child levels
|
|
274
276
|
level-counts.insert(str(nest_level), level-counts.at(str(nest_level)) + 1)
|
|
275
277
|
for child in range(nest_level + 1, max-levels) {
|
|
@@ -278,13 +280,13 @@
|
|
|
278
280
|
par
|
|
279
281
|
} else {
|
|
280
282
|
// AFH 33-337 §2: "A single paragraph is not numbered"
|
|
281
|
-
|
|
283
|
+
item_content
|
|
282
284
|
}
|
|
283
285
|
} else {
|
|
284
286
|
// Unnumbered mode: only explicitly nested items (enum/list) get numbered
|
|
285
287
|
if nest_level > 0 {
|
|
286
288
|
let effective_level = nest_level - 1
|
|
287
|
-
let par = format-numbered-par(
|
|
289
|
+
let par = format-numbered-par(item_content, effective_level, level-counts)
|
|
288
290
|
level-counts.insert(str(effective_level), level-counts.at(str(effective_level)) + 1)
|
|
289
291
|
for child in range(effective_level + 1, max-levels) {
|
|
290
292
|
level-counts.insert(str(child), 1)
|
|
@@ -296,12 +298,12 @@
|
|
|
296
298
|
for child in range(max-levels) {
|
|
297
299
|
level-counts.insert(str(child), 1)
|
|
298
300
|
}
|
|
299
|
-
|
|
301
|
+
item_content
|
|
300
302
|
}
|
|
301
303
|
}
|
|
302
304
|
}
|
|
303
305
|
|
|
304
|
-
//If this is the final
|
|
306
|
+
// If this is the final item, apply AFH 33-337 §11 rule:
|
|
305
307
|
// "Avoid dividing a paragraph of less than four lines between two pages"
|
|
306
308
|
blank-line()
|
|
307
309
|
if i == total_count {
|
|
@@ -309,16 +311,16 @@
|
|
|
309
311
|
|
|
310
312
|
// Use configured spacing for line height calculation
|
|
311
313
|
let line_height = measure(line(length: spacing.line + spacing.line-height)).width
|
|
312
|
-
// Calculate last
|
|
314
|
+
// Calculate last item's height
|
|
313
315
|
let par_height = measure(final_par, width: available_width).height
|
|
314
316
|
|
|
315
317
|
let estimated_lines = calc.ceil(par_height / line_height)
|
|
316
318
|
|
|
317
319
|
if estimated_lines < 4 {
|
|
318
|
-
// Short
|
|
320
|
+
// Short content (< 4 lines): make sticky to keep with signature
|
|
319
321
|
block(sticky: true)[#final_par]
|
|
320
322
|
} else {
|
|
321
|
-
// Longer
|
|
323
|
+
// Longer content (≥ 4 lines): use default breaking behavior
|
|
322
324
|
block(breakable: true)[#final_par]
|
|
323
325
|
}
|
|
324
326
|
} else {
|
|
@@ -158,19 +158,19 @@
|
|
|
158
158
|
blank-line()
|
|
159
159
|
// Circle the selected option using a box with rounded corners
|
|
160
160
|
// Use baseline parameter to maintain vertical text alignment
|
|
161
|
-
let approve-text = if action == "approve" {
|
|
162
|
-
box(stroke: 0.5pt + black, radius: 2pt, inset: 2pt, baseline: 2pt)[Approve]
|
|
161
|
+
let approve-text = if action == "approve" {
|
|
162
|
+
box(stroke: 0.5pt + black, radius: 2pt, inset: 2pt, baseline: 2pt)[Approve]
|
|
163
163
|
} else if action == "disapprove" {
|
|
164
164
|
strike[Approve]
|
|
165
|
-
} else {
|
|
166
|
-
[Approve]
|
|
165
|
+
} else {
|
|
166
|
+
[Approve]
|
|
167
167
|
}
|
|
168
|
-
let disapprove-text = if action == "disapprove" {
|
|
169
|
-
box(stroke: 0.5pt + black, radius: 2pt, inset: 2pt, baseline: 2pt)[Disapprove]
|
|
168
|
+
let disapprove-text = if action == "disapprove" {
|
|
169
|
+
box(stroke: 0.5pt + black, radius: 2pt, inset: 2pt, baseline: 2pt)[Disapprove]
|
|
170
170
|
} else if action == "approve" {
|
|
171
171
|
strike[Disapprove]
|
|
172
|
-
} else {
|
|
173
|
-
[Disapprove]
|
|
172
|
+
} else {
|
|
173
|
+
[Disapprove]
|
|
174
174
|
}
|
|
175
175
|
[#approve-text / #disapprove-text]
|
|
176
176
|
}
|
|
@@ -191,6 +191,9 @@
|
|
|
191
191
|
/// - it (content): The table element to style and render
|
|
192
192
|
/// -> content
|
|
193
193
|
#let render-memo-table(it) = {
|
|
194
|
+
// AFH 33-337 does not specify table formatting, so we follow the general
|
|
195
|
+
// aesthetic principles of the standard: bold headers for clarity.
|
|
196
|
+
show table.cell.where(y: 0): set text(weight: "bold")
|
|
194
197
|
set table(
|
|
195
198
|
stroke: 0.5pt + black,
|
|
196
199
|
inset: (x: 0.5em, y: 0.4em),
|