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.
- package/.agents/skills/laporan-generator/SKILL.md +132 -0
- package/.agents/skills/laporan-generator/agents/openai.yaml +3 -0
- package/.agents/skills/laporan-generator/references/campus-guide.md +120 -0
- package/.agents/skills/laporan-generator/references/metadata-schema.md +76 -0
- package/.agents/skills/laporan-generator/references/preset-schema.md +79 -0
- package/.agents/skills/laporan-generator/references/syntax-cheatsheet.md +122 -0
- package/.agents/skills/laporan-generator/references/template-guide.md +100 -0
- package/.agents/skills/laporan-generator/references/troubleshooting.md +105 -0
- package/.agents/skills/laporan-generator/resources/Makefile +90 -0
- package/.agents/skills/laporan-generator/resources/apa.csl +2273 -0
- package/.agents/skills/laporan-generator/resources/build-docx.sh +122 -0
- package/.agents/skills/laporan-generator/resources/build.sh +102 -0
- package/.agents/skills/laporan-generator/resources/chapters/bab1-pendahuluan.md +60 -0
- package/.agents/skills/laporan-generator/resources/chapters/bab2-tinjauan-pustaka.md +83 -0
- package/.agents/skills/laporan-generator/resources/chapters/bab3-metodologi.md +116 -0
- package/.agents/skills/laporan-generator/resources/chapters/bab4-hasil-dan-pembahasan.md +93 -0
- package/.agents/skills/laporan-generator/resources/chapters/bab5-penutup.md +27 -0
- package/.agents/skills/laporan-generator/resources/cover.md +50 -0
- package/.agents/skills/laporan-generator/resources/docx.lua +416 -0
- package/.agents/skills/laporan-generator/resources/laporan +464 -0
- package/.agents/skills/laporan-generator/resources/laporan.ps1 +552 -0
- package/.agents/skills/laporan-generator/resources/logo.jpg +0 -0
- package/.agents/skills/laporan-generator/resources/metadata.yml +35 -0
- package/.agents/skills/laporan-generator/resources/presets/itb-ta.yml +27 -0
- package/.agents/skills/laporan-generator/resources/presets/its-skripsi.yml +26 -0
- package/.agents/skills/laporan-generator/resources/presets/skripsi-4433.yml +26 -0
- package/.agents/skills/laporan-generator/resources/presets/standard.yml +26 -0
- package/.agents/skills/laporan-generator/resources/presets/ugm-skripsi.yml +26 -0
- package/.agents/skills/laporan-generator/resources/presets/ui-skripsi.yml +26 -0
- package/.agents/skills/laporan-generator/resources/presets/unpad-skripsi.yml +27 -0
- package/.agents/skills/laporan-generator/resources/reference.docx +0 -0
- package/.agents/skills/laporan-generator/resources/references.bib +115 -0
- package/.agents/skills/laporan-generator/resources/scripts/bundle.py +75 -0
- package/.agents/skills/laporan-generator/resources/scripts/docx-pagenum.py +192 -0
- package/.agents/skills/laporan-generator/resources/scripts/finalize-docx.py +291 -0
- package/.agents/skills/laporan-generator/resources/scripts/make-reference-docx.py +670 -0
- package/.agents/skills/laporan-generator/resources/scripts/report-doctor.py +211 -0
- package/.agents/skills/laporan-generator/resources/scripts/report-stats.py +149 -0
- package/.agents/skills/laporan-generator/resources/scripts/scan-preset.py +311 -0
- package/.agents/skills/laporan-generator/resources/scripts/setup-deps.ps1 +152 -0
- package/.agents/skills/laporan-generator/resources/scripts/setup-deps.sh +113 -0
- package/.agents/skills/laporan-generator/resources/scripts/test_scripts.py +128 -0
- package/.agents/skills/laporan-generator/resources/scripts/validate-preset.py +166 -0
- package/.agents/skills/laporan-generator/resources/template.typ +394 -0
- package/.agents/skills/laporan-generator/scripts/build.sh +78 -0
- package/.agents/skills/laporan-generator/scripts/bundle.py +75 -0
- package/.agents/skills/laporan-generator/scripts/docx-pagenum.py +192 -0
- package/.agents/skills/laporan-generator/scripts/finalize-docx.py +152 -0
- package/.agents/skills/laporan-generator/scripts/laporan +447 -0
- package/.agents/skills/laporan-generator/scripts/laporan.ps1 +529 -0
- package/.agents/skills/laporan-generator/scripts/make-reference-docx.py +630 -0
- package/.agents/skills/laporan-generator/scripts/report-doctor.py +211 -0
- package/.agents/skills/laporan-generator/scripts/report-stats.py +149 -0
- package/.agents/skills/laporan-generator/scripts/scan-preset.py +311 -0
- package/.agents/skills/laporan-generator/scripts/setup-deps.ps1 +152 -0
- package/.agents/skills/laporan-generator/scripts/setup-deps.sh +113 -0
- package/.agents/skills/laporan-generator/scripts/test_scripts.py +103 -0
- package/.agents/skills/laporan-generator/scripts/validate-preset.py +166 -0
- package/.agents/workflows/laporan-generator.md +8 -0
- package/LICENSE +21 -0
- package/Makefile +90 -0
- package/README.md +389 -0
- package/apa.csl +2273 -0
- package/bin/laporan-generator.js +71 -0
- package/build-docx.sh +122 -0
- package/build.sh +102 -0
- package/chapters/bab1-pendahuluan.md +60 -0
- package/chapters/bab2-tinjauan-pustaka.md +83 -0
- package/chapters/bab3-metodologi.md +116 -0
- package/chapters/bab4-hasil-dan-pembahasan.md +93 -0
- package/chapters/bab5-penutup.md +27 -0
- package/cover.md +50 -0
- package/docs/campus-guide.md +120 -0
- package/docs/metadata-schema.md +76 -0
- package/docs/preset-schema.md +79 -0
- package/docs/syntax-cheatsheet.md +122 -0
- package/docs/template-guide.md +100 -0
- package/docs/troubleshooting.md +105 -0
- package/docx.lua +416 -0
- package/laporan +464 -0
- package/laporan.ps1 +552 -0
- package/lib/init.js +118 -0
- package/lib/setup.js +33 -0
- package/lib/sync-hosts.js +194 -0
- package/lib/uninstall.js +123 -0
- package/logo.jpg +0 -0
- package/metadata.yml +35 -0
- package/package.json +65 -0
- package/presets/itb-ta.yml +27 -0
- package/presets/its-skripsi.yml +26 -0
- package/presets/skripsi-4433.yml +26 -0
- package/presets/standard.yml +26 -0
- package/presets/ugm-skripsi.yml +26 -0
- package/presets/ui-skripsi.yml +26 -0
- package/presets/unpad-skripsi.yml +27 -0
- package/reference.docx +0 -0
- package/references.bib +115 -0
- package/scripts/bundle.py +75 -0
- package/scripts/docx-pagenum.py +192 -0
- package/scripts/finalize-docx.py +291 -0
- package/scripts/make-reference-docx.py +670 -0
- package/scripts/report-doctor.py +211 -0
- package/scripts/report-stats.py +149 -0
- package/scripts/scan-preset.py +311 -0
- package/scripts/setup-deps.ps1 +152 -0
- package/scripts/setup-deps.sh +113 -0
- package/scripts/test_scripts.py +128 -0
- package/scripts/validate-preset.py +166 -0
- package/template.typ +394 -0
package/laporan.ps1
ADDED
|
@@ -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.1 " -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, 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
|
+
}
|
package/lib/init.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
function copyRecursiveSync(src, dest) {
|
|
7
|
+
if (!fs.existsSync(src)) return;
|
|
8
|
+
const stats = fs.statSync(src);
|
|
9
|
+
if (stats.isDirectory()) {
|
|
10
|
+
if (!fs.existsSync(dest)) {
|
|
11
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
fs.readdirSync(src).forEach((childItemName) => {
|
|
14
|
+
copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
|
|
15
|
+
});
|
|
16
|
+
} else {
|
|
17
|
+
fs.copyFileSync(src, dest);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function run(argv = []) {
|
|
22
|
+
const cwd = process.cwd();
|
|
23
|
+
console.log('\n==========================================================');
|
|
24
|
+
console.log(' LAPORAN GENERATOR - INISIALISASI PROYEK DOKUMEN ');
|
|
25
|
+
console.log('==========================================================\n');
|
|
26
|
+
|
|
27
|
+
const metaPath = path.join(cwd, 'metadata.yml');
|
|
28
|
+
if (fs.existsSync(metaPath)) {
|
|
29
|
+
console.log('[WARN] Dokumen laporan sudah ada di direktori ini (metadata.yml ditemukan).');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Cari direktori resources (bisa dari package root atau global skills)
|
|
34
|
+
const pkgResources = path.join(__dirname, '../.agents/skills/laporan-generator/resources');
|
|
35
|
+
const globalResources = path.join(require('os').homedir(), '.agents/skills/laporan-generator/resources');
|
|
36
|
+
const sourceDir = fs.existsSync(pkgResources) ? pkgResources : (fs.existsSync(globalResources) ? globalResources : null);
|
|
37
|
+
|
|
38
|
+
if (sourceDir) {
|
|
39
|
+
console.log(`Menyalin template lengkap dari: ${sourceDir} ...\n`);
|
|
40
|
+
const filesToCopy = [
|
|
41
|
+
'metadata.yml',
|
|
42
|
+
'cover.md',
|
|
43
|
+
'references.bib',
|
|
44
|
+
'apa.csl',
|
|
45
|
+
'logo.jpg',
|
|
46
|
+
'template.typ',
|
|
47
|
+
'reference.docx',
|
|
48
|
+
'docx.lua',
|
|
49
|
+
'Makefile',
|
|
50
|
+
'build.sh',
|
|
51
|
+
'build-docx.sh',
|
|
52
|
+
'laporan',
|
|
53
|
+
'laporan.ps1',
|
|
54
|
+
'presets',
|
|
55
|
+
'chapters',
|
|
56
|
+
'scripts'
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
for (const f of filesToCopy) {
|
|
60
|
+
const srcFile = path.join(sourceDir, f);
|
|
61
|
+
const destFile = path.join(cwd, f);
|
|
62
|
+
if (fs.existsSync(srcFile) && !fs.existsSync(destFile)) {
|
|
63
|
+
copyRecursiveSync(srcFile, destFile);
|
|
64
|
+
console.log(` ✔ Disalin: ${f}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// Fallback manual jika source resources tidak ditemukan
|
|
69
|
+
const defaultMeta = `title: "Laporan Akademik & Proyek"
|
|
70
|
+
author:
|
|
71
|
+
- name: "Nama Penulis"
|
|
72
|
+
id: "1234567890"
|
|
73
|
+
date: "2026"
|
|
74
|
+
institution: "Universitas / Institusi Akademik"
|
|
75
|
+
faculty: "Fakultas Teknik & Ilmu Komputer"
|
|
76
|
+
department: "Program Studi Informatika"
|
|
77
|
+
location: "Indonesia"
|
|
78
|
+
margin_preset: "skripsi-4433"
|
|
79
|
+
font_family: "Times New Roman"
|
|
80
|
+
font_size: "12pt"
|
|
81
|
+
line_spacing: "0.75em"
|
|
82
|
+
first_line_indent: "1.25cm"
|
|
83
|
+
heading_chapter_prefix: "BAB "
|
|
84
|
+
heading_chapter_num_format: "roman"
|
|
85
|
+
`;
|
|
86
|
+
fs.writeFileSync(metaPath, defaultMeta, 'utf8');
|
|
87
|
+
console.log(' ✔ Dibuat: metadata.yml (Preset: skripsi-4433)');
|
|
88
|
+
|
|
89
|
+
const coverPath = path.join(cwd, 'cover.md');
|
|
90
|
+
fs.writeFileSync(coverPath, '# Laporan Akademik\n\nDokumen ini disusun sebagai dokumentasi resmi laporan proyek/penelitian.\n', 'utf8');
|
|
91
|
+
console.log(' ✔ Dibuat: cover.md');
|
|
92
|
+
|
|
93
|
+
const chaptersDir = path.join(cwd, 'chapters');
|
|
94
|
+
if (!fs.existsSync(chaptersDir)) fs.mkdirSync(chaptersDir, { recursive: true });
|
|
95
|
+
const bab1 = `# Pendahuluan\n\n## Latar Belakang\nTuliskan latar belakang masalah di sini.\n\n## Rumusan Masalah\n1. Masalah pertama.\n2. Masalah kedua.\n\n## Tujuan Penelitian\nTujuan dari pelaksanaan proyek ini adalah menghasilkan analisis yang komprehensif.\n`;
|
|
96
|
+
fs.writeFileSync(path.join(chaptersDir, 'bab1-pendahuluan.md'), bab1, 'utf8');
|
|
97
|
+
console.log(' ✔ Dibuat: chapters/bab1-pendahuluan.md');
|
|
98
|
+
|
|
99
|
+
const refBibPath = path.join(cwd, 'references.bib');
|
|
100
|
+
fs.writeFileSync(refBibPath, `@book{contoh2026,\n title = {Panduan Penulisan Karya Ilmiah},\n author = {Penulis, Contoh},\n year = {2026},\n publisher = {Penerbit Akademik}\n}\n`, 'utf8');
|
|
101
|
+
console.log(' ✔ Dibuat: references.bib');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Ensure scripts are executable on Unix
|
|
105
|
+
try {
|
|
106
|
+
if (process.platform !== 'win32') {
|
|
107
|
+
const laporanBin = path.join(cwd, 'laporan');
|
|
108
|
+
const buildSh = path.join(cwd, 'build.sh');
|
|
109
|
+
if (fs.existsSync(laporanBin)) fs.chmodSync(laporanBin, '755');
|
|
110
|
+
if (fs.existsSync(buildSh)) fs.chmodSync(buildSh, '755');
|
|
111
|
+
}
|
|
112
|
+
} catch (_) {}
|
|
113
|
+
|
|
114
|
+
console.log('\n✨ Inisialisasi dokumen selesai!');
|
|
115
|
+
console.log('Jalankan "./laporan build" atau "npx laporan-generator build" untuk mengompilasi dokumen ke PDF & Word!\n');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = { run };
|