@tonguetoquill/collection 0.7.2 → 0.8.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 (26) hide show
  1. package/package.json +2 -2
  2. package/quills/daf1206/0.1.0/Quill.yaml +11 -11
  3. package/quills/daf1206/0.1.0/example.md +11 -11
  4. package/quills/daf1206/0.1.0/packages/typst-daf1206/FIELDS.json +13 -13
  5. package/quills/daf1206/0.1.0/packages/typst-daf1206/form.typ +24 -24
  6. package/quills/daf1206/0.1.0/plate.typ +12 -12
  7. package/quills/daf4392/0.1.0/Quill.yaml +5 -3
  8. package/quills/daf4392/0.1.0/example.md +1 -1
  9. package/quills/daf4392/0.1.0/plate.typ +2 -2
  10. package/templates/daf1206.md +11 -11
  11. package/templates/daf4392.md +4 -5
  12. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/out/debug.typ +0 -4
  13. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/out/example.typ +0 -4
  14. package/quills/daf4392/0.1.0/packages/daf4392page2_pkg/page1.png +0 -0
  15. package/quills/daf4392/0.2.0/Quill.yaml +0 -140
  16. package/quills/daf4392/0.2.0/assets/arimo-v35-latin-700.ttf +0 -0
  17. package/quills/daf4392/0.2.0/assets/arimo-v35-latin-700italic.ttf +0 -0
  18. package/quills/daf4392/0.2.0/assets/arimo-v35-latin-italic.ttf +0 -0
  19. package/quills/daf4392/0.2.0/assets/arimo-v35-latin-regular.ttf +0 -0
  20. package/quills/daf4392/0.2.0/assets/page1.png +0 -0
  21. package/quills/daf4392/0.2.0/example.md +0 -34
  22. package/quills/daf4392/0.2.0/packages/daf4392page2_pkg/FIELDS.json +0 -9
  23. package/quills/daf4392/0.2.0/packages/daf4392page2_pkg/form.typ +0 -14
  24. package/quills/daf4392/0.2.0/packages/daf4392page2_pkg/lib.typ +0 -227
  25. package/quills/daf4392/0.2.0/packages/daf4392page2_pkg/typst.toml +0 -7
  26. package/quills/daf4392/0.2.0/plate.typ +0 -68
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tonguetoquill/collection",
3
- "version": "0.7.2",
3
+ "version": "0.8.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nibsbin/tonguetoquill-collection.git"
@@ -37,6 +37,6 @@
37
37
  "dependencies": {},
38
38
  "devDependencies": {
39
39
  "@quillmark/registry": "^0.10.0",
40
- "@quillmark/wasm": "^0.46.0"
40
+ "@quillmark/wasm": "^0.49.0"
41
41
  }
42
42
  }
@@ -10,42 +10,42 @@ main:
10
10
  ui:
11
11
  hide_body: true
12
12
  fields:
13
- award:
13
+ AWARD:
14
14
  title: Award
15
15
  type: string
16
16
  required: true
17
- category:
17
+ CATEGORY:
18
18
  title: Category (If Applicable)
19
19
  type: string
20
- award_period:
20
+ AWARD_PERIOD:
21
21
  title: Award Period
22
22
  type: string
23
23
  required: true
24
- rankname_of_nominee:
24
+ RANKNAME_OF_NOMINEE:
25
25
  title: Rank/Name of Nominee (First, Middle Initial, Last)
26
26
  type: string
27
27
  required: true
28
- majcom_fldcom_foa_or_dru:
28
+ MAJCOM_FLDCOM_FOA_OR_DRU:
29
29
  title: MAJCOM/FLDCOM/FOA/DRU
30
30
  type: string
31
- dafscduty_title:
31
+ DAFSCDUTY_TITLE:
32
32
  title: DAFSC/Duty Title
33
33
  type: string
34
- nominees_telephone:
34
+ NOMINEES_TELEPHONE:
35
35
  title: Nominee's Telephone (DSN/Commercial)
36
36
  type: string
37
- unitoffice_symbol:
37
+ UNITOFFICE_SYMBOL:
38
38
  title: Unit/Office Symbol/Street Address/Base/State/Zip Code
39
39
  type: string
40
- unit_commander:
40
+ UNIT_COMMANDER:
41
41
  title: Rank/Name of Unit Commander & Telephone
42
42
  type: string
43
- accomplishments:
43
+ ACCOMPLISHMENTS:
44
44
  title: Specific Accomplishments (Page 1)
45
45
  type: string
46
46
  ui:
47
47
  multiline: true
48
- accomplishments_continued:
48
+ ACCOMPLISHMENTS_CONTINUED:
49
49
  title: Specific Accomplishments (Continued - Page 2)
50
50
  type: string
51
51
  ui:
@@ -1,19 +1,19 @@
1
1
  ---
2
2
  QUILL: daf1206@0.1.0
3
- award: "AIR AND SPACE ACHIEVEMENT MEDAL"
4
- category: ""
5
- award_period: "1 Jan 24 - 31 Dec 24"
6
- rankname_of_nominee: "SSgt Doe, John A."
7
- majcom_fldcom_foa_or_dru: "ACC"
8
- dafscduty_title: "1D7X1 / Cyber Operator"
9
- nominees_telephone: "DSN: 123-4567 / Comm: (123) 456-7890"
10
- unitoffice_symbol: "1st Communications Squadron / SC, 123 Main St, AFB, ST 12345"
11
- unit_commander: "Capt Jane Smith / DSN: 123-4568 / Comm: (123) 456-7891"
3
+ AWARD: "AIR AND SPACE ACHIEVEMENT MEDAL"
4
+ CATEGORY: "asdfasdfasdf"
5
+ AWARD_PERIOD: "1 Jan 24 - 31 Dec 24 asdfasdfasdf"
6
+ RANKNAME_OF_NOMINEE: "SSgt Doe, John A."
7
+ MAJCOM_FLDCOM_FOA_OR_DRU: "ACC"
8
+ DAFSCDUTY_TITLE: "1D7X1 / Cyber Operator"
9
+ NOMINEES_TELEPHONE: "DSN: 123-4567 / Comm: (123) 456-7890"
10
+ UNITOFFICE_SYMBOL: "1st Communications Squadron / SC, 123 Main St, AFB, ST 12345"
11
+ UNIT_COMMANDER: "Capt Jane Smith / DSN: 123-4568 / Comm: (123) 456-7891"
12
12
 
13
- accomplishments: |-
13
+ ACCOMPLISHMENTS: |-
14
14
  - Spearheaded major network upgrade; improved speed by 50%
15
15
  - Mentored 5 Airmen; 100% upgrade training completion rate
16
16
 
17
- accomplishments_continued: |-
17
+ ACCOMPLISHMENTS_CONTINUED: |-
18
18
  - Continued excellence in supporting base communications
19
19
  ---
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "fields": [
13
13
  {
14
- "name": "award",
14
+ "name": "AWARD",
15
15
  "type": "text",
16
16
  "bbox": [
17
17
  21.479999542236328,
@@ -23,7 +23,7 @@
23
23
  "options": null
24
24
  },
25
25
  {
26
- "name": "category",
26
+ "name": "CATEGORY If Applicable",
27
27
  "type": "text",
28
28
  "bbox": [
29
29
  309.1199951171875,
@@ -35,7 +35,7 @@
35
35
  "options": null
36
36
  },
37
37
  {
38
- "name": "award_period",
38
+ "name": "AWARD PERIOD",
39
39
  "type": "text",
40
40
  "bbox": [
41
41
  424.9200134277344,
@@ -47,7 +47,7 @@
47
47
  "options": null
48
48
  },
49
49
  {
50
- "name": "rankname_of_nominee",
50
+ "name": "RANKNAME OF NOMINEE First Middle Initial Last",
51
51
  "type": "text",
52
52
  "bbox": [
53
53
  21.360000610351562,
@@ -59,7 +59,7 @@
59
59
  "options": null
60
60
  },
61
61
  {
62
- "name": "majcom_fldcom_foa_or_dru",
62
+ "name": "MAJCOM FLDCOM FOA OR DRU",
63
63
  "type": "text",
64
64
  "bbox": [
65
65
  350.1600036621094,
@@ -71,7 +71,7 @@
71
71
  "options": null
72
72
  },
73
73
  {
74
- "name": "dafscduty_title",
74
+ "name": "DAFSCDUTY TITLE",
75
75
  "type": "text",
76
76
  "bbox": [
77
77
  21.479999542236328,
@@ -83,7 +83,7 @@
83
83
  "options": null
84
84
  },
85
85
  {
86
- "name": "nominees_telephone",
86
+ "name": "NOMINEES TELEPHONE DSN Commercial",
87
87
  "type": "text",
88
88
  "bbox": [
89
89
  288.4800109863281,
@@ -95,7 +95,7 @@
95
95
  "options": null
96
96
  },
97
97
  {
98
- "name": "unitoffice_symbol",
98
+ "name": "UNITOFFICE SYMBOLSTREET ADDRESSBASESTATEZIP CODE",
99
99
  "type": "text",
100
100
  "bbox": [
101
101
  21.360000610351562,
@@ -107,7 +107,7 @@
107
107
  "options": null
108
108
  },
109
109
  {
110
- "name": "unit_commander",
110
+ "name": "RANKNAME OF UNIT COMMANDER First Middle Initial LastCOMMANDERS TELEPHONE DSN Commercial",
111
111
  "type": "text",
112
112
  "bbox": [
113
113
  21.479999542236328,
@@ -119,7 +119,7 @@
119
119
  "options": null
120
120
  },
121
121
  {
122
- "name": "accomplishments",
122
+ "name": "SPECIFIC ACCOMPLISHMENTS Use Performance Statements IAW DAFMAN 362806",
123
123
  "type": "text",
124
124
  "bbox": [
125
125
  22.079999923706055,
@@ -131,7 +131,7 @@
131
131
  "options": null
132
132
  },
133
133
  {
134
- "name": "rankname_of_nominee_2",
134
+ "name": "RANKNAME OF NOMINEE First Middle Initial Last_2",
135
135
  "type": "text",
136
136
  "bbox": [
137
137
  21.479999542236328,
@@ -143,7 +143,7 @@
143
143
  "options": null
144
144
  },
145
145
  {
146
- "name": "accomplishments_continued",
146
+ "name": "SPECIFIC ACCOMPLISHMENTS Use Performance Statements IAW DAFMAN 362806 Continued",
147
147
  "type": "text",
148
148
  "bbox": [
149
149
  22.079999923706055,
@@ -155,4 +155,4 @@
155
155
  "options": null
156
156
  }
157
157
  ]
158
- }
158
+ }
@@ -3,34 +3,34 @@
3
3
 
4
4
  #let form(
5
5
  debug: false,
6
- award: "", // text
7
- category: "", // text
8
- award_period: "", // text
9
- rankname_of_nominee: "", // text
10
- majcom_fldcom_foa_or_dru: "", // text
11
- dafscduty_title: "", // text
12
- nominees_telephone: "", // text
13
- unitoffice_symbol: "", // text
14
- unit_commander: "", // text
15
- accomplishments: "", // text
16
- rankname_of_nominee_2: "", // text
17
- accomplishments_continued: "", // text
6
+ AWARD: "", // text
7
+ CATEGORY_If_Applicable: "", // text
8
+ AWARD_PERIOD: "", // text
9
+ RANKNAME_OF_NOMINEE_First_Middle_Initial_Last: "", // text
10
+ MAJCOM_FLDCOM_FOA_OR_DRU: "", // text
11
+ DAFSCDUTY_TITLE: "", // text
12
+ NOMINEES_TELEPHONE__DSN__Commercial: "", // text
13
+ UNITOFFICE_SYMBOLSTREET_ADDRESSBASESTATEZIP_CODE: "", // text
14
+ RANKNAME_OF_UNIT_COMMANDER_First_Middle_Initial_LastCOMMANDERS_TELEPHONE_DSN__Commercial: "", // text
15
+ SPECIFIC_ACCOMPLISHMENTS_Use_Performance_Statements_IAW_DAFMAN_362806: "", // text
16
+ RANKNAME_OF_NOMINEE_First_Middle_Initial_Last_2: "", // text
17
+ SPECIFIC_ACCOMPLISHMENTS_Use_Performance_Statements_IAW_DAFMAN_362806_Continued: "", // text
18
18
  ) = render-form(
19
19
  schema: json("FIELDS.json"),
20
20
  backgrounds: ("page1.png", "page2.png",),
21
21
  values: (
22
- "award": award,
23
- "category": category,
24
- "award_period": award_period,
25
- "rankname_of_nominee": rankname_of_nominee,
26
- "majcom_fldcom_foa_or_dru": majcom_fldcom_foa_or_dru,
27
- "dafscduty_title": dafscduty_title,
28
- "nominees_telephone": nominees_telephone,
29
- "unitoffice_symbol": unitoffice_symbol,
30
- "unit_commander": unit_commander,
31
- "accomplishments": accomplishments,
32
- "rankname_of_nominee_2": rankname_of_nominee_2,
33
- "accomplishments_continued": accomplishments_continued,
22
+ "AWARD": AWARD,
23
+ "CATEGORY If Applicable": CATEGORY_If_Applicable,
24
+ "AWARD PERIOD": AWARD_PERIOD,
25
+ "RANKNAME OF NOMINEE First Middle Initial Last": RANKNAME_OF_NOMINEE_First_Middle_Initial_Last,
26
+ "MAJCOM FLDCOM FOA OR DRU": MAJCOM_FLDCOM_FOA_OR_DRU,
27
+ "DAFSCDUTY TITLE": DAFSCDUTY_TITLE,
28
+ "NOMINEES TELEPHONE DSN Commercial": NOMINEES_TELEPHONE__DSN__Commercial,
29
+ "UNITOFFICE SYMBOLSTREET ADDRESSBASESTATEZIP CODE": UNITOFFICE_SYMBOLSTREET_ADDRESSBASESTATEZIP_CODE,
30
+ "RANKNAME OF UNIT COMMANDER First Middle Initial LastCOMMANDERS TELEPHONE DSN Commercial": RANKNAME_OF_UNIT_COMMANDER_First_Middle_Initial_LastCOMMANDERS_TELEPHONE_DSN__Commercial,
31
+ "SPECIFIC ACCOMPLISHMENTS Use Performance Statements IAW DAFMAN 362806": SPECIFIC_ACCOMPLISHMENTS_Use_Performance_Statements_IAW_DAFMAN_362806,
32
+ "RANKNAME OF NOMINEE First Middle Initial Last_2": RANKNAME_OF_NOMINEE_First_Middle_Initial_Last_2,
33
+ "SPECIFIC ACCOMPLISHMENTS Use Performance Statements IAW DAFMAN 362806 Continued": SPECIFIC_ACCOMPLISHMENTS_Use_Performance_Statements_IAW_DAFMAN_362806_Continued,
34
34
  ),
35
35
  debug: debug,
36
36
  )
@@ -7,22 +7,22 @@
7
7
  #let vals = (:)
8
8
 
9
9
  // --- Admin fields (page 1 header) ---
10
- #if "award" in data { vals.insert("award", data.award) }
11
- #if "category" in data { vals.insert("category", data.category) }
12
- #if "award_period" in data { vals.insert("award_period", data.award_period) }
10
+ #if "AWARD" in data { vals.insert("AWARD", data.AWARD) }
11
+ #if "CATEGORY" in data { vals.insert("CATEGORY_If_Applicable", data.CATEGORY) }
12
+ #if "AWARD_PERIOD" in data { vals.insert("AWARD_PERIOD", data.AWARD_PERIOD) }
13
13
 
14
- #if "rankname_of_nominee" in data { vals.insert("rankname_of_nominee", data.rankname_of_nominee) }
15
- #if "rankname_of_nominee" in data { vals.insert("rankname_of_nominee_2", data.rankname_of_nominee) }
14
+ #if "RANKNAME_OF_NOMINEE" in data { vals.insert("RANKNAME_OF_NOMINEE_First_Middle_Initial_Last", data.RANKNAME_OF_NOMINEE) }
15
+ #if "RANKNAME_OF_NOMINEE" in data { vals.insert("RANKNAME_OF_NOMINEE_First_Middle_Initial_Last_2", data.RANKNAME_OF_NOMINEE) }
16
16
 
17
- #if "majcom_fldcom_foa_or_dru" in data { vals.insert("majcom_fldcom_foa_or_dru", data.majcom_fldcom_foa_or_dru) }
18
- #if "dafscduty_title" in data { vals.insert("dafscduty_title", data.dafscduty_title) }
19
- #if "nominees_telephone" in data { vals.insert("nominees_telephone", data.nominees_telephone) }
20
- #if "unitoffice_symbol" in data { vals.insert("unitoffice_symbol", data.unitoffice_symbol) }
21
- #if "unit_commander" in data { vals.insert("unit_commander", data.unit_commander) }
17
+ #if "MAJCOM_FLDCOM_FOA_OR_DRU" in data { vals.insert("MAJCOM_FLDCOM_FOA_OR_DRU", data.MAJCOM_FLDCOM_FOA_OR_DRU) }
18
+ #if "DAFSCDUTY_TITLE" in data { vals.insert("DAFSCDUTY_TITLE", data.DAFSCDUTY_TITLE) }
19
+ #if "NOMINEES_TELEPHONE" in data { vals.insert("NOMINEES_TELEPHONE__DSN__Commercial", data.NOMINEES_TELEPHONE) }
20
+ #if "UNITOFFICE_SYMBOL" in data { vals.insert("UNITOFFICE_SYMBOLSTREET_ADDRESSBASESTATEZIP_CODE", data.UNITOFFICE_SYMBOL) }
21
+ #if "UNIT_COMMANDER" in data { vals.insert("RANKNAME_OF_UNIT_COMMANDER_First_Middle_Initial_LastCOMMANDERS_TELEPHONE_DSN__Commercial", data.UNIT_COMMANDER) }
22
22
 
23
23
  // --- Accomplishments (page 1 & 2 content) ---
24
- #if "accomplishments" in data { vals.insert("accomplishments", data.accomplishments) }
25
- #if "accomplishments_continued" in data { vals.insert("accomplishments_continued", data.accomplishments_continued) }
24
+ #if "ACCOMPLISHMENTS" in data { vals.insert("SPECIFIC_ACCOMPLISHMENTS_Use_Performance_Statements_IAW_DAFMAN_362806", data.ACCOMPLISHMENTS) }
25
+ #if "ACCOMPLISHMENTS_CONTINUED" in data { vals.insert("SPECIFIC_ACCOMPLISHMENTS_Use_Performance_Statements_IAW_DAFMAN_362806_Continued", data.ACCOMPLISHMENTS_CONTINUED) }
26
26
 
27
27
  // Render the form with assembled values
28
28
  #form(..vals)
@@ -85,9 +85,10 @@ main:
85
85
  description: "Put in your Grade."
86
86
 
87
87
  emergency_contact:
88
- title: Emergency Contact
89
- type: string
90
- description: "Name and phone number of the emergency contact person at the bottom of the form."
88
+ title: Emergency Contacts
89
+ type: markdown
90
+ description: "Emergency contact (name and number)"
91
+
91
92
 
92
93
  cards:
93
94
  itinerary:
@@ -95,6 +96,7 @@ cards:
95
96
  description: "Each card represents one row in the travel itinerary table. Up to 10 rows are supported."
96
97
  ui:
97
98
  hide_body: true
99
+ default_title: Leg
98
100
  fields:
99
101
  date:
100
102
  title: Date
@@ -11,7 +11,7 @@ briefee_name: "Doe, Jane"
11
11
  briefee_grade: "O-1"
12
12
  briefer_name: ""
13
13
  briefer_grade: ""
14
- emergency_contact: "John Doe: 999-999-9999"
14
+ emergency_contact: "John Doe, 999-999-9999"
15
15
  ---
16
16
 
17
17
  ---
@@ -1,4 +1,4 @@
1
- #import "@local/quillmark-helper:0.1.0": data
1
+ #import "@local/quillmark-helper:0.1.0": data, eval-markup
2
2
 
3
3
  #set page(width: 8.5in, height: 11in, margin: 0in)
4
4
  #set text(font: "Arimo", size: 10pt)
@@ -65,4 +65,4 @@
65
65
  #tf(270pt, 680pt)[#data.at("briefer_grade", default: "")]
66
66
 
67
67
  // Emergency Contact
68
- #tf(40pt, 700pt)[#text(size: 10pt, weight: "bold")[EMERGENCY CONTACT:] #text(size: 10pt)[#data.at("emergency_contact", default: "")]]
68
+ #tf(40pt, 700pt)[#text(size: 10pt, weight: "bold")[EMERGENCY CONTACT:] #text(size: 10pt)[#eval-markup(data.at("emergency_contact", default:""))]]
@@ -2,30 +2,30 @@
2
2
  QUILL: daf1206@0.1.0
3
3
 
4
4
  # EDIT: Award name (e.g., "AIR AND SPACE ACHIEVEMENT MEDAL")
5
- award: "AWARD NAME"
5
+ AWARD: "AWARD NAME"
6
6
  # EDIT: Category (If Applicable)
7
- category: ""
7
+ CATEGORY: ""
8
8
  # EDIT: Award Period (e.g., "1 Jan 24 - 31 Dec 24")
9
- award_period: "1 Jan 2X - 31 Dec 2X"
9
+ AWARD_PERIOD: "1 Jan 2X - 31 Dec 2X"
10
10
  # EDIT: Rank/Name of Nominee (First, Middle Initial, Last)
11
- rankname_of_nominee: "LAST, FIRST M."
11
+ RANKNAME_OF_NOMINEE: "LAST, FIRST M."
12
12
  # EDIT: MAJCOM/FLDCOM/FOA/DRU
13
- majcom_fldcom_foa_or_dru: ""
13
+ MAJCOM_FLDCOM_FOA_OR_DRU: ""
14
14
  # EDIT: DAFSC/Duty Title
15
- dafscduty_title: ""
15
+ DAFSCDUTY_TITLE: ""
16
16
  # EDIT: Nominee's Telephone (DSN/Commercial)
17
- nominees_telephone: ""
17
+ NOMINEES_TELEPHONE: ""
18
18
  # EDIT: Unit/Office Symbol/Street Address/Base/State/Zip Code
19
- unitoffice_symbol: ""
19
+ UNITOFFICE_SYMBOL: ""
20
20
  # EDIT: Rank/Name of Unit Commander & Telephone
21
- unit_commander: ""
21
+ UNIT_COMMANDER: ""
22
22
 
23
23
  # EDIT: Specific Accomplishments (Page 1)
24
- accomplishments: |-
24
+ ACCOMPLISHMENTS: |-
25
25
  -
26
26
  -
27
27
 
28
28
  # EDIT: Specific Accomplishments (Continued - Page 2)
29
- accomplishments_continued: |-
29
+ ACCOMPLISHMENTS_CONTINUED: |-
30
30
  -
31
31
  ---
@@ -1,5 +1,5 @@
1
1
  ---
2
- QUILL: daf4392
2
+ QUILL: daf4392@0.1
3
3
 
4
4
  transportation_mode: "other"
5
5
  departure_date: "XX Mar 26"
@@ -11,12 +11,11 @@ briefee_name: "Doe, Jane"
11
11
  briefee_grade: "O-1"
12
12
  briefer_name: ""
13
13
  briefer_grade: ""
14
- emergency_contact_name: "John Doe"
15
- emergency_contact_phone: "999-999-9999"
14
+ emergency_contact: "John Doe, 999-999-9999"
16
15
  ---
17
16
 
18
17
  ---
19
- CARD: leg
18
+ CARD: itinerary
20
19
  date: "XX Mar"
21
20
  departure_point: "Biloxi, MS"
22
21
  arrival_point: "Fake City, MS"
@@ -25,7 +24,7 @@ mileage: "250"
25
24
  ---
26
25
 
27
26
  ---
28
- CARD: leg
27
+ CARD: itinerary
29
28
  date: "XX Mar"
30
29
  departure_point: "Fake City, MS"
31
30
  arrival_point: "Biloxi, MS"
@@ -1,4 +0,0 @@
1
- // debug.typ (generated � renders form with debug overlays)
2
- #import "../form.typ": form
3
-
4
- #form(debug: true)
@@ -1,4 +0,0 @@
1
- // example.typ (edit this file to fill the form)
2
- #import "../form.typ": form
3
-
4
- #form()
@@ -1,140 +0,0 @@
1
- Quill:
2
- name: daf4392
3
- version: 0.2.0
4
- backend: typst
5
- plate_file: plate.typ
6
- example_file: example.md
7
- description: "DAF Form 4392 - Pre-Departure Safety Briefing (Page 2)"
8
-
9
- main:
10
- ui:
11
- hide_body: true
12
- fields:
13
- transportation_mode:
14
- title: Mode of Transportation
15
- type: string
16
- enum: [pmv, airplane, bus, train, motorcycle, other]
17
- required: true
18
- description: "Matches the check box."
19
-
20
-
21
- departure_date:
22
- title: Departure Date
23
- type: date
24
- required: true
25
- ui:
26
- compact: true
27
- description: "Date of initial departure."
28
-
29
- final_destination:
30
- title: Final Destination
31
- type: string
32
- required: true
33
- ui:
34
- compact: true
35
- description: "Final travel destination."
36
-
37
- dept_flight_num:
38
- title: Departure Flight Number
39
- type: string
40
- ui:
41
- compact: true
42
- description: "Departure flight number. (tenative or confirmed)"
43
-
44
- arrival_flight_num:
45
- title: Arrival Flight Number
46
- type: string
47
- ui:
48
- compact: true
49
- description: "Arrival flight number. (tenative or confirmed)"
50
-
51
- notes:
52
- title: Notes
53
- type: string
54
- description: "Additional notes or remarks for the travel."
55
-
56
- organization:
57
- title: Organization
58
- type: string
59
- required: true
60
- ui:
61
- compact: true
62
- description: "Unit / Organization."
63
-
64
- briefed_date:
65
- title: Date Briefed
66
- type: date
67
- required: true
68
- ui:
69
- compact: true
70
- description: "Put in today's date."
71
-
72
- briefee_name:
73
- title: Individual Receiving Brief (Name)
74
- type: string
75
- required: true
76
- ui:
77
- compact: true
78
- description: "Put in your Name (Last, First)."
79
-
80
- briefee_grade:
81
- title: Individual Receiving Brief (Grade)
82
- type: string
83
- ui:
84
- compact: true
85
- description: "Put in your Grade."
86
-
87
- emergency_contact_name:
88
- title: Emergency Contact Name
89
- type: string
90
- required: true
91
- description: "Put in your Emergency Contact Name."
92
-
93
- emergency_contact_phone:
94
- title: Emergency Contact Phone
95
- type: string
96
- required: true
97
- description: "Put in your Emergency Contact's Phone Number."
98
-
99
- cards:
100
- leg:
101
- title: Proposed Travel Itinerary
102
- description: "Each card represents one row in the travel itinerary table. Up to 10 rows are supported."
103
- ui:
104
- hide_body: true
105
- fields:
106
- date:
107
- title: Date
108
- type: date
109
- ui:
110
- group: Itinerary Entry
111
- compact: true
112
- description: "Date for the itinerary row."
113
- departure_point:
114
- title: Departure Point
115
- type: string
116
- ui:
117
- group: Itinerary Entry
118
- compact: true
119
- description: "Point of departure."
120
- arrival_point:
121
- title: Arrival Point
122
- type: string
123
- ui:
124
- group: Itinerary Entry
125
- compact: true
126
- description: "Point of arrival."
127
- rest_length:
128
- title: Length of Rest Period
129
- type: string
130
- ui:
131
- group: Itinerary Entry
132
- compact: true
133
- description: "Duration of stay at arrival point"
134
- mileage:
135
- title: Approximate Mileage
136
- type: string
137
- ui:
138
- group: Itinerary Entry
139
- compact: true
140
- description: "Approximate mileage for this leg (leave blank if not applicable, e.g., flights)."
@@ -1,34 +0,0 @@
1
- ---
2
- QUILL: daf4392
3
-
4
- transportation_mode: "other"
5
- departure_date: "XX Mar 26"
6
- final_destination: "123 Sesame St, Fake City, MS"
7
- notes: "Visiting Donald Duck over 3 day weekend."
8
- organization: "333 TRS"
9
- briefed_date: "XX Mar 26"
10
- briefee_name: "Doe, Jane"
11
- briefee_grade: "O-1"
12
- briefer_name: ""
13
- briefer_grade: ""
14
- emergency_contact_name: "John Doe"
15
- emergency_contact_phone: "999-999-9999"
16
- ---
17
-
18
- ---
19
- CARD: leg
20
- date: "XX Mar"
21
- departure_point: "Biloxi, MS"
22
- arrival_point: "Fake City, MS"
23
- rest_length: "2 days"
24
- mileage: "250"
25
- ---
26
-
27
- ---
28
- CARD: leg
29
- date: "XX Mar"
30
- departure_point: "Fake City, MS"
31
- arrival_point: "Biloxi, MS"
32
- rest_length: "0"
33
- mileage: "0"
34
- ---
@@ -1,9 +0,0 @@
1
- {
2
- "pages": [
3
- {
4
- "width": 612.0,
5
- "height": 792.0
6
- }
7
- ],
8
- "fields": []
9
- }
@@ -1,14 +0,0 @@
1
- // form.typ (generated � do not edit)
2
- #import "lib.typ": render-form
3
-
4
- #let form(
5
- debug: false,
6
-
7
- ) = render-form(
8
- schema: json("FIELDS.json"),
9
- backgrounds: ("page1.png",),
10
- values: (
11
- ,
12
- ),
13
- debug: debug,
14
- )
@@ -1,227 +0,0 @@
1
- // Formalizer Engine – rendering engine
2
- // Renders pixel-perfect PDF form replicas from a PyMuPDF-extracted schema.
3
-
4
- /// Render a single field's content overlay.
5
- ///
6
- /// - field-type (str): normalised lowercase type
7
- /// - value: user-supplied value for this field (or none)
8
- /// - width (length): field width
9
- /// - height (length): field height
10
- /// - field (dictionary): raw field entry from the schema
11
- #let render-field(field-type, value, width, height, field) = {
12
- if field-type == "text" {
13
- if value != none and str(value) != "" {
14
- context {
15
- let default-size = height * 0.6
16
- let min-size = 6pt
17
- let x-inset = 1.5pt
18
- let m = measure(text(size: default-size, str(value)))
19
- let scale = calc.min(1.0, (width - 2 * x-inset) / m.width)
20
- let final-size = calc.max(min-size, default-size * scale)
21
- box(
22
- width: width,
23
- height: height,
24
- clip: true,
25
- inset: (x: x-inset),
26
- align(left + horizon, text(size: final-size, str(value))),
27
- )
28
- }
29
- }
30
- } else if field-type == "checkbox" {
31
- if value == true {
32
- box(
33
- width: width,
34
- height: height,
35
- align(center + horizon, text(size: height * 0.8, "✓")),
36
- )
37
- }
38
- } else if field-type == "radio" {
39
- // value is true when this specific button is the selected one
40
- // (resolved at group level before calling this helper)
41
- if value == true {
42
- let dot-r = calc.min(width, height) * 0.3
43
- box(
44
- width: width,
45
- height: height,
46
- align(center + horizon, circle(radius: dot-r, fill: black)),
47
- )
48
- }
49
- } else if field-type == "combobox" or field-type == "listbox" {
50
- let display = if value != none { str(value) } else { "" }
51
- // Resolve export value → display label when options are present
52
- if field.at("options", default: none) != none and value != none {
53
- for opt in field.options {
54
- if str(opt.at(0)) == str(value) {
55
- display = str(opt.at(1))
56
- }
57
- }
58
- }
59
- if display != "" {
60
- context {
61
- let default-size = height * 0.6
62
- let min-size = 6pt
63
- let x-inset = 2pt
64
- let m = measure(text(size: default-size, display))
65
- let scale = calc.min(1.0, (width - 2 * x-inset) / m.width)
66
- let final-size = calc.max(min-size, default-size * scale)
67
- box(
68
- width: width,
69
- height: height,
70
- clip: true,
71
- inset: (x: x-inset),
72
- align(left + horizon, text(size: final-size, display)),
73
- )
74
- }
75
- }
76
- }
77
- }
78
-
79
- /// Determine whether a single radio button should appear selected.
80
- ///
81
- /// Strategy:
82
- /// 1. If the field carries an `export_value` key, match against it.
83
- /// 2. Otherwise fall back to matching the 0-based index within the group
84
- /// (stringified) against the supplied value.
85
- #let radio-button-selected(field, group-value, index-in-group) = {
86
- if group-value == none { return false }
87
- let ev = field.at("export_value", default: none)
88
- if ev != none {
89
- return str(ev) == str(group-value)
90
- }
91
- // Fallback: match against the stringified index
92
- str(index-in-group) == str(group-value)
93
- }
94
-
95
- /// Draw a debug overlay rectangle with a label for a field.
96
- ///
97
- /// - field-type (str): normalised lowercase type
98
- /// - name (str): field name
99
- /// - width (length): field width
100
- /// - height (length): field height
101
- #let debug-overlay(field-type, name, width, height) = {
102
- let color = if field-type == "text" {
103
- rgb(0, 0, 255, 40%)
104
- } else if field-type == "checkbox" {
105
- rgb(0, 128, 0, 40%)
106
- } else if field-type == "radio" {
107
- rgb(255, 165, 0, 40%)
108
- } else if field-type == "combobox" {
109
- rgb(128, 0, 128, 40%)
110
- } else if field-type == "listbox" {
111
- rgb(0, 128, 128, 40%)
112
- } else {
113
- rgb(128, 128, 128, 40%)
114
- }
115
-
116
- let stroke-color = if field-type == "text" {
117
- rgb(0, 0, 255)
118
- } else if field-type == "checkbox" {
119
- rgb(0, 128, 0)
120
- } else if field-type == "radio" {
121
- rgb(255, 165, 0)
122
- } else if field-type == "combobox" {
123
- rgb(128, 0, 128)
124
- } else if field-type == "listbox" {
125
- rgb(0, 128, 128)
126
- } else {
127
- rgb(128, 128, 128)
128
- }
129
-
130
- // Insert zero-width spaces after _ and - so the label can wrap
131
- let breakable-name = name.replace("_", "_\u{200B}").replace("-", "-\u{200B}")
132
- let label = breakable-name + " [" + field-type + "]"
133
-
134
- box(width: width, height: height, {
135
- // Semi-transparent colored background
136
- rect(width: 100%, height: 100%, fill: color, stroke: 0.5pt + stroke-color)
137
- // Label in top-left — uses block so text wraps within field width
138
- place(
139
- top + left,
140
- dx: 1pt,
141
- dy: 1pt,
142
- block(
143
- width: calc.max(width - 2pt, 10pt),
144
- fill: white,
145
- inset: (x: 2pt, y: 1pt),
146
- radius: 2pt,
147
- stroke: 0.3pt + stroke-color,
148
- breakable: false,
149
- text(size: 5pt, fill: stroke-color, weight: "bold", label),
150
- ),
151
- )
152
- })
153
- }
154
-
155
- /// Main entry point.
156
- ///
157
- /// - schema (dictionary): result of `json("FIELDS.json")`
158
- /// - backgrounds (array): list of image paths / bytes, one per page
159
- /// - values (dictionary): field name → value; omit to render blank
160
- /// - debug (bool): when true, draw colored overlays on each field
161
- #let render-form(schema: none, backgrounds: (), values: (:), debug: false) = {
162
- assert(schema != none, message: "render-form: `schema` is required")
163
- assert(backgrounds.len() > 0, message: "render-form: `backgrounds` is required")
164
- let pages = schema.pages
165
- let fields = schema.fields
166
-
167
- // Track how many radio buttons we have seen per group so far
168
- let radio-counters = (:)
169
-
170
- for (i, page-info) in pages.enumerate() {
171
- let page-num = i + 1
172
- let page-fields = fields.filter(f => f.page == page-num)
173
-
174
- let bg = backgrounds.at(i)
175
- let pw = page-info.width * 1pt
176
- let ph = page-info.height * 1pt
177
-
178
- page(
179
- width: pw,
180
- height: ph,
181
- margin: 0pt,
182
- )[
183
- // Background image (the original PDF page rasterised as PNG)
184
- #place(top + left, image(bg, width: pw, height: ph, fit: "stretch"))
185
-
186
- // Field overlays
187
- #for field in page-fields.filter(f => ("text", "checkbox", "radio", "combobox", "listbox").contains(lower(
188
- f.type,
189
- ))) {
190
- let x = field.bbox.at(0) * 1pt
191
- let y = field.bbox.at(1) * 1pt
192
- let w = (field.bbox.at(2) - field.bbox.at(0)) * 1pt
193
- let h = (field.bbox.at(3) - field.bbox.at(1)) * 1pt
194
-
195
- let field-type = lower(field.type)
196
- let val = values.at(field.name, default: none)
197
-
198
- // --- Radio: resolve group-level value to per-button boolean ---
199
- if field-type == "radio" {
200
- let group-name = field.name
201
- let idx = radio-counters.at(group-name, default: 0)
202
- radio-counters.insert(group-name, idx + 1)
203
- val = radio-button-selected(field, val, idx)
204
- }
205
-
206
- place(
207
- top + left,
208
- dx: x,
209
- dy: y,
210
- render-field(field-type, val, w, h, field),
211
- )
212
-
213
- if debug {
214
- place(
215
- top + left,
216
- dx: x,
217
- dy: y,
218
- debug-overlay(field-type, field.name, w, h),
219
- )
220
- }
221
-
222
- // Zero-width fence to break PDF viewer text-selection grouping
223
- place(top + left, dx: x, dy: y, text(size: 0.001pt, "\u{FEFF}"))
224
- }
225
- ]
226
- }
227
- }
@@ -1,7 +0,0 @@
1
- [package]
2
- name = "daf4392page2-pkg"
3
- version = "0.1.0"
4
- entrypoint = "form.typ"
5
- authors = ["formalizer"]
6
- license = "Apache-2.0"
7
- description = "Fillable form package generated by formalizer"
@@ -1,68 +0,0 @@
1
- #import "@local/quillmark-helper:0.1.0": data
2
-
3
- #set page(width: 8.5in, height: 11in, margin: 0in)
4
- #set text(font: "Arimo", size: 10pt)
5
-
6
- // Background
7
- #place(image("assets/page1.png", width: 100%, height: 100%))
8
-
9
- #let tf(dx, dy, content) = place(dx: dx, dy: dy, content)
10
- #let check(dx, dy, is_checked) = if is_checked { place(dx: dx, dy: dy, text(weight: "bold", size: 12pt)[✓]) }
11
-
12
- // Mode of Transportation
13
- #let mode = data.at("transportation_mode", default: "")
14
- #check(40pt, 67pt, mode == "pmv")
15
- #check(173pt, 67pt, mode == "airplane")
16
- #check(243pt, 67pt, mode == "bus")
17
- #check(286pt, 67pt, mode == "train")
18
- #check(336pt, 67pt, mode == "motorcycle")
19
- #check(411pt, 67pt, mode == "other")
20
-
21
- // Fields
22
- #tf(40pt, 100pt)[#data.at("departure_date", default: "")]
23
- #tf(123pt, 100pt)[#data.at("final_destination", default: "")]
24
-
25
- // Itinerary Rows (via CARDS)
26
- #{
27
- let row = 0
28
- let dy-start = 160pt
29
- let dy-step = 40pt
30
- if "CARDS" in data {
31
- for card in data.CARDS {
32
- if card.CARD == "itinerary" and row < 10 {
33
- let dy = dy-start + (row * dy-step)
34
- tf(80pt, dy)[#card.at("date", default: "")]
35
- tf(135pt, dy)[#card.at("departure_point", default: "")]
36
- tf(295pt, dy)[#card.at("arrival_point", default: "")]
37
- tf(450pt, dy)[#card.at("rest_length", default: "")]
38
- tf(515pt, dy)[#card.at("mileage", default: "")]
39
- row = row + 1
40
- }
41
- }
42
- }
43
- }
44
-
45
- // Flight Info
46
- #{
47
- let d-flight = str(data.at("dept_flight_num", default: ""))
48
- if d-flight != "" { tf(350pt, 545pt)[#text(weight: "bold")[Dept Flight:] #d-flight] }
49
-
50
- let a-flight = str(data.at("arrival_flight_num", default: ""))
51
- if a-flight != "" { tf(450pt, 545pt)[#text(weight: "bold")[Arr Flight:] #a-flight] }
52
- }
53
-
54
- // Notes
55
- #tf(40pt, 565pt)[#block(width: 530pt)[#data.at("notes", default: "")]]
56
-
57
- // Acknowledgements
58
- #tf(40pt, 620pt)[#data.at("organization", default: "")]
59
- #tf(500pt, 620pt)[#data.at("briefed_date", default: "")]
60
-
61
- #tf(40pt, 650pt)[#data.at("briefee_name", default: "")]
62
- #tf(270pt, 650pt)[#data.at("briefee_grade", default: "")]
63
-
64
- #tf(40pt, 680pt)[#data.at("briefer_name", default: "")]
65
- #tf(270pt, 680pt)[#data.at("briefer_grade", default: "")]
66
-
67
- // Emergency Contact
68
- #tf(40pt, 700pt)[#text(size: 10pt, weight: "bold")[EMERGENCY CONTACT:] #text(size: 10pt)[#data.at("emergency_contact_name", default: ""): #data.at("emergency_contact_phone", default: "")]]