@tonguetoquill/collection 0.2.3 → 0.2.5-beta.1

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.
Files changed (102) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +39 -39
  3. package/index.d.ts +2 -2
  4. package/index.js +8 -8
  5. package/package.json +41 -41
  6. package/quills/af4141/0.1.0/Quill.yaml +88 -88
  7. package/quills/af4141/0.1.0/design/TASK.md +19 -19
  8. package/quills/af4141/0.1.0/example.md +35 -35
  9. package/quills/af4141/0.1.0/packages/typst-af4141/FIELDS.json +3169 -3169
  10. package/quills/af4141/0.1.0/packages/typst-af4141/form.typ +538 -538
  11. package/quills/af4141/0.1.0/packages/typst-af4141/lib.typ +227 -227
  12. package/quills/af4141/0.1.0/packages/typst-af4141/typst.toml +7 -7
  13. package/quills/af4141/0.1.0/plate.typ +48 -48
  14. package/quills/classic_resume/0.1.0/Quill.yaml +118 -118
  15. package/quills/classic_resume/0.1.0/example.md +232 -232
  16. package/quills/classic_resume/0.1.0/packages/ttq-classic-resume/LICENSE +21 -21
  17. package/quills/classic_resume/0.1.0/packages/ttq-classic-resume/README.md +38 -38
  18. package/quills/classic_resume/0.1.0/packages/ttq-classic-resume/src/components.typ +184 -184
  19. package/quills/classic_resume/0.1.0/packages/ttq-classic-resume/src/layout.typ +42 -42
  20. package/quills/classic_resume/0.1.0/packages/ttq-classic-resume/src/lib.typ +5 -5
  21. package/quills/classic_resume/0.1.0/packages/ttq-classic-resume/typst.toml +26 -26
  22. package/quills/classic_resume/0.1.0/plate.typ +44 -44
  23. package/quills/cmu_letter/0.1.0/.quillignore +30 -30
  24. package/quills/cmu_letter/0.1.0/Quill.yaml +64 -64
  25. package/quills/cmu_letter/0.1.0/assets/cmu-wordmark.svg +174 -174
  26. package/quills/cmu_letter/0.1.0/example.md +30 -30
  27. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/LICENSE +21 -21
  28. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/fonts/README.txt +100 -100
  29. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/src/backmatter.typ +13 -13
  30. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/src/config.typ +39 -39
  31. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/src/frontmatter.typ +72 -72
  32. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/src/lib.typ +47 -47
  33. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/src/mainmatter.typ +42 -42
  34. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/src/primitives.typ +70 -70
  35. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/src/utils.typ +85 -85
  36. package/quills/cmu_letter/0.1.0/packages/tonguetoquill-cmu-letter/typst.toml +17 -17
  37. package/quills/cmu_letter/0.1.0/plate.typ +19 -19
  38. package/quills/daf4392/0.1.0/Quill.yaml +110 -0
  39. package/quills/daf4392/0.1.0/assets/arimo-v35-latin-700.ttf +0 -0
  40. package/quills/daf4392/0.1.0/assets/arimo-v35-latin-700italic.ttf +0 -0
  41. package/quills/daf4392/0.1.0/assets/arimo-v35-latin-italic.ttf +0 -0
  42. package/quills/daf4392/0.1.0/assets/arimo-v35-latin-regular.ttf +0 -0
  43. package/quills/daf4392/0.1.0/assets/page1.png +0 -0
  44. package/quills/daf4392/0.1.0/example.md +33 -0
  45. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/FIELDS.json +9 -0
  46. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/form.typ +14 -0
  47. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/lib.typ +227 -0
  48. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/out/debug.typ +4 -0
  49. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/out/example.typ +4 -0
  50. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/page1.png +0 -0
  51. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/typst.toml +7 -0
  52. package/quills/daf4392/0.1.0/plate.typ +60 -0
  53. package/quills/taro/0.1.0/Quill.yaml +29 -29
  54. package/quills/taro/0.1.0/example.md +26 -26
  55. package/quills/taro/0.1.0/plate.typ +31 -31
  56. package/quills/usaf_memo/0.1.0/.quillignore +30 -30
  57. package/quills/usaf_memo/0.1.0/Quill.yaml +209 -209
  58. package/quills/usaf_memo/0.1.0/example.md +54 -54
  59. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/LICENSE +21 -21
  60. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/fonts/Cinzel/LICENSE +93 -93
  61. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/fonts/CopperplateCC/LICENSE.md +79 -79
  62. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/fonts/NimbusRomanNo9L/GNU General Public License.txt +339 -339
  63. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/backmatter.typ +28 -28
  64. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/body.typ +332 -332
  65. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/config.typ +63 -63
  66. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/frontmatter.typ +114 -114
  67. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/indorsement.typ +118 -118
  68. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/lib.typ +55 -55
  69. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/mainmatter.typ +32 -32
  70. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/primitives.typ +272 -272
  71. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/src/utils.typ +377 -377
  72. package/quills/usaf_memo/0.1.0/packages/tonguetoquill-usaf-memo/typst.toml +16 -16
  73. package/quills/usaf_memo/0.1.0/plate.typ +74 -74
  74. package/quills/usaf_memo/0.2.0/.quillignore +30 -30
  75. package/quills/usaf_memo/0.2.0/Quill.yaml +219 -219
  76. package/quills/usaf_memo/0.2.0/example.md +55 -55
  77. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/.gitignore +6 -6
  78. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/LICENSE +21 -21
  79. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/fonts/Cinzel/LICENSE +93 -93
  80. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/fonts/CopperplateCC/LICENSE.md +79 -79
  81. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/fonts/NimbusRomanNo9L/GNU General Public License.txt +339 -339
  82. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/backmatter.typ +28 -28
  83. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/body.typ +333 -333
  84. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/config.typ +64 -64
  85. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/frontmatter.typ +114 -114
  86. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/indorsement.typ +118 -118
  87. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/lib.typ +55 -55
  88. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/mainmatter.typ +32 -32
  89. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/primitives.typ +293 -293
  90. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/src/utils.typ +374 -374
  91. package/quills/usaf_memo/0.2.0/packages/tonguetoquill-usaf-memo/typst.toml +27 -27
  92. package/quills/usaf_memo/0.2.0/plate.typ +75 -75
  93. package/templates/af4141.md +88 -88
  94. package/templates/cmu_letter_template.md +37 -37
  95. package/templates/daf4392.md +33 -0
  96. package/templates/loc.md +78 -78
  97. package/templates/pass_request.md +43 -43
  98. package/templates/rebuttal.md +55 -55
  99. package/templates/taro.md +26 -26
  100. package/templates/templates.json +55 -49
  101. package/templates/usaf_template.md +23 -23
  102. package/templates/ussf_template.md +29 -29
@@ -1,64 +1,64 @@
1
- // config.typ: Configuration constants and defaults for USAF memorandum template
2
- //
3
- // This module defines core configuration values that implement AFH 33-337 Chapter 14
4
- // formatting requirements for official USAF memorandums.
5
-
6
- // =============================================================================
7
- // SPACING CONSTANTS
8
- // =============================================================================
9
- // AFH 33-337 specifies precise spacing requirements throughout Chapter 14
10
-
11
- #let spacing = (
12
- vertical: 19.05pt, // Base gap between elements
13
- line: .5em, // Internal line spacing for readability
14
- line-height: .7em, // Base height of text lines for pagination estimates
15
- tab: 0.5in, // Tab stop for multi-column recipient alignment
16
- margin: 1in, // AFH 33-337 §4: "Use 1-inch margins on the left, right and bottom"
17
- )
18
-
19
- // =============================================================================
20
- // TYPOGRAPHY DEFAULTS
21
- // =============================================================================
22
- // AFH 33-337 §5: "Use 12 point Times New Roman font for text"
23
-
24
- #let DEFAULT_LETTERHEAD_FONTS = ("Copperplate CC",)
25
- #let DEFAULT_BODY_FONTS = ("times new roman", "NimbusRomNo9L") // AFH 33-337 §5: Times New Roman required
26
- #let LETTERHEAD_COLOR = rgb("#204093") // Faded USAF blue for letterhead
27
-
28
- // =============================================================================
29
- // PARAGRAPH CONFIGURATION
30
- // =============================================================================
31
- // AFH 33-337 "The Text of the Official Memorandum" §2:
32
- // "Number and letter each paragraph and subparagraph"
33
- // Hierarchical numbering: 1., a., (1), (a), etc.
34
-
35
- #let paragraph-config = (
36
- counter-prefix: "par-counter-",
37
- // AFH 33-337 §2: Hierarchical paragraph numbering format
38
- // Level 0: 1., 2., 3. | Level 1: a., b., c. | Level 2: (1), (2), (3) | Level 3: (a), (b), (c)
39
- numbering-formats: ("1.", "a.", "(1)", "(a)", n => underline(str(n)), n => underline(str(n))),
40
- )
41
-
42
- // =============================================================================
43
- // COUNTERS
44
- // =============================================================================
45
-
46
- #let counters = (
47
- indorsement: counter("indorsement"),
48
- )
49
-
50
- // =============================================================================
51
- // CLASSIFICATION COLORS
52
- // =============================================================================
53
- // AFH 33-337 §3: "Follow AFI 31-401, Information Security Program Management,
54
- // applicable executive orders and DoD guidance for the necessary markings on
55
- // classified correspondence."
56
- // Color values follow DoD standard classification marking colors
57
- // Source: https://security.stackexchange.com/questions/161829
58
-
59
- #let CLASSIFICATION_COLORS = (
60
- "UNCLASSIFIED": rgb(0, 122, 51), // Forest green (#007A33)
61
- "CONFIDENTIAL": rgb(0, 51, 160), // Deep blue (#0033A0)
62
- "SECRET": rgb(200, 16, 46), // Crimson red (#C8102E)
63
- "TOP SECRET": rgb(255, 103, 31), // Burnt orange (#FF671F)
64
- )
1
+ // config.typ: Configuration constants and defaults for USAF memorandum template
2
+ //
3
+ // This module defines core configuration values that implement AFH 33-337 Chapter 14
4
+ // formatting requirements for official USAF memorandums.
5
+
6
+ // =============================================================================
7
+ // SPACING CONSTANTS
8
+ // =============================================================================
9
+ // AFH 33-337 specifies precise spacing requirements throughout Chapter 14
10
+
11
+ #let spacing = (
12
+ vertical: 19.05pt, // Base gap between elements
13
+ line: .5em, // Internal line spacing for readability
14
+ line-height: .7em, // Base height of text lines for pagination estimates
15
+ tab: 0.5in, // Tab stop for multi-column recipient alignment
16
+ margin: 1in, // AFH 33-337 §4: "Use 1-inch margins on the left, right and bottom"
17
+ )
18
+
19
+ // =============================================================================
20
+ // TYPOGRAPHY DEFAULTS
21
+ // =============================================================================
22
+ // AFH 33-337 §5: "Use 12 point Times New Roman font for text"
23
+
24
+ #let DEFAULT_LETTERHEAD_FONTS = ("Copperplate CC",)
25
+ #let DEFAULT_BODY_FONTS = ("times new roman", "NimbusRomNo9L") // AFH 33-337 §5: Times New Roman required
26
+ #let LETTERHEAD_COLOR = rgb("#204093") // Faded USAF blue for letterhead
27
+
28
+ // =============================================================================
29
+ // PARAGRAPH CONFIGURATION
30
+ // =============================================================================
31
+ // AFH 33-337 "The Text of the Official Memorandum" §2:
32
+ // "Number and letter each paragraph and subparagraph"
33
+ // Hierarchical numbering: 1., a., (1), (a), etc.
34
+
35
+ #let paragraph-config = (
36
+ counter-prefix: "par-counter-",
37
+ // AFH 33-337 §2: Hierarchical paragraph numbering format
38
+ // Level 0: 1., 2., 3. | Level 1: a., b., c. | Level 2: (1), (2), (3) | Level 3: (a), (b), (c)
39
+ numbering-formats: ("1.", "a.", "(1)", "(a)", n => underline(str(n)), n => underline(str(n))),
40
+ )
41
+
42
+ // =============================================================================
43
+ // COUNTERS
44
+ // =============================================================================
45
+
46
+ #let counters = (
47
+ indorsement: counter("indorsement"),
48
+ )
49
+
50
+ // =============================================================================
51
+ // CLASSIFICATION COLORS
52
+ // =============================================================================
53
+ // AFH 33-337 §3: "Follow AFI 31-401, Information Security Program Management,
54
+ // applicable executive orders and DoD guidance for the necessary markings on
55
+ // classified correspondence."
56
+ // Color values follow DoD standard classification marking colors
57
+ // Source: https://security.stackexchange.com/questions/161829
58
+
59
+ #let CLASSIFICATION_COLORS = (
60
+ "UNCLASSIFIED": rgb(0, 122, 51), // Forest green (#007A33)
61
+ "CONFIDENTIAL": rgb(0, 51, 160), // Deep blue (#0033A0)
62
+ "SECRET": rgb(200, 16, 46), // Crimson red (#C8102E)
63
+ "TOP SECRET": rgb(255, 103, 31), // Burnt orange (#FF671F)
64
+ )
@@ -1,114 +1,114 @@
1
- // frontmatter.typ: Frontmatter show rule for USAF memorandum
2
- //
3
- // This module implements the frontmatter (heading section) of a USAF memorandum
4
- // per AFH 33-337 Chapter 14 "The Heading Section". It handles:
5
- // - Page setup with proper margins
6
- // - Letterhead rendering
7
- // - Date, MEMORANDUM FOR, FROM, SUBJECT, and References placement
8
- // - Classification markings in headers/footers
9
-
10
- #import "primitives.typ": *
11
-
12
- #let frontmatter(
13
- subject: none,
14
- memo_for: none,
15
- memo_from: none,
16
- date: none,
17
- references: none,
18
- letterhead_title: "DEPARTMENT OF THE AIR FORCE",
19
- letterhead_caption: "[YOUR SQUADRON/UNIT NAME]",
20
- letterhead_seal: none,
21
- letterhead_font: DEFAULT_LETTERHEAD_FONTS,
22
- body_font: DEFAULT_BODY_FONTS,
23
- font_size: 12pt,
24
- memo_for_cols: 3,
25
- classification_level: none,
26
- footer_tag_line: none,
27
- auto_numbering: true,
28
- it,
29
- ) = {
30
- assert(subject != none, message: "subject is required")
31
- assert(memo_for != none, message: "memo_for is required")
32
- assert(memo_from != none, message: "memo_from is required")
33
-
34
- let actual_date = if date == none { datetime.today() } else { date }
35
- let classification_color = get-classification-level-color(classification_level)
36
-
37
- // Document-wide typography settings (inlined from configure())
38
- set par(leading: spacing.line, spacing: spacing.line, justify: false)
39
- set block(above: spacing.line, below: 0em, spacing: 0em)
40
- set text(font: body_font, size: font_size, fallback: true)
41
-
42
- set page(
43
- paper: "us-letter",
44
- // AFH 33-337 §4: "Use 1-inch margins on the left, right and bottom"
45
- margin: (
46
- left: spacing.margin,
47
- right: spacing.margin,
48
- top: spacing.margin,
49
- bottom: spacing.margin,
50
- ),
51
- header: {
52
- // AFH 33-337 "Page numbering" §12: "The first page of a memorandum is never numbered.
53
- // Number the succeeding pages starting with page 2. Place page numbers 0.5-inch from
54
- // the top of the page, flush with the right margin."
55
- context if counter(page).get().first() > 1 {
56
- place(
57
- dy: +.5in,
58
- block(
59
- width: 100%,
60
- align(right, text(12pt)[#counter(page).display()]),
61
- ),
62
- )
63
- }
64
-
65
- if classification_level != none {
66
- place(
67
- top + center,
68
- dy: 0.375in,
69
- text(12pt, font: DEFAULT_BODY_FONTS, fill: classification_color)[#strong(classification_level)],
70
- )
71
- }
72
- },
73
- footer: {
74
- place(
75
- bottom + center,
76
- dy: -.375in,
77
- text(12pt, font: DEFAULT_BODY_FONTS, fill: classification_color)[#strong(classification_level)],
78
- )
79
-
80
- if not falsey(footer_tag_line) {
81
- place(
82
- bottom + center,
83
- dy: -0.625in,
84
- align(center)[
85
- #text(fill: LETTERHEAD_COLOR, font: "cinzel", size: 15pt)[#footer_tag_line]
86
- ],
87
- )
88
- }
89
- },
90
- )
91
-
92
- render-letterhead(letterhead_title, letterhead_caption, letterhead_seal, letterhead_font)
93
-
94
- // AFH 33-337 "Date": "Place the date 1 inch from the right edge, 1.75 inches from the top"
95
- // Since we have a 1-inch top margin, we need (1.75in - margin) vertical space
96
- v(1.75in - spacing.margin)
97
-
98
- render-date-section(actual_date)
99
- render-for-section(memo_for, memo_for_cols)
100
- render-from-section(memo_from)
101
- render-subject-section(subject)
102
- render-references-section(references)
103
-
104
- metadata((
105
- subject: subject,
106
- original_date: actual_date,
107
- original_from: first-or-value(memo_from),
108
- body_font: body_font,
109
- font_size: font_size,
110
- auto_numbering: auto_numbering,
111
- ))
112
-
113
- it
114
- }
1
+ // frontmatter.typ: Frontmatter show rule for USAF memorandum
2
+ //
3
+ // This module implements the frontmatter (heading section) of a USAF memorandum
4
+ // per AFH 33-337 Chapter 14 "The Heading Section". It handles:
5
+ // - Page setup with proper margins
6
+ // - Letterhead rendering
7
+ // - Date, MEMORANDUM FOR, FROM, SUBJECT, and References placement
8
+ // - Classification markings in headers/footers
9
+
10
+ #import "primitives.typ": *
11
+
12
+ #let frontmatter(
13
+ subject: none,
14
+ memo_for: none,
15
+ memo_from: none,
16
+ date: none,
17
+ references: none,
18
+ letterhead_title: "DEPARTMENT OF THE AIR FORCE",
19
+ letterhead_caption: "[YOUR SQUADRON/UNIT NAME]",
20
+ letterhead_seal: none,
21
+ letterhead_font: DEFAULT_LETTERHEAD_FONTS,
22
+ body_font: DEFAULT_BODY_FONTS,
23
+ font_size: 12pt,
24
+ memo_for_cols: 3,
25
+ classification_level: none,
26
+ footer_tag_line: none,
27
+ auto_numbering: true,
28
+ it,
29
+ ) = {
30
+ assert(subject != none, message: "subject is required")
31
+ assert(memo_for != none, message: "memo_for is required")
32
+ assert(memo_from != none, message: "memo_from is required")
33
+
34
+ let actual_date = if date == none { datetime.today() } else { date }
35
+ let classification_color = get-classification-level-color(classification_level)
36
+
37
+ // Document-wide typography settings (inlined from configure())
38
+ set par(leading: spacing.line, spacing: spacing.line, justify: false)
39
+ set block(above: spacing.line, below: 0em, spacing: 0em)
40
+ set text(font: body_font, size: font_size, fallback: true)
41
+
42
+ set page(
43
+ paper: "us-letter",
44
+ // AFH 33-337 §4: "Use 1-inch margins on the left, right and bottom"
45
+ margin: (
46
+ left: spacing.margin,
47
+ right: spacing.margin,
48
+ top: spacing.margin,
49
+ bottom: spacing.margin,
50
+ ),
51
+ header: {
52
+ // AFH 33-337 "Page numbering" §12: "The first page of a memorandum is never numbered.
53
+ // Number the succeeding pages starting with page 2. Place page numbers 0.5-inch from
54
+ // the top of the page, flush with the right margin."
55
+ context if counter(page).get().first() > 1 {
56
+ place(
57
+ dy: +.5in,
58
+ block(
59
+ width: 100%,
60
+ align(right, text(12pt)[#counter(page).display()]),
61
+ ),
62
+ )
63
+ }
64
+
65
+ if classification_level != none {
66
+ place(
67
+ top + center,
68
+ dy: 0.375in,
69
+ text(12pt, font: DEFAULT_BODY_FONTS, fill: classification_color)[#strong(classification_level)],
70
+ )
71
+ }
72
+ },
73
+ footer: {
74
+ place(
75
+ bottom + center,
76
+ dy: -.375in,
77
+ text(12pt, font: DEFAULT_BODY_FONTS, fill: classification_color)[#strong(classification_level)],
78
+ )
79
+
80
+ if not falsey(footer_tag_line) {
81
+ place(
82
+ bottom + center,
83
+ dy: -0.625in,
84
+ align(center)[
85
+ #text(fill: LETTERHEAD_COLOR, font: "cinzel", size: 15pt)[#footer_tag_line]
86
+ ],
87
+ )
88
+ }
89
+ },
90
+ )
91
+
92
+ render-letterhead(letterhead_title, letterhead_caption, letterhead_seal, letterhead_font)
93
+
94
+ // AFH 33-337 "Date": "Place the date 1 inch from the right edge, 1.75 inches from the top"
95
+ // Since we have a 1-inch top margin, we need (1.75in - margin) vertical space
96
+ v(1.75in - spacing.margin)
97
+
98
+ render-date-section(actual_date)
99
+ render-for-section(memo_for, memo_for_cols)
100
+ render-from-section(memo_from)
101
+ render-subject-section(subject)
102
+ render-references-section(references)
103
+
104
+ metadata((
105
+ subject: subject,
106
+ original_date: actual_date,
107
+ original_from: first-or-value(memo_from),
108
+ body_font: body_font,
109
+ font_size: font_size,
110
+ auto_numbering: auto_numbering,
111
+ ))
112
+
113
+ it
114
+ }
@@ -1,118 +1,118 @@
1
- // indorsement.typ: Indorsement rendering for USAF memorandum
2
- //
3
- // This module implements indorsements (endorsements) per AFH 33-337 Chapter 14.
4
- // Indorsements are used to forward memorandums with additional commentary.
5
- // They follow the format: "1st Ind", "2d Ind", "3d Ind", etc.
6
- // Each indorsement includes its own body text and signature block.
7
- //
8
- // Note: When using #show: indorsement.with(...), the indorsement wraps the
9
- // entire remainder of the document. This works for a single indorsement at
10
- // the end of a file. For multiple indorsements, use the function call syntax:
11
- // #indorsement(...)[Body text...]
12
-
13
- #import "primitives.typ": *
14
- #import "body.typ": *
15
-
16
- #let indorsement(
17
- from: none,
18
- to: none,
19
- signature_block: none,
20
- signature_blank_lines: 4,
21
- attachments: none,
22
- cc: none,
23
- date: none,
24
- // Format of indorsement: "standard" (same page), "informal" (no header), or "separate_page" (starts on new page)
25
- format: "standard",
26
- // Approval action: none (default, no action line displayed), "undecided", "approve", or "disapprove".
27
- // When set to "undecided", the action line is displayed with neither option circled.
28
- // When set to "approve" or "disapprove", the action line is displayed with the selected option circled.
29
- action: none,
30
- content,
31
- ) = {
32
- // Validate format parameter
33
- assert(
34
- format in ("standard", "informal", "separate_page"),
35
- message: "format must be \"standard\", \"informal\", or \"separate_page\"",
36
- )
37
-
38
- if format != "informal" {
39
- assert(from != none, message: "from is required")
40
- assert(to != none, message: "to is required")
41
- }
42
-
43
-
44
- let actual_date = if date == none { datetime.today() } else { date }
45
- let ind_from = first-or-value(from)
46
- let ind_for = to
47
-
48
- if format != "informal" {
49
- // Step the counter BEFORE the context block to avoid read-then-update loop
50
- counters.indorsement.step()
51
-
52
- context {
53
- let config = query(metadata).last().value
54
- let original_subject = config.subject
55
- let original_date = config.original_date
56
- let original_from = config.original_from
57
-
58
- // Read the counter value (already stepped above)
59
- let indorsement_number = counters.indorsement.get().at(0, default: 1)
60
- let indorsement_label = format-indorsement-number(indorsement_number)
61
-
62
- if format == "separate_page" {
63
- pagebreak()
64
- [#indorsement_label to #original_from, #display-date(original_date), #original_subject]
65
-
66
- blank-line()
67
- grid(
68
- columns: (auto, 1fr),
69
- ind_from, align(right)[#display-date(actual_date)],
70
- )
71
-
72
- blank-line()
73
- grid(
74
- columns: (auto, auto, 1fr),
75
- "MEMORANDUM FOR", " ", ind_for,
76
- )
77
- } else {
78
- blank-line()
79
- grid(
80
- columns: (auto, 1fr),
81
- [#indorsement_label, #ind_from], align(right)[#display-date(actual_date)],
82
- )
83
-
84
- blank-line()
85
- grid(
86
- columns: (auto, auto, 1fr),
87
- "MEMORANDUM FOR", " ", ind_for,
88
- )
89
- }
90
- }
91
- blank-line()
92
- }
93
-
94
- // Show action line only when an action decision is set (not `none`)
95
- if action != none {
96
- render-action-line(action)
97
- }
98
-
99
- render-body(content)
100
-
101
- render-signature-block(signature_block, signature-blank-lines: signature_blank_lines)
102
-
103
- if not falsey(attachments) {
104
- calculate-backmatter-spacing(true)
105
- let attachment-count = attachments.len()
106
- let section-label = if attachment-count == 1 { "Attachment:" } else { str(attachment-count) + " Attachments:" }
107
- let continuation-label = (
108
- (if attachment-count == 1 { "Attachment" } else { str(attachment-count) + " Attachments" })
109
- + " (listed on next page):"
110
- )
111
- render-backmatter-section(attachments, section-label, numbering-style: "1.", continuation-label: continuation-label)
112
- }
113
-
114
- if not falsey(cc) {
115
- calculate-backmatter-spacing(falsey(attachments))
116
- render-backmatter-section(cc, "cc:")
117
- }
118
- }
1
+ // indorsement.typ: Indorsement rendering for USAF memorandum
2
+ //
3
+ // This module implements indorsements (endorsements) per AFH 33-337 Chapter 14.
4
+ // Indorsements are used to forward memorandums with additional commentary.
5
+ // They follow the format: "1st Ind", "2d Ind", "3d Ind", etc.
6
+ // Each indorsement includes its own body text and signature block.
7
+ //
8
+ // Note: When using #show: indorsement.with(...), the indorsement wraps the
9
+ // entire remainder of the document. This works for a single indorsement at
10
+ // the end of a file. For multiple indorsements, use the function call syntax:
11
+ // #indorsement(...)[Body text...]
12
+
13
+ #import "primitives.typ": *
14
+ #import "body.typ": *
15
+
16
+ #let indorsement(
17
+ from: none,
18
+ to: none,
19
+ signature_block: none,
20
+ signature_blank_lines: 4,
21
+ attachments: none,
22
+ cc: none,
23
+ date: none,
24
+ // Format of indorsement: "standard" (same page), "informal" (no header), or "separate_page" (starts on new page)
25
+ format: "standard",
26
+ // Approval action: none (default, no action line displayed), "undecided", "approve", or "disapprove".
27
+ // When set to "undecided", the action line is displayed with neither option circled.
28
+ // When set to "approve" or "disapprove", the action line is displayed with the selected option circled.
29
+ action: none,
30
+ content,
31
+ ) = {
32
+ // Validate format parameter
33
+ assert(
34
+ format in ("standard", "informal", "separate_page"),
35
+ message: "format must be \"standard\", \"informal\", or \"separate_page\"",
36
+ )
37
+
38
+ if format != "informal" {
39
+ assert(from != none, message: "from is required")
40
+ assert(to != none, message: "to is required")
41
+ }
42
+
43
+
44
+ let actual_date = if date == none { datetime.today() } else { date }
45
+ let ind_from = first-or-value(from)
46
+ let ind_for = to
47
+
48
+ if format != "informal" {
49
+ // Step the counter BEFORE the context block to avoid read-then-update loop
50
+ counters.indorsement.step()
51
+
52
+ context {
53
+ let config = query(metadata).last().value
54
+ let original_subject = config.subject
55
+ let original_date = config.original_date
56
+ let original_from = config.original_from
57
+
58
+ // Read the counter value (already stepped above)
59
+ let indorsement_number = counters.indorsement.get().at(0, default: 1)
60
+ let indorsement_label = format-indorsement-number(indorsement_number)
61
+
62
+ if format == "separate_page" {
63
+ pagebreak()
64
+ [#indorsement_label to #original_from, #display-date(original_date), #original_subject]
65
+
66
+ blank-line()
67
+ grid(
68
+ columns: (auto, 1fr),
69
+ ind_from, align(right)[#display-date(actual_date)],
70
+ )
71
+
72
+ blank-line()
73
+ grid(
74
+ columns: (auto, auto, 1fr),
75
+ "MEMORANDUM FOR", " ", ind_for,
76
+ )
77
+ } else {
78
+ blank-line()
79
+ grid(
80
+ columns: (auto, 1fr),
81
+ [#indorsement_label, #ind_from], align(right)[#display-date(actual_date)],
82
+ )
83
+
84
+ blank-line()
85
+ grid(
86
+ columns: (auto, auto, 1fr),
87
+ "MEMORANDUM FOR", " ", ind_for,
88
+ )
89
+ }
90
+ }
91
+ blank-line()
92
+ }
93
+
94
+ // Show action line only when an action decision is set (not `none`)
95
+ if action != none {
96
+ render-action-line(action)
97
+ }
98
+
99
+ render-body(content)
100
+
101
+ render-signature-block(signature_block, signature-blank-lines: signature_blank_lines)
102
+
103
+ if not falsey(attachments) {
104
+ calculate-backmatter-spacing(true)
105
+ let attachment-count = attachments.len()
106
+ let section-label = if attachment-count == 1 { "Attachment:" } else { str(attachment-count) + " Attachments:" }
107
+ let continuation-label = (
108
+ (if attachment-count == 1 { "Attachment" } else { str(attachment-count) + " Attachments" })
109
+ + " (listed on next page):"
110
+ )
111
+ render-backmatter-section(attachments, section-label, numbering-style: "1.", continuation-label: continuation-label)
112
+ }
113
+
114
+ if not falsey(cc) {
115
+ calculate-backmatter-spacing(falsey(attachments))
116
+ render-backmatter-section(cc, "cc:")
117
+ }
118
+ }