@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.11",
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
- // Item tuple: (content, nest_level, is_heading, is_table, is_continuation)
135
- pars.push((text([#p.body]), nest_level, is_heading, false, is_continuation))
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((t, -1, false, true, false))
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 tuple layout:
203
- // item.at(0) content : the paragraph body or table element
204
- // item.at(1)nest_level : nesting depth (−1 for tables)
205
- // item.at(2) is_heading : bool, true if item is a heading paragraph
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
- // Tables and continuation blocks do not count as distinct paragraphs
214
- // for AFH 33-337 §2 numbering purposes
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 is_table = item.at(ITEM_IS_TABLE, default: false)
232
+ let kind = item.kind
233
+ let item_content = item.content
235
234
 
236
- // Render tables inline without paragraph numbering
237
- if is_table {
238
- blank-line()
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
- let par_content = item.at(0)
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
- par_content = [#strong[#heading_buffer.] #par_content]
251
- }
252
- if is_heading {
253
- heading_buffer = par_content
254
- continue
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 is_continuation {
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(par_content, nest_level, level-counts)
265
+ format-continuation-par(item_content, nest_level, level-counts)
264
266
  } else if nest_level > 0 {
265
- format-continuation-par(par_content, nest_level - 1, level-counts)
267
+ format-continuation-par(item_content, nest_level - 1, level-counts)
266
268
  } else {
267
- par_content
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(par_content, nest_level, level-counts)
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
- par_content
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(par_content, effective_level, level-counts)
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
- par_content
301
+ item_content
300
302
  }
301
303
  }
302
304
  }
303
305
 
304
- //If this is the final paragraph, apply AFH 33-337 §11 rule:
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 par's height
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 paragraph (< 4 lines): make sticky to keep with signature
320
+ // Short content (< 4 lines): make sticky to keep with signature
319
321
  block(sticky: true)[#final_par]
320
322
  } else {
321
- // Longer paragraph (≥ 4 lines): use default breaking behavior
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),