laporan-generator 2.6.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 (109) hide show
  1. package/.agents/skills/laporan-generator/SKILL.md +132 -0
  2. package/.agents/skills/laporan-generator/agents/openai.yaml +3 -0
  3. package/.agents/skills/laporan-generator/references/campus-guide.md +120 -0
  4. package/.agents/skills/laporan-generator/references/metadata-schema.md +76 -0
  5. package/.agents/skills/laporan-generator/references/preset-schema.md +79 -0
  6. package/.agents/skills/laporan-generator/references/syntax-cheatsheet.md +122 -0
  7. package/.agents/skills/laporan-generator/references/template-guide.md +100 -0
  8. package/.agents/skills/laporan-generator/references/troubleshooting.md +105 -0
  9. package/.agents/skills/laporan-generator/resources/Makefile +90 -0
  10. package/.agents/skills/laporan-generator/resources/apa.csl +2273 -0
  11. package/.agents/skills/laporan-generator/resources/build-docx.sh +122 -0
  12. package/.agents/skills/laporan-generator/resources/build.sh +102 -0
  13. package/.agents/skills/laporan-generator/resources/chapters/bab1-pendahuluan.md +60 -0
  14. package/.agents/skills/laporan-generator/resources/chapters/bab2-tinjauan-pustaka.md +83 -0
  15. package/.agents/skills/laporan-generator/resources/chapters/bab3-metodologi.md +116 -0
  16. package/.agents/skills/laporan-generator/resources/chapters/bab4-hasil-dan-pembahasan.md +93 -0
  17. package/.agents/skills/laporan-generator/resources/chapters/bab5-penutup.md +27 -0
  18. package/.agents/skills/laporan-generator/resources/cover.md +50 -0
  19. package/.agents/skills/laporan-generator/resources/docx.lua +416 -0
  20. package/.agents/skills/laporan-generator/resources/laporan +464 -0
  21. package/.agents/skills/laporan-generator/resources/laporan.ps1 +552 -0
  22. package/.agents/skills/laporan-generator/resources/logo.jpg +0 -0
  23. package/.agents/skills/laporan-generator/resources/metadata.yml +35 -0
  24. package/.agents/skills/laporan-generator/resources/presets/itb-ta.yml +27 -0
  25. package/.agents/skills/laporan-generator/resources/presets/its-skripsi.yml +26 -0
  26. package/.agents/skills/laporan-generator/resources/presets/skripsi-4433.yml +26 -0
  27. package/.agents/skills/laporan-generator/resources/presets/standard.yml +26 -0
  28. package/.agents/skills/laporan-generator/resources/presets/ugm-skripsi.yml +26 -0
  29. package/.agents/skills/laporan-generator/resources/presets/ui-skripsi.yml +26 -0
  30. package/.agents/skills/laporan-generator/resources/presets/unpad-skripsi.yml +27 -0
  31. package/.agents/skills/laporan-generator/resources/reference.docx +0 -0
  32. package/.agents/skills/laporan-generator/resources/references.bib +115 -0
  33. package/.agents/skills/laporan-generator/resources/scripts/bundle.py +75 -0
  34. package/.agents/skills/laporan-generator/resources/scripts/docx-pagenum.py +192 -0
  35. package/.agents/skills/laporan-generator/resources/scripts/finalize-docx.py +291 -0
  36. package/.agents/skills/laporan-generator/resources/scripts/make-reference-docx.py +670 -0
  37. package/.agents/skills/laporan-generator/resources/scripts/report-doctor.py +211 -0
  38. package/.agents/skills/laporan-generator/resources/scripts/report-stats.py +149 -0
  39. package/.agents/skills/laporan-generator/resources/scripts/scan-preset.py +311 -0
  40. package/.agents/skills/laporan-generator/resources/scripts/setup-deps.ps1 +152 -0
  41. package/.agents/skills/laporan-generator/resources/scripts/setup-deps.sh +113 -0
  42. package/.agents/skills/laporan-generator/resources/scripts/test_scripts.py +128 -0
  43. package/.agents/skills/laporan-generator/resources/scripts/validate-preset.py +166 -0
  44. package/.agents/skills/laporan-generator/resources/template.typ +394 -0
  45. package/.agents/skills/laporan-generator/scripts/build.sh +78 -0
  46. package/.agents/skills/laporan-generator/scripts/bundle.py +75 -0
  47. package/.agents/skills/laporan-generator/scripts/docx-pagenum.py +192 -0
  48. package/.agents/skills/laporan-generator/scripts/finalize-docx.py +152 -0
  49. package/.agents/skills/laporan-generator/scripts/laporan +447 -0
  50. package/.agents/skills/laporan-generator/scripts/laporan.ps1 +529 -0
  51. package/.agents/skills/laporan-generator/scripts/make-reference-docx.py +630 -0
  52. package/.agents/skills/laporan-generator/scripts/report-doctor.py +211 -0
  53. package/.agents/skills/laporan-generator/scripts/report-stats.py +149 -0
  54. package/.agents/skills/laporan-generator/scripts/scan-preset.py +311 -0
  55. package/.agents/skills/laporan-generator/scripts/setup-deps.ps1 +152 -0
  56. package/.agents/skills/laporan-generator/scripts/setup-deps.sh +113 -0
  57. package/.agents/skills/laporan-generator/scripts/test_scripts.py +103 -0
  58. package/.agents/skills/laporan-generator/scripts/validate-preset.py +166 -0
  59. package/.agents/workflows/laporan-generator.md +8 -0
  60. package/LICENSE +21 -0
  61. package/Makefile +90 -0
  62. package/README.md +389 -0
  63. package/apa.csl +2273 -0
  64. package/bin/laporan-generator.js +71 -0
  65. package/build-docx.sh +122 -0
  66. package/build.sh +102 -0
  67. package/chapters/bab1-pendahuluan.md +60 -0
  68. package/chapters/bab2-tinjauan-pustaka.md +83 -0
  69. package/chapters/bab3-metodologi.md +116 -0
  70. package/chapters/bab4-hasil-dan-pembahasan.md +93 -0
  71. package/chapters/bab5-penutup.md +27 -0
  72. package/cover.md +50 -0
  73. package/docs/campus-guide.md +120 -0
  74. package/docs/metadata-schema.md +76 -0
  75. package/docs/preset-schema.md +79 -0
  76. package/docs/syntax-cheatsheet.md +122 -0
  77. package/docs/template-guide.md +100 -0
  78. package/docs/troubleshooting.md +105 -0
  79. package/docx.lua +416 -0
  80. package/laporan +464 -0
  81. package/laporan.ps1 +552 -0
  82. package/lib/init.js +118 -0
  83. package/lib/setup.js +33 -0
  84. package/lib/sync-hosts.js +194 -0
  85. package/lib/uninstall.js +123 -0
  86. package/logo.jpg +0 -0
  87. package/metadata.yml +35 -0
  88. package/package.json +65 -0
  89. package/presets/itb-ta.yml +27 -0
  90. package/presets/its-skripsi.yml +26 -0
  91. package/presets/skripsi-4433.yml +26 -0
  92. package/presets/standard.yml +26 -0
  93. package/presets/ugm-skripsi.yml +26 -0
  94. package/presets/ui-skripsi.yml +26 -0
  95. package/presets/unpad-skripsi.yml +27 -0
  96. package/reference.docx +0 -0
  97. package/references.bib +115 -0
  98. package/scripts/bundle.py +75 -0
  99. package/scripts/docx-pagenum.py +192 -0
  100. package/scripts/finalize-docx.py +291 -0
  101. package/scripts/make-reference-docx.py +670 -0
  102. package/scripts/report-doctor.py +211 -0
  103. package/scripts/report-stats.py +149 -0
  104. package/scripts/scan-preset.py +311 -0
  105. package/scripts/setup-deps.ps1 +152 -0
  106. package/scripts/setup-deps.sh +113 -0
  107. package/scripts/test_scripts.py +128 -0
  108. package/scripts/validate-preset.py +166 -0
  109. package/template.typ +394 -0
package/template.typ ADDED
@@ -0,0 +1,394 @@
1
+ #set document(
2
+ title: "$title$",
3
+ author: ($for(author)$"$author.name$"$sep$,$endfor$),
4
+ )
5
+
6
+ $if(margin_top)$
7
+ #let doc-margin = (
8
+ top: $margin_top$,
9
+ bottom: $margin_bottom$,
10
+ left: $margin_left$,
11
+ right: $margin_right$,
12
+ )
13
+ $else$
14
+ #let doc-margin = if "$margin_preset$" == "skripsi-4433" or "$margin_preset$" == "4-4-3-3" {
15
+ (top: 4cm, bottom: 3cm, left: 4cm, right: 3cm)
16
+ } else {
17
+ (top: 2cm, bottom: 3cm, left: 2.5cm, right: 2.5cm)
18
+ }
19
+ $endif$
20
+
21
+ #set page(
22
+ paper: "a4",
23
+ margin: doc-margin,
24
+ numbering: none,
25
+ )
26
+
27
+ $if(font_family)$
28
+ #set text(font: "$font_family$", size: $if(font_size)$$font_size$$else$12pt$endif$)
29
+ $else$
30
+ #set text(font: "Libertinus Serif", size: 12pt)
31
+ $endif$
32
+
33
+ $if(line_spacing)$
34
+ #set par(justify: true, leading: $line_spacing$, first-line-indent: $if(first_line_indent)$$first_line_indent$$else$1.25cm$endif$)
35
+ $else$
36
+ #set par(justify: true, leading: 0.75em, first-line-indent: 1.25cm)
37
+ $endif$
38
+ #show bibliography: set par(hanging-indent: $if(first_line_indent)$$first_line_indent$$else$1.25cm$endif$, first-line-indent: 0cm)
39
+
40
+ #let raw-prefix = "$if(heading_chapter_prefix)$$heading_chapter_prefix$$else$BAB $endif$"
41
+ #let chapter-prefix = if raw-prefix == "" {
42
+ ""
43
+ } else if raw-prefix.ends-with(" ") {
44
+ raw-prefix
45
+ } else {
46
+ raw-prefix + " "
47
+ }
48
+ #let chapter-fmt = "$if(heading_chapter_num_format)$$heading_chapter_num_format$$else$roman$endif$"
49
+ #let format-chapter-num(n) = {
50
+ if chapter-fmt == "arabic" {
51
+ numbering("1", n)
52
+ } else {
53
+ numbering("I", n)
54
+ }
55
+ }
56
+
57
+ #set heading(numbering: (..ns) => {
58
+ if ns.len() == 1 {
59
+ if chapter-prefix != "" {
60
+ chapter-prefix + format-chapter-num(ns.at(0))
61
+ } else {
62
+ format-chapter-num(ns.at(0))
63
+ }
64
+ } else if ns.len() == 2 {
65
+ numbering("$if(heading_sub_dot)$1.1.$else$1.1$endif$", ..ns)
66
+ } else {
67
+ numbering("$if(heading_subsub_dot)$1.1.1.$else$1.1.1$endif$", ..ns)
68
+ }
69
+ })
70
+
71
+ #show figure.where(kind: image): set figure(
72
+ supplement: [Gambar],
73
+ numbering: it => {
74
+ let ch = counter(heading).get().at(0, default: 1)
75
+ str(ch) + "." + str(it)
76
+ }
77
+ )
78
+
79
+ #show figure.where(kind: table): set figure(
80
+ supplement: [Tabel],
81
+ numbering: it => {
82
+ let ch = counter(heading).get().at(0, default: 1)
83
+ str(ch) + "." + str(it)
84
+ }
85
+ )
86
+
87
+ #show figure.where(kind: raw): set figure(
88
+ supplement: [Listing],
89
+ numbering: it => {
90
+ let ch = counter(heading).get().at(0, default: 1)
91
+ str(ch) + "." + str(it)
92
+ }
93
+ )
94
+
95
+ #set math.equation(numbering: it => "(" + str(counter(heading).get().at(0, default: 1)) + "." + str(it) + ")")
96
+
97
+ #show heading.where(level: 1): it => {
98
+ counter(figure.where(kind: image)).update(0)
99
+ counter(figure.where(kind: table)).update(0)
100
+ counter(figure.where(kind: raw)).update(0)
101
+ counter(math.equation).update(0)
102
+ pagebreak(weak: true)
103
+ align(center)[
104
+ #block(inset: (top: 0.5em, bottom: 1.8em))[
105
+ #text(size: 14pt, weight: "bold")[
106
+ #if it.numbering != none [
107
+ #if chapter-prefix != "" [
108
+ #(chapter-prefix + format-chapter-num(counter(heading).get().at(0)))
109
+ #linebreak()
110
+ ] else [
111
+ #(format-chapter-num(counter(heading).get().at(0)) + ". ")
112
+ ]
113
+ #if it.body.has("text") [
114
+ #upper(it.body.text)
115
+ ] else [
116
+ #upper(it.body)
117
+ ]
118
+ ] else [
119
+ #it.body
120
+ ]
121
+ ]
122
+ ]
123
+ ]
124
+ }
125
+
126
+ #show heading.where(level: 2): it => {
127
+ block(above: 1.0em, below: 0.5em)[
128
+ #text(size: 12pt, weight: "bold")[#it]
129
+ ]
130
+ par(leading: 0.75em)[]
131
+ }
132
+
133
+ #show heading.where(level: 3): it => {
134
+ block(above: 0.8em, below: 0.4em)[
135
+ #text(size: 12pt, weight: "bold")[#it]
136
+ ]
137
+ par(leading: 0.75em)[]
138
+ }
139
+
140
+ #show figure: it => it + par[]
141
+ #show list: it => it + par[]
142
+ #show enum: it => it + par[]
143
+ #show quote: it => {
144
+ block(
145
+ fill: rgb("#f3f4f6"),
146
+ stroke: (left: 3.5pt + rgb("#2563eb")),
147
+ inset: (x: 12pt, y: 8pt),
148
+ radius: (right: 4pt),
149
+ width: 100%,
150
+ )[
151
+ #set text(size: 10.5pt, style: "italic")
152
+ #set par(justify: true, leading: 0.65em)
153
+ #it.body
154
+ ]
155
+ }
156
+ #show table: it => it + par[]
157
+ #show raw.where(block: true): it => {
158
+ block(
159
+ fill: rgb("#f8f9fa"),
160
+ stroke: 0.5pt + rgb("#d1d5db"),
161
+ inset: (x: 10pt, y: 8pt),
162
+ radius: 4pt,
163
+ width: 100%,
164
+ )[
165
+ #set text(font: "DejaVu Sans Mono", size: 8.5pt)
166
+ #set par(justify: false, leading: 0.55em)
167
+ #it
168
+ ]
169
+ }
170
+
171
+ #show outline.entry.where(level: 1): set text(weight: "bold")
172
+ #set par(leading: 0.75em)
173
+
174
+ #let balance-split(title, k) = {
175
+ let words = title.split(" ")
176
+ let n = words.len()
177
+ if n <= 1 {
178
+ return (title,)
179
+ }
180
+ if n <= k {
181
+ return words
182
+ }
183
+ let single-count = lines => lines.map(l => if l.split(" ").len() <= 1 { 1 } else { 0 }).sum()
184
+ let candidates = ()
185
+ if k == 2 {
186
+ for c in range(1, n) {
187
+ let line1 = words.slice(0, c).join(" ")
188
+ let line2 = words.slice(c, n).join(" ")
189
+ let mx = calc.max(line1.len(), line2.len())
190
+ candidates = candidates + (
191
+ (mx + 100 * single-count((line1, line2)), (line1, line2)),
192
+ )
193
+ }
194
+ } else if k == 3 {
195
+ for c1 in range(1, n - 1) {
196
+ for c2 in range(c1 + 1, n) {
197
+ let line1 = words.slice(0, c1).join(" ")
198
+ let line2 = words.slice(c1, c2).join(" ")
199
+ let line3 = words.slice(c2, n).join(" ")
200
+ let mx = calc.max(line1.len(), line2.len(), line3.len())
201
+ candidates = candidates + (
202
+ (mx + 100 * single-count((line1, line2, line3)), (line1, line2, line3)),
203
+ )
204
+ }
205
+ }
206
+ }
207
+ let best = candidates.at(0)
208
+ for cand in candidates {
209
+ if cand.at(0) < best.at(0) {
210
+ best = cand
211
+ }
212
+ }
213
+ best.at(1)
214
+ }
215
+
216
+ #let title-lines = layout(size => {
217
+ let t = upper("$title$".replace("\n", " ").replace("\r", " "))
218
+ let lines = if measure(text(t, size: 14pt, weight: "bold")).width <= size.width {
219
+ (t,)
220
+ } else {
221
+ let two = balance-split(t, 2)
222
+ let w-two = two.map(l => measure(text(l, size: 14pt, weight: "bold")).width)
223
+ .fold(0pt, calc.max)
224
+ let orphan = two.any(l => l.split(" ").len() <= 1)
225
+ if (not orphan) and w-two <= size.width {
226
+ two
227
+ } else {
228
+ balance-split(t, 3)
229
+ }
230
+ }
231
+ let out = ()
232
+ for i in range(lines.len()) {
233
+ if i > 0 {
234
+ out.push(linebreak())
235
+ }
236
+ out.push(lines.at(i))
237
+ }
238
+ out.join()
239
+ })
240
+
241
+ #set table(stroke: 0.5pt + luma(140), inset: 4pt)
242
+ #show table.header: set text(weight: "bold")
243
+ #set figure.caption(position: bottom)
244
+ #show raw.where(block: true): set text(font: "DejaVu Sans Mono", size: 9pt)
245
+
246
+ #v(1cm)
247
+ #align(center)[
248
+ #text(size: 14pt, weight: "bold")[#title-lines]
249
+ ]
250
+ $if(subtitle)$
251
+ #v(0.3cm)
252
+ #align(center)[
253
+ #text(size: 14pt, weight: "bold")[#upper("$subtitle$".replace("\n", " "))]
254
+ ]
255
+ $endif$
256
+ $if(course)$
257
+ #v(0.8cm)
258
+ #align(center)[
259
+ #text(size: 12pt, weight: "bold")[$course$]
260
+ ]
261
+ $endif$
262
+ $if(lecturer)$
263
+ #let hide-lecturer = ("$cover_hide_lecturer$" == "true" or "$cover_show_lecturer$" == "false")
264
+ #if not hide-lecturer [
265
+ #v(0.4cm)
266
+ #align(center)[
267
+ #text(size: 11pt)[$if(lecturer_label)$$lecturer_label$$else$Dosen Pengampu:$endif$]
268
+ #text(size: 12pt, weight: "bold")[$lecturer$]
269
+ ]
270
+ ]
271
+ $endif$
272
+
273
+ #v(1fr)
274
+ #align(center)[
275
+ #image("logo.jpg", width: $if(cover_logo_width)$$cover_logo_width$$else$4cm$endif$)
276
+ ]
277
+ #v(1fr)
278
+
279
+ #align(center)[
280
+ #text(size: 12pt)[Disusun oleh:]
281
+ ]
282
+ $for(author)$
283
+ #v(0.3cm)
284
+ #align(center)[
285
+ #text(size: 12pt, weight: "bold")[$author.name$] \
286
+ #text(size: 11pt)[$author.nim$]
287
+ ]
288
+ $endfor$
289
+
290
+ #v(1fr)
291
+ #align(center)[
292
+ #text(size: 14pt, weight: "bold")[#upper("$faculty$".replace("\n", " "))]
293
+ #linebreak()
294
+ #text(size: 14pt, weight: "bold")[#upper("$institution$".replace("\n", " "))]
295
+ #linebreak()
296
+ #text(size: 14pt, weight: "bold")[#upper("$year$".replace("\n", " "))]
297
+ ]
298
+ #v(1cm)
299
+
300
+ #pagebreak()
301
+ #set page(numbering: "i")
302
+ #counter(page).update(1)
303
+
304
+ $if(approval)$
305
+ #align(center)[
306
+ #text(size: 14pt, weight: "bold")[LEMBAR PENGESAHAN]
307
+ #v(0.8cm)
308
+ #text(size: 12pt, weight: "bold")[#title-lines]
309
+ ]
310
+ #v(0.5cm)
311
+ #align(center)[
312
+ #text(size: 11pt)[Disusun oleh:] \
313
+ $for(author)$
314
+ #text(size: 11pt, weight: "bold")[$author.name$] #text(size: 11pt)[($author.nim$)] \
315
+ $endfor$
316
+ ]
317
+ #v(0.5cm)
318
+ #align(center)[
319
+ #text(size: 11pt)[Telah diperiksa dan disetujui untuk diujikan pada:] \
320
+ #text(size: 11pt)[$if(approval.city)$$approval.city$, $endif$$if(approval.date)$$approval.date$$else$$date$$endif$]
321
+ ]
322
+ #v(1cm)
323
+ #grid(
324
+ columns: (1fr, 1fr),
325
+ gutter: 20pt,
326
+ $for(approval.supervisors)$
327
+ align(center)[
328
+ #text(size: 10.5pt)[$it.role$] \
329
+ #v(2cm)
330
+ #text(size: 10.5pt, weight: "bold")[$it.name$] \
331
+ $if(it.nip)$#text(size: 9pt)[NIP. $it.nip$]$endif$
332
+ ],
333
+ $endfor$
334
+ )
335
+ $if(approval.dean)$
336
+ #v(1cm)
337
+ #align(center)[
338
+ #text(size: 10.5pt)[Mengetahui,] \
339
+ #text(size: 10.5pt)[$approval.dean.role$] \
340
+ #v(2cm)
341
+ #text(size: 10.5pt, weight: "bold")[$approval.dean.name$] \
342
+ $if(approval.dean.nip)$#text(size: 9pt)[NIP. $approval.dean.nip$]$endif$
343
+ ]
344
+ $endif$
345
+ #pagebreak()
346
+ $endif$
347
+
348
+ $if(abstract_id)$
349
+ #align(center)[
350
+ #text(size: 14pt, weight: "bold")[ABSTRAK]
351
+ ]
352
+ #v(0.5cm)
353
+ #align(center)[
354
+ #text(size: 11pt, weight: "bold")[#title-lines]
355
+ ]
356
+ #v(0.5cm)
357
+ #set par(justify: true, leading: 0.65em, first-line-indent: 1cm)
358
+ #text(size: 11pt)[
359
+ $abstract_id$
360
+ ]
361
+ $if(keywords_id)$
362
+ #v(0.5cm)
363
+ #text(size: 10.5pt)[
364
+ #set par(first-line-indent: 0cm)
365
+ #strong[Kata Kunci:] #emph[$for(keywords_id)$$keywords_id$$sep$, $endfor$]
366
+ ]
367
+ $endif$
368
+ #pagebreak()
369
+ $endif$
370
+
371
+ $if(abstract_en)$
372
+ #align(center)[
373
+ #text(size: 14pt, weight: "bold")[ABSTRACT]
374
+ ]
375
+ #v(0.5cm)
376
+ #align(center)[
377
+ #text(size: 11pt, weight: "bold", style: "italic")[#title-lines]
378
+ ]
379
+ #v(0.5cm)
380
+ #set par(justify: true, leading: 0.65em, first-line-indent: 1cm)
381
+ #text(size: 11pt, style: "italic")[
382
+ $abstract_en$
383
+ ]
384
+ $if(keywords_en)$
385
+ #v(0.5cm)
386
+ #text(size: 10.5pt)[
387
+ #set par(first-line-indent: 0cm)
388
+ #strong[Keywords:] #emph[$for(keywords_en)$$keywords_en$$sep$, $endfor$]
389
+ ]
390
+ $endif$
391
+ #pagebreak()
392
+ $endif$
393
+
394
+ $body$