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
@@ -0,0 +1,552 @@
1
+ # ==============================================================================
2
+ # Laporan Generator CLI Helper for Windows PowerShell (.\laporan.ps1)
3
+ # ==============================================================================
4
+ param (
5
+ [Parameter(Position=0)]
6
+ [string]$Command = "help",
7
+ [Parameter(Position=1)]
8
+ [string]$SubCommand = "",
9
+ [Parameter(Position=2)]
10
+ [string]$Arg1 = "",
11
+ [Parameter(Position=3)]
12
+ [string]$Arg2 = ""
13
+ )
14
+
15
+ $ErrorActionPreference = "Stop"
16
+ $env:PYTHONUTF8 = "1"
17
+
18
+ # Pastikan folder localBin ada di PATH sesi saat ini jika ada
19
+ $localBin = Join-Path $env:LOCALAPPDATA "laporan-generator\bin"
20
+ if ((Test-Path $localBin) -and ($env:Path -notlike "*$localBin*")) {
21
+ $env:Path = "$localBin;$env:Path"
22
+ }
23
+
24
+ function Get-PythonCommand {
25
+ foreach ($cmd in @("python", "python3")) {
26
+ $c = Get-Command $cmd -ErrorAction SilentlyContinue
27
+ if ($c) {
28
+ if ($c.Source -match "WindowsApps\\python") {
29
+ continue
30
+ }
31
+ return $c.Source
32
+ }
33
+ }
34
+ $fallback = Get-Command "python" -ErrorAction SilentlyContinue
35
+ if ($fallback) { return $fallback.Source }
36
+ return ""
37
+ }
38
+
39
+ function Show-Banner {
40
+ Write-Host " ========================================================" -ForegroundColor Cyan
41
+ Write-Host " LAPORAN GENERATOR CLI v2.6.0 " -ForegroundColor Cyan
42
+ Write-Host " Otomatisasi Dokumen Akademik (Typst + DOCX Engine) " -ForegroundColor Cyan
43
+ Write-Host " ========================================================" -ForegroundColor Cyan
44
+ Write-Host ""
45
+ }
46
+
47
+ function Show-Help {
48
+ Show-Banner
49
+ Write-Host "Penggunaan: .\laporan.ps1 <perintah>" -ForegroundColor White
50
+ Write-Host ""
51
+ Write-Host "Perintah yang Tersedia:" -ForegroundColor White
52
+ Write-Host " build Kompilasi PDF dan DOCX sekaligus" -ForegroundColor Green
53
+ Write-Host " pdf Kompilasi dokumen PDF (via Typst)" -ForegroundColor Green
54
+ Write-Host " docx Kompilasi dokumen Microsoft Word (.docx)" -ForegroundColor Green
55
+ Write-Host " init Wizard interaktif untuk konfigurasi awal metadata" -ForegroundColor Green
56
+ Write-Host " preset Kelola preset format kampus (list/show/apply/validate/diff/scan)" -ForegroundColor Green
57
+ Write-Host " stats Analisis statistik kata, halaman, gambar, dan durasi baca" -ForegroundColor Green
58
+ Write-Host " doctor Audit kesehatan proyek (broken images, sitasi hilang, dll.)" -ForegroundColor Green
59
+ Write-Host " bundle Kemas seluruh laporan (PDF, DOCX, MD) menjadi arsip zip" -ForegroundColor Green
60
+ Write-Host " setup Pasang dependensi sistem otomatis Windows (Typst, Pandoc, Magick)" -ForegroundColor Green
61
+ Write-Host " sync-skills Sinkronkan skill AI agent ke Antigravity, Claude, Gemini, Grok" -ForegroundColor Green
62
+ Write-Host " check Audit dependensi sistem dan struktur proyek" -ForegroundColor Green
63
+ Write-Host " test Jalankan suite pengujian otomatis" -ForegroundColor Green
64
+ Write-Host " view Buka dokumen Laporan.pdf di PDF viewer" -ForegroundColor Green
65
+ Write-Host " watch Pantau perubahan berkas dan auto-rebuild" -ForegroundColor Green
66
+ Write-Host " clean Bersihkan berkas output dan direktori sementara" -ForegroundColor Green
67
+ Write-Host " help Tampilkan panduan bantuan ini" -ForegroundColor Green
68
+ Write-Host ""
69
+ Write-Host "Contoh:" -ForegroundColor Yellow
70
+ Write-Host " .\laporan.ps1 build"
71
+ Write-Host " .\laporan.ps1 stats"
72
+ Write-Host " .\laporan.ps1 preset list"
73
+ Write-Host " .\laporan.ps1 preset apply itb-ta"
74
+ }
75
+
76
+ function Cmd-Check {
77
+ Show-Banner
78
+ Write-Host "[1/2] Memeriksa Dependensi Sistem..." -ForegroundColor Blue
79
+
80
+ $pyPath = Get-PythonCommand
81
+ $pyFound = if ($pyPath) { Get-Command $pyPath -ErrorAction SilentlyContinue } else { $null }
82
+
83
+ $imFound = Get-Command "magick" -ErrorAction SilentlyContinue
84
+ if (-not $imFound -and -not ($env:OS -match "Windows")) {
85
+ $imFound = Get-Command "convert" -ErrorAction SilentlyContinue
86
+ }
87
+
88
+ $deps = @(
89
+ @{ Name="Pandoc"; Cmd="pandoc"; Found=(Get-Command "pandoc" -ErrorAction SilentlyContinue); Req=$true },
90
+ @{ Name="Typst"; Cmd="typst"; Found=(Get-Command "typst" -ErrorAction SilentlyContinue); Req=$true },
91
+ @{ Name="ImageMagick"; Cmd="magick/convert"; Found=$imFound; Req=$false },
92
+ @{ Name="Python 3"; Cmd="python/python3"; Found=$pyFound; Req=$true },
93
+ @{ Name="LibreOffice"; Cmd="soffice"; Found=(Get-Command "soffice" -ErrorAction SilentlyContinue); Req=$false }
94
+ )
95
+
96
+ $allOk = $true
97
+ foreach ($d in $deps) {
98
+ if ($d.Found) {
99
+ Write-Host " [OK] $($d.Name) ($($d.Cmd)) terpasang: $($d.Found.Source)" -ForegroundColor Green
100
+ } else {
101
+ if ($d.Req) {
102
+ Write-Host " [FAIL] $($d.Name) ($($d.Cmd)) TIDAK DITEMUKAN (Wajib)" -ForegroundColor Red
103
+ $allOk = $false
104
+ } else {
105
+ Write-Host " [INFO] $($d.Name) ($($d.Cmd)) tidak ditemukan (Opsional)" -ForegroundColor Yellow
106
+ }
107
+ }
108
+ }
109
+
110
+ Write-Host ""
111
+ Write-Host "[2/2] Memeriksa Berkas Proyek..." -ForegroundColor Blue
112
+ $files = @("metadata.yml", "cover.md", "template.typ", "reference.docx", "references.bib", "docx.lua")
113
+ foreach ($f in $files) {
114
+ if (Test-Path $f) {
115
+ Write-Host " [OK] Berkas $f ditemukan" -ForegroundColor Green
116
+ } else {
117
+ Write-Host " [FAIL] Berkas $f tidak ditemukan" -ForegroundColor Red
118
+ $allOk = $false
119
+ }
120
+ }
121
+
122
+ $dirs = @("presets", "chapters")
123
+ foreach ($d in $dirs) {
124
+ if (Test-Path $d) {
125
+ Write-Host " [OK] Direktori $d ditemukan" -ForegroundColor Green
126
+ } else {
127
+ Write-Host " [FAIL] Direktori $d tidak ditemukan" -ForegroundColor Red
128
+ $allOk = $false
129
+ }
130
+ }
131
+
132
+ Write-Host ""
133
+ if ($allOk) {
134
+ Write-Host "Semua dependensi dan berkas proyek lengkap dan siap digunakan!" -ForegroundColor Green
135
+ } else {
136
+ Write-Host "Ada beberapa komponen yang kurang. Gunakan Docker jika ingin bebas instalasi lokal." -ForegroundColor Yellow
137
+ }
138
+ }
139
+
140
+ function Cmd-Build-PDF {
141
+ Show-Banner
142
+ Write-Host "Membangun Dokumen PDF (Typst Engine)..." -ForegroundColor Blue
143
+
144
+ $inputFiles = @("cover.md") + (Get-ChildItem -Path "chapters" -Filter "bab*.md" | Sort-Object Name | ForEach-Object { $_.FullName })
145
+ $presetOpt = ""
146
+ if (Test-Path "metadata.yml") {
147
+ $content = Get-Content "metadata.yml" -Raw
148
+ if ($content -match "(?:preset|margin_preset)\s*:\s*[`"']?([a-zA-Z0-9_-]+)[`"']?") {
149
+ $presetName = $matches[1]
150
+ if (Test-Path "presets\$presetName.yml") {
151
+ $presetOpt = "--metadata-file=presets\$presetName.yml"
152
+ }
153
+ }
154
+ }
155
+
156
+ $pandocArgs = @()
157
+ $pandocArgs += $inputFiles
158
+ $pandocArgs += "--template=template.typ"
159
+ if ($presetOpt) { $pandocArgs += $presetOpt }
160
+ $pandocArgs += "--metadata-file=metadata.yml"
161
+ $pandocArgs += "--citeproc"
162
+ $pandocArgs += "--bibliography=references.bib"
163
+ $pandocArgs += "--csl=apa.csl"
164
+ $pandocArgs += "--metadata=reference-section-title=DAFTAR PUSTAKA"
165
+ $pandocArgs += "--top-level-division=chapter"
166
+ $pandocArgs += "--pdf-engine=typst"
167
+ $pandocArgs += "--syntax-highlighting=none"
168
+ $pandocArgs += @("-o", "Laporan.pdf")
169
+
170
+ & pandoc $pandocArgs
171
+ if ($LASTEXITCODE -eq 0) {
172
+ Write-Host ""
173
+ Write-Host "=== PDF BERHASIL DIBUAT ===" -ForegroundColor Green
174
+ Write-Host "Lokasi: $(Get-Location)\Laporan.pdf" -ForegroundColor Cyan
175
+ } else {
176
+ Write-Host "[ERROR] Kompilasi PDF gagal." -ForegroundColor Red
177
+ }
178
+ }
179
+
180
+ function Cmd-Build-DOCX {
181
+ Show-Banner
182
+ Write-Host "Membangun Dokumen Microsoft Word (DOCX Multi-Pass)..." -ForegroundColor Blue
183
+
184
+ if (-not (Test-Path "chapters")) {
185
+ Write-Host "[ERROR] Direktori chapters/ tidak ditemukan." -ForegroundColor Red
186
+ return
187
+ }
188
+
189
+ $pyCmd = Get-PythonCommand
190
+ if (-not $pyCmd) {
191
+ Write-Host "[ERROR] Python 3 dibutuhkan untuk memproses DOCX." -ForegroundColor Red
192
+ return
193
+ }
194
+
195
+ $inputFiles = @("cover.md") + (Get-ChildItem -Path "chapters" -Filter "bab*.md" | Sort-Object Name | ForEach-Object { $_.FullName })
196
+ $presetOpt = ""
197
+ if (Test-Path "metadata.yml") {
198
+ $content = Get-Content "metadata.yml" -Raw
199
+ if ($content -match "(?:preset|margin_preset)\s*:\s*[`"']?([a-zA-Z0-9_-]+)[`"']?") {
200
+ $presetName = $matches[1]
201
+ if (Test-Path "presets\$presetName.yml") {
202
+ $presetOpt = "--metadata-file=presets\$presetName.yml"
203
+ }
204
+ }
205
+ }
206
+
207
+ $tmpDocx = [System.IO.Path]::GetTempFileName() + ".docx"
208
+ $sectDocx = [System.IO.Path]::GetTempFileName() + ".docx"
209
+
210
+ try {
211
+ $pandocArgs = @()
212
+ $pandocArgs += $inputFiles
213
+ if ($presetOpt) { $pandocArgs += $presetOpt }
214
+ $pandocArgs += "--metadata-file=metadata.yml"
215
+ $pandocArgs += "--citeproc"
216
+ $pandocArgs += "--bibliography=references.bib"
217
+ $pandocArgs += "--csl=apa.csl"
218
+ $pandocArgs += "--metadata=reference-section-title=DAFTAR PUSTAKA"
219
+ $pandocArgs += "--top-level-division=chapter"
220
+ $pandocArgs += "--reference-doc=reference.docx"
221
+ $pandocArgs += "--lua-filter=docx.lua"
222
+ $pandocArgs += @("-o", $tmpDocx)
223
+
224
+ & pandoc $pandocArgs
225
+ if ($LASTEXITCODE -ne 0) {
226
+ Write-Host "[ERROR] Kompilasi Pandoc ke DOCX gagal." -ForegroundColor Red
227
+ return
228
+ }
229
+
230
+ & $pyCmd scripts/finalize-docx.py $tmpDocx $sectDocx
231
+ & $pyCmd scripts/docx-pagenum.py $sectDocx Laporan.docx
232
+
233
+ if (Test-Path "Laporan.docx") {
234
+ Write-Host ""
235
+ Write-Host "=== DOCX BERHASIL DIBUAT ===" -ForegroundColor Green
236
+ Write-Host "Lokasi: $(Get-Location)\Laporan.docx" -ForegroundColor Cyan
237
+ }
238
+ } finally {
239
+ Remove-Item -Force -ErrorAction SilentlyContinue $tmpDocx, $sectDocx
240
+ }
241
+ }
242
+
243
+ function Cmd-Build {
244
+ Show-Banner
245
+ Write-Host "[1/2] Membangun Dokumen PDF (Typst Engine)..." -ForegroundColor Blue
246
+ Cmd-Build-PDF
247
+ Write-Host ""
248
+ Write-Host "[2/2] Membangun Dokumen Microsoft Word (DOCX Multi-Pass)..." -ForegroundColor Blue
249
+ Cmd-Build-DOCX
250
+ Write-Host ""
251
+ Write-Host "Dokumen PDF dan DOCX berhasil diproses!" -ForegroundColor Green
252
+ }
253
+
254
+ function Escape-Yaml {
255
+ param ([string]$Val)
256
+ if (-not $Val) { return "" }
257
+ $Val = $Val -replace "\\", "\\\\"
258
+ $Val = $Val -replace '"', '\"'
259
+ $Val = $Val -replace "`r", ""
260
+ $Val = $Val -replace "`n", " "
261
+ return $Val
262
+ }
263
+
264
+ function Cmd-Init {
265
+ Show-Banner
266
+ Write-Host "Wizard Konfigurasi Laporan Akademik (Windows PowerShell)" -ForegroundColor Cyan
267
+ Write-Host "Isi data di bawah ini (tekan Enter untuk memakai nilai default):"
268
+ Write-Host ""
269
+
270
+ $in_title = Read-Host "Judul Laporan [LAPORAN PROYEK AKADEMIK]"
271
+ if (-not $in_title) { $in_title = "LAPORAN PROYEK AKADEMIK" }
272
+
273
+ $in_subtitle = Read-Host "Subjudul [DOKUMENTASI DAN ANALISIS IMPLEMENTASI]"
274
+ if (-not $in_subtitle) { $in_subtitle = "DOKUMENTASI DAN ANALISIS IMPLEMENTASI" }
275
+
276
+ $in_course = Read-Host "Mata Kuliah [Proyek Perangkat Lunak]"
277
+ if (-not $in_course) { $in_course = "Proyek Perangkat Lunak" }
278
+
279
+ $in_lecturer = Read-Host "Dosen Pengampu [Dr. Nama Dosen, M.Kom.]"
280
+ if (-not $in_lecturer) { $in_lecturer = "Dr. Nama Dosen, M.Kom." }
281
+
282
+ $in_author = Read-Host "Nama Penulis 1 [Nama Mahasiswa]"
283
+ if (-not $in_author) { $in_author = "Nama Mahasiswa" }
284
+
285
+ $in_nim = Read-Host "NIM Penulis 1 [12345678]"
286
+ if (-not $in_nim) { $in_nim = "12345678" }
287
+
288
+ $in_institution = Read-Host "Institusi/Universitas [UNIVERSITAS TEKNOLOGI]"
289
+ if (-not $in_institution) { $in_institution = "UNIVERSITAS TEKNOLOGI" }
290
+
291
+ $in_faculty = Read-Host "Fakultas [FAKULTAS ILMU KOMPUTER]"
292
+ if (-not $in_faculty) { $in_faculty = "FAKULTAS ILMU KOMPUTER" }
293
+
294
+ $in_year = Read-Host "Tahun Akademik [2026/2027]"
295
+ if (-not $in_year) { $in_year = "2026/2027" }
296
+
297
+ Write-Host ""
298
+ Write-Host "Pilihan Preset Format Kampus:" -ForegroundColor Blue
299
+ Write-Host " standard / skripsi-4433 / ui-skripsi / itb-ta / ugm-skripsi / its-skripsi / unpad-skripsi"
300
+ $in_preset = Read-Host "Preset Format [standard]"
301
+ if (-not $in_preset) { $in_preset = "standard" }
302
+
303
+ $curDate = (Get-Date -Format "MMMM yyyy")
304
+
305
+ $escTitle = Escape-Yaml $in_title
306
+ $escSubtitle = Escape-Yaml $in_subtitle
307
+ $escCourse = Escape-Yaml $in_course
308
+ $escLecturer = Escape-Yaml $in_lecturer
309
+ $escAuthor = Escape-Yaml $in_author
310
+ $escNim = Escape-Yaml $in_nim
311
+ $escInstitution = Escape-Yaml $in_institution
312
+ $escFaculty = Escape-Yaml $in_faculty
313
+ $escYear = Escape-Yaml $in_year
314
+ $escPreset = Escape-Yaml $in_preset
315
+
316
+ $yamlContent = @"
317
+ title: "$escTitle"
318
+ subtitle: "$escSubtitle"
319
+ course: "$escCourse"
320
+ lecturer: "$escLecturer"
321
+ author:
322
+ - name: "$escAuthor"
323
+ nim: "$escNim"
324
+ institution: "$escInstitution"
325
+ faculty: "$escFaculty"
326
+ year: "$escYear"
327
+ date: "$curDate"
328
+ preset: "$escPreset"
329
+ "@
330
+
331
+ Set-Content -Path "metadata.yml" -Value $yamlContent
332
+ Write-Host ""
333
+ Write-Host "metadata.yml berhasil diperbarui!" -ForegroundColor Green
334
+ Write-Host "Jalankan '.\laporan.ps1 build' untuk mulai menghasilkan laporan." -ForegroundColor Cyan
335
+ }
336
+
337
+ function Cmd-Test {
338
+ Show-Banner
339
+ Write-Host "Menjalankan Test Suite..." -ForegroundColor Blue
340
+ $gitBash = "C:\Program Files\Git\bin\bash.exe"
341
+ $bashCmd = if (Test-Path $gitBash) { $gitBash } elseif ((Get-Command "bash" -ErrorAction SilentlyContinue) -and (Get-Command "bash").Source -notmatch "system32\\bash\.exe") { "bash" } else { "" }
342
+ if ($bashCmd) {
343
+ & $bashCmd test.sh
344
+ } else {
345
+ $pyCmd = Get-PythonCommand
346
+ if ($pyCmd) {
347
+ Write-Host "Menjalankan validasi skema preset..." -ForegroundColor Blue
348
+ & $pyCmd scripts/validate-preset.py --all
349
+ } else {
350
+ Write-Host "Test suite membutuhkan bash atau python3." -ForegroundColor Yellow
351
+ }
352
+ }
353
+ }
354
+
355
+ function Cmd-Preset {
356
+ param ($Sub, $P1, $P2)
357
+ $pyCmd = Get-PythonCommand
358
+
359
+ switch ($Sub) {
360
+ "list" {
361
+ Show-Banner
362
+ Write-Host "Daftar Preset Format Kampus Tersedia:" -ForegroundColor Blue
363
+ Write-Host ""
364
+ Get-ChildItem -Path "presets" -Filter "*.yml" | ForEach-Object {
365
+ $presetId = $_.BaseName
366
+ $name = (Select-String -Path $_.FullName -Pattern "^\s*name:\s*`"?(.*?)`"?\s*$" | Select-Object -First 1).Matches.Groups[1].Value
367
+ $desc = (Select-String -Path $_.FullName -Pattern "^\s*description:\s*`"?(.*?)`"?\s*$" | Select-Object -First 1).Matches.Groups[1].Value
368
+ Write-Host " * $presetId - $name" -ForegroundColor Green
369
+ if ($desc) { Write-Host " $desc" -ForegroundColor Gray }
370
+ Write-Host ""
371
+ }
372
+ }
373
+ "show" {
374
+ if (-not $P1) { Write-Host "Error: Sebutkan ID preset. Contoh: .\laporan.ps1 preset show itb-ta" -ForegroundColor Red; return }
375
+ $file = "presets\$P1.yml"
376
+ if (Test-Path $file) {
377
+ Show-Banner
378
+ Write-Host "Konfigurasi Preset: $P1" -ForegroundColor Cyan
379
+ Write-Host "--------------------------------------------------------"
380
+ Get-Content $file
381
+ Write-Host "--------------------------------------------------------"
382
+ } else {
383
+ Write-Host "Preset '$P1' tidak ditemukan." -ForegroundColor Red
384
+ }
385
+ }
386
+ "apply" {
387
+ if (-not $P1) { Write-Host "Error: Sebutkan ID preset. Contoh: .\laporan.ps1 preset apply itb-ta" -ForegroundColor Red; return }
388
+ $file = "presets\$P1.yml"
389
+ if (-not (Test-Path $file)) { Write-Host "Preset '$P1' tidak ditemukan." -ForegroundColor Red; return }
390
+ if (-not (Test-Path "metadata.yml")) { Write-Host "metadata.yml tidak ditemukan." -ForegroundColor Red; return }
391
+
392
+ $content = Get-Content "metadata.yml" -Raw
393
+ if ($content -match "preset\s*:") {
394
+ $content = $content -replace "preset\s*:.*", "preset: `"$P1`""
395
+ } else {
396
+ $content += "`npreset: `"$P1`""
397
+ }
398
+ Set-Content -Path "metadata.yml" -Value $content -NoNewline
399
+ Write-Host "[OK] Preset '$P1' berhasil diterapkan ke metadata.yml!" -ForegroundColor Green
400
+ }
401
+ "validate" {
402
+ if (-not $pyCmd) { Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red; return }
403
+ if ($P1) {
404
+ $tgt = $P1
405
+ if (Test-Path "presets\$tgt.yml") { $tgt = "presets\$tgt.yml" }
406
+ & $pyCmd scripts/validate-preset.py $tgt
407
+ } else {
408
+ & $pyCmd scripts/validate-preset.py --all
409
+ }
410
+ }
411
+ "diff" {
412
+ if (-not $P1) { Write-Host "Error: Sebutkan setidaknya 1 preset untuk dibandingkan." -ForegroundColor Red; return }
413
+ $f1 = "presets\$P1.yml"
414
+ if (-not (Test-Path $f1)) { Write-Host "Preset '$P1' tidak ditemukan." -ForegroundColor Red; return }
415
+ if ($P2) {
416
+ $f2 = "presets\$P2.yml"
417
+ if (-not (Test-Path $f2)) { Write-Host "Preset '$P2' tidak ditemukan." -ForegroundColor Red; return }
418
+ Compare-Object (Get-Content $f1) (Get-Content $f2)
419
+ } else {
420
+ $curr = "standard"
421
+ if (Test-Path "metadata.yml") {
422
+ $content = Get-Content "metadata.yml" -Raw
423
+ if ($content -match "(?:preset|margin_preset)\s*:\s*[`"']?([a-zA-Z0-9_-]+)[`"']?") {
424
+ $curr = $matches[1]
425
+ }
426
+ }
427
+ $f2 = "presets\$curr.yml"
428
+ Compare-Object (Get-Content $f2) (Get-Content $f1)
429
+ }
430
+ }
431
+ "scan" {
432
+ if (-not $pyCmd) { Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red; return }
433
+ if (-not $P1) { Write-Host "Error: Masukkan path file PDF pedoman kampus." -ForegroundColor Red; return }
434
+ & $pyCmd scripts/scan-preset.py $P1 $P2
435
+ }
436
+ default {
437
+ Write-Host "Gunakan: .\laporan.ps1 preset [list | show <id> | apply <id> | validate | diff <id> | scan <file>]" -ForegroundColor Yellow
438
+ }
439
+ }
440
+ }
441
+
442
+ function Cmd-Clean {
443
+ Remove-Item -Force -ErrorAction SilentlyContinue Laporan.pdf, Laporan.docx, Laporan.html
444
+ Remove-Item -Recurse -Force -ErrorAction SilentlyContinue tmp, dist
445
+ Write-Host "[OK] Berkas output berhasil dibersihkan." -ForegroundColor Green
446
+ }
447
+
448
+ function Cmd-Stats {
449
+ $pyCmd = Get-PythonCommand
450
+ if ($pyCmd) {
451
+ & $pyCmd scripts/report-stats.py
452
+ } else {
453
+ Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red
454
+ }
455
+ }
456
+
457
+ function Cmd-Doctor {
458
+ $pyCmd = Get-PythonCommand
459
+ if ($pyCmd) {
460
+ & $pyCmd scripts/report-doctor.py
461
+ } else {
462
+ Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red
463
+ }
464
+ }
465
+
466
+ function Cmd-Bundle {
467
+ $pyCmd = Get-PythonCommand
468
+ if ($pyCmd) {
469
+ & $pyCmd scripts/bundle.py
470
+ } else {
471
+ Write-Host "Error: Python 3 tidak ditemukan." -ForegroundColor Red
472
+ }
473
+ }
474
+
475
+ function Cmd-View {
476
+ if (Test-Path "Laporan.pdf") {
477
+ Start-Process "Laporan.pdf"
478
+ } else {
479
+ Write-Host "Laporan.pdf belum dibuat. Jalankan '.\laporan.ps1 build' terlebih dahulu." -ForegroundColor Red
480
+ }
481
+ }
482
+
483
+ function Cmd-Watch {
484
+ Show-Banner
485
+ Write-Host "Memantau perubahan berkas dan auto-rebuild... (Tekan Ctrl+C untuk berhenti)" -ForegroundColor Cyan
486
+ $scriptPath = $MyInvocation.MyCommand.Definition
487
+ if (-not $scriptPath) { $scriptPath = $PSCommandPath }
488
+ if (-not $scriptPath) { $scriptPath = ".\laporan.ps1" }
489
+
490
+ $watcher = New-Object System.IO.FileSystemWatcher
491
+ $watcher.Path = (Get-Location).Path
492
+ $watcher.IncludeSubdirectories = $true
493
+ $watcher.EnableRaisingEvents = $true
494
+ $watcher.Filter = "*.*"
495
+
496
+ $action = {
497
+ $path = $Event.SourceEventArgs.FullPath
498
+ if ($path -notmatch '(\.pdf|\.docx|tmp|dist|\.git)' -and ($path -match '(\.md|\.typ|\.yml|\.bib)')) {
499
+ Write-Host "[Perubahan Terdeteksi] $path -> Membangun ulang..." -ForegroundColor Yellow
500
+ if (Get-Command Cmd-Build -ErrorAction SilentlyContinue) {
501
+ Cmd-Build
502
+ } elseif ($using:scriptPath -and (Test-Path $using:scriptPath)) {
503
+ & powershell -ExecutionPolicy Bypass -File $using:scriptPath build
504
+ } else {
505
+ powershell -ExecutionPolicy Bypass -File ".\laporan.ps1" build
506
+ }
507
+ }
508
+ }
509
+
510
+ Register-ObjectEvent $watcher "Changed" -Action $action | Out-Null
511
+ Register-ObjectEvent $watcher "Created" -Action $action | Out-Null
512
+
513
+ try {
514
+ while ($true) { Start-Sleep -Seconds 1 }
515
+ } finally {
516
+ Get-EventSubscriber | Unregister-Event
517
+ $watcher.Dispose()
518
+ }
519
+ }
520
+
521
+ switch ($Command.ToLower()) {
522
+ "build" { Cmd-Build }
523
+ "pdf" { Cmd-Build-PDF }
524
+ "docx" { Cmd-Build-DOCX }
525
+ "init" { Cmd-Init }
526
+ "stats" { Cmd-Stats }
527
+ "doctor" { Cmd-Doctor }
528
+ "bundle" { Cmd-Bundle }
529
+ "setup" { & powershell -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot "scripts\setup-deps.ps1") }
530
+ "sync-skills" {
531
+ if (Get-Command "node" -ErrorAction SilentlyContinue) {
532
+ node (Join-Path $PSScriptRoot "bin\laporan-generator.js") sync-hosts
533
+ } else {
534
+ Write-Host "Node.js diperlukan untuk sinkronisasi multi-host AI agent." -ForegroundColor Yellow
535
+ }
536
+ }
537
+ "sync-hosts" {
538
+ if (Get-Command "node" -ErrorAction SilentlyContinue) {
539
+ node (Join-Path $PSScriptRoot "bin\laporan-generator.js") sync-hosts
540
+ } else {
541
+ Write-Host "Node.js diperlukan untuk sinkronisasi multi-host AI agent." -ForegroundColor Yellow
542
+ }
543
+ }
544
+ "check" { Cmd-Check }
545
+ "clean" { Cmd-Clean }
546
+ "view" { Cmd-View }
547
+ "watch" { Cmd-Watch }
548
+ "test" { Cmd-Test }
549
+ "preset" { Cmd-Preset $SubCommand $Arg1 $Arg2 }
550
+ "help" { Show-Help }
551
+ default { Show-Help }
552
+ }
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: "Otomatisasi Pembuatan Dokumen Laporan Akademik Menggunakan Pandoc, Typst, dan Markdown"
3
+ subtitle: "Laporan Dokumentasi Pipeline dan Arsitektur Multi-Engine"
4
+ author:
5
+ - name: "Nama Mahasiswa 1"
6
+ nim: "101234567"
7
+ - name: "Nama Mahasiswa 2"
8
+ nim: "101234568"
9
+ - name: "Nama Mahasiswa 3"
10
+ nim: "101234569"
11
+ lecturer: "Dr. Nama Dosen Pengampu, M.Kom."
12
+ lecturer_label: "Dosen Pengampu:"
13
+ course: "Proyek Perangkat Lunak"
14
+ institution: "Universitas Example"
15
+ faculty: "Program Studi Informatika"
16
+ year: "2026/2027"
17
+ date: "Agustus 2026"
18
+ abstract_id: |
19
+ Laporan ini membahas perancangan dan implementasi pipeline otomatisasi pembuatan dokumen akademik modern menggunakan Markdown, Pandoc, Typst, Lua Filter, dan multi-pass DOCX engine. Pipeline ini memungkinkan penulisan konten laporan dalam format Markdown yang secara otomatis dikonversi menjadi dokumen PDF berkualitas percetakan berbasis Typst serta dokumen Microsoft Word (.docx) berstruktur formal lengkap dengan penomoran bab, tabel, gambar, dan halaman otomatis yang mematuhi standar karya ilmiah perguruan tinggi di Indonesia.
20
+ keywords_id:
21
+ - Otomatisasi Dokumen
22
+ - Pandoc
23
+ - Typst
24
+ - OpenXML
25
+ - Rekayasa Perangkat Lunak
26
+ abstract_en: |
27
+ This report presents the design and implementation of a modern academic document automation pipeline utilizing Markdown, Pandoc, Typst, Lua Filters, and a multi-pass DOCX engine. This pipeline facilitates authoring scholarly reports in plain Markdown, seamlessly generating both print-quality Typst-based PDF documents and formally structured Microsoft Word (.docx) files. The generated outputs feature automated chapter, table, figure, and dual-pagination numbering compliant with standardized higher education guidelines.
28
+ keywords_en:
29
+ - Document Automation
30
+ - Pandoc
31
+ - Typst
32
+ - OpenXML
33
+ - Software Engineering
34
+ preset: "standard"
35
+ ...
@@ -0,0 +1,27 @@
1
+ # Preset: Institut Teknologi Bandung (ITB)
2
+ preset_id: "itb-ta"
3
+ name: "Institut Teknologi Bandung (ITB)"
4
+ description: "Format Tugas Akhir / Tesis sesuai Pedoman Penulisan Karya Ilmiah ITB (Margin 4-4-3-3, Cover Minimalis)."
5
+
6
+ # Margin halaman (Standar ITB: Kiri 4cm, Atas 4cm, Bawah 3cm, Kanan 3cm)
7
+ margin_top: 4cm
8
+ margin_bottom: 3cm
9
+ margin_left: 4cm
10
+ margin_right: 3cm
11
+
12
+ # Tipografi
13
+ font_family: "Libertinus Serif"
14
+ font_size: 12pt
15
+ line_spacing: 0.75em
16
+ first_line_indent: 1.25cm
17
+
18
+ # Penomoran Heading
19
+ heading_chapter_prefix: "BAB "
20
+ heading_chapter_num_format: "roman"
21
+ heading_sub_dot: true
22
+ heading_subsub_dot: false
23
+
24
+ # Pengaturan Cover (ITB standar sampul depan tidak mencantumkan nama dosen pembimbing)
25
+ cover_show_lecturer: false
26
+ cover_hide_lecturer: true
27
+ cover_logo_width: 4.5cm
@@ -0,0 +1,26 @@
1
+ # Preset: Institut Teknologi Sepuluh Nopember (ITS)
2
+ preset_id: "its-skripsi"
3
+ name: "Institut Teknologi Sepuluh Nopember (ITS)"
4
+ description: "Format Tugas Akhir & Skripsi Institut Teknologi Sepuluh Nopember (Margin 4-4-3-3, Standard Academic)."
5
+
6
+ # Margin halaman (Standar ITS: Kiri 4cm, Atas 4cm, Bawah 3cm, Kanan 3cm)
7
+ margin_top: 4cm
8
+ margin_bottom: 3cm
9
+ margin_left: 4cm
10
+ margin_right: 3cm
11
+
12
+ # Tipografi
13
+ font_family: "Libertinus Serif"
14
+ font_size: 12pt
15
+ line_spacing: 0.75em
16
+ first_line_indent: 1.25cm
17
+
18
+ # Penomoran Heading
19
+ heading_chapter_prefix: "BAB "
20
+ heading_chapter_num_format: "roman"
21
+ heading_sub_dot: true
22
+ heading_subsub_dot: false
23
+
24
+ # Pengaturan Cover
25
+ cover_show_lecturer: true
26
+ cover_logo_width: 4.2cm
@@ -0,0 +1,26 @@
1
+ # Preset: Skripsi Tradisional (Margin 4-4-3-3)
2
+ preset_id: "skripsi-4433"
3
+ name: "Skripsi Tradisional (4-4-3-3)"
4
+ description: "Format skripsi/tesis jilid tebal (hardcover) dengan margin kiri ekstra 4cm untuk area jilid."
5
+
6
+ # Margin halaman
7
+ margin_top: 4cm
8
+ margin_bottom: 3cm
9
+ margin_left: 4cm
10
+ margin_right: 3cm
11
+
12
+ # Tipografi
13
+ font_family: "Libertinus Serif"
14
+ font_size: 12pt
15
+ line_spacing: 0.75em
16
+ first_line_indent: 1.25cm
17
+
18
+ # Penomoran Heading
19
+ heading_chapter_prefix: "BAB "
20
+ heading_chapter_num_format: "roman"
21
+ heading_sub_dot: true
22
+ heading_subsub_dot: false
23
+
24
+ # Pengaturan Cover
25
+ cover_show_lecturer: true
26
+ cover_logo_width: 4cm