@liascript/exporter 3.0.0--1.0.3 → 3.0.1--1.0.3
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/dist/assets/capacitor/{index.bfe7363b.js → index.a7f021f7.js} +1 -1
- package/dist/assets/capacitor/index.html +1 -1
- package/dist/assets/capacitor/{jszip.min.f6eda75b.js → jszip.min.43389eb1.js} +1 -1
- package/dist/assets/capacitor/{trystero-ipfs.min.b27a61d7.js → trystero-ipfs.min.f25fe3e7.js} +1 -1
- package/dist/assets/indexeddb/{index.599a57d6.js → index.4aceca2f.js} +1 -1
- package/dist/assets/indexeddb/index.html +1 -1
- package/dist/assets/indexeddb/{jszip.min.63142cc8.js → jszip.min.4fbcc13f.js} +1 -1
- package/dist/assets/scorm2004/{index.7a5820ab.js → index.33bec53a.js} +1 -1
- package/dist/assets/scorm2004/index.html +1 -1
- package/dist/assets/scorm2004/{jszip.min.63142cc8.js → jszip.min.4fbcc13f.js} +1 -1
- package/dist/assets/xapi/{index.018a032a.js → index.f2e89e49.js} +1 -1
- package/dist/assets/xapi/index.html +1 -1
- package/dist/assets/xapi/{jszip.min.eaecf580.js → jszip.min.19c66d77.js} +1 -1
- package/dist/index.js +47 -47
- package/dist/server/presets.json +94 -0
- package/dist/server/presets.yaml +120 -0
- package/dist/server/public/app.js +1 -0
- package/dist/server/public/assets/android.svg +38 -0
- package/dist/server/public/assets/cmi.svg +154 -0
- package/dist/server/public/assets/docx.svg +20 -0
- package/dist/server/public/assets/edX.svg +75 -0
- package/dist/server/public/assets/edx.svg +75 -0
- package/dist/server/public/assets/epub.svg +18 -0
- package/dist/server/public/assets/icon.svg +82 -0
- package/dist/server/public/assets/ilias.png +0 -0
- package/dist/server/public/assets/json.svg +4 -0
- package/dist/server/public/assets/learnworlds.png +0 -0
- package/dist/server/public/assets/moodle.svg +190 -0
- package/dist/server/public/assets/opal.png +0 -0
- package/dist/server/public/assets/openolat.png +0 -0
- package/dist/server/public/assets/pdf.svg +4 -0
- package/dist/server/public/assets/rdf.svg +4 -0
- package/dist/server/public/assets/scorm.png +0 -0
- package/dist/server/public/assets/web.png +0 -0
- package/dist/server/public/assets/xapi.png +0 -0
- package/dist/server/public/i18n.js +1 -0
- package/dist/server/public/index.html +1587 -0
- package/dist/server/public/locales/de.json +247 -0
- package/dist/server/public/locales/en.json +247 -0
- package/dist/server/public/status.html +251 -0
- package/dist/server/public/styles.css +712 -0
- package/package.json +5 -1
- package/.parcelrc +0 -3
- package/DESKTOP_APP_README.md +0 -58
- package/DOCKERHUB_DESCRIPTION.md +0 -52
- package/Dockerfile +0 -129
- package/PLAYSTORE_GUIDE.md +0 -172
- package/action.yml +0 -157
- package/custom.css +0 -10
- package/electron-builder.json +0 -149
- package/src/cli.ts +0 -69
- package/src/colorize.ts +0 -115
- package/src/export/android.ts +0 -419
- package/src/export/docx.ts +0 -1025
- package/src/export/epub.ts +0 -1306
- package/src/export/h5p.ts +0 -390
- package/src/export/helper.ts +0 -360
- package/src/export/ims.ts +0 -191
- package/src/export/pdf.ts +0 -406
- package/src/export/presets.ts +0 -220
- package/src/export/project.ts +0 -829
- package/src/export/rdf.ts +0 -551
- package/src/export/scorm12.ts +0 -167
- package/src/export/scorm2004.ts +0 -140
- package/src/export/web.ts +0 -306
- package/src/export/xapi.ts +0 -424
- package/src/exporter.ts +0 -296
- package/src/index.ts +0 -96
- package/src/parser.ts +0 -373
- package/src/presets.yaml +0 -219
- package/src/types.ts +0 -82
- package/tsconfig.json +0 -24
package/src/export/pdf.ts
DELETED
|
@@ -1,406 +0,0 @@
|
|
|
1
|
-
import * as helper from './helper'
|
|
2
|
-
import * as COLOR from '../colorize'
|
|
3
|
-
import * as path from 'path'
|
|
4
|
-
import puppeteer, { Browser, Page } from 'puppeteer'
|
|
5
|
-
|
|
6
|
-
// Default PDF generation settings
|
|
7
|
-
const DEFAULT_TIMEOUT_MS = 15000 // 15 seconds
|
|
8
|
-
const DEFAULT_MARGIN_TOP = 80
|
|
9
|
-
const DEFAULT_MARGIN_BOTTOM = 80
|
|
10
|
-
const DEFAULT_MARGIN_LEFT = 30
|
|
11
|
-
const DEFAULT_MARGIN_RIGHT = 30
|
|
12
|
-
const DEFAULT_SCALE = 1
|
|
13
|
-
const DEFAULT_FORMAT = 'a4'
|
|
14
|
-
const DEFAULT_PRINT_BACKGROUND = true
|
|
15
|
-
const DEFAULT_DISPLAY_HEADER_FOOTER = false
|
|
16
|
-
const DEFAULT_LANDSCAPE = false
|
|
17
|
-
const DEFAULT_OMIT_BACKGROUND = false
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Displays help information about PDF export options and settings.
|
|
21
|
-
* Shows both LiaScript-specific settings and Puppeteer PDF options.
|
|
22
|
-
*/
|
|
23
|
-
export function help() {
|
|
24
|
-
console.log('')
|
|
25
|
-
console.log(COLOR.heading('PDF settings:'), '\n')
|
|
26
|
-
|
|
27
|
-
COLOR.info(
|
|
28
|
-
'PDF export generates printable documents from your LiaScript course using Puppeteer, a headless Chrome browser automation tool. This allows for high-quality rendering of all course elements including interactive content.',
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
console.log('\nLearn more: https://pptr.dev/ \n')
|
|
32
|
-
|
|
33
|
-
COLOR.command(
|
|
34
|
-
null,
|
|
35
|
-
'--pdf-stylesheet',
|
|
36
|
-
' Inject an local CSS for changing the appearance.',
|
|
37
|
-
)
|
|
38
|
-
COLOR.command(
|
|
39
|
-
null,
|
|
40
|
-
'--pdf-theme',
|
|
41
|
-
' LiaScript themes: default, turquoise, blue, red, yellow',
|
|
42
|
-
)
|
|
43
|
-
COLOR.command(
|
|
44
|
-
null,
|
|
45
|
-
'--pdf-timeout',
|
|
46
|
-
` Set an additional time horizon to wait until finished (default ${DEFAULT_TIMEOUT_MS} ms)`,
|
|
47
|
-
)
|
|
48
|
-
COLOR.command(
|
|
49
|
-
null,
|
|
50
|
-
'--pdf-preview',
|
|
51
|
-
' Open preview-browser (default false), print not possible',
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
console.log('')
|
|
55
|
-
console.log(COLOR.italic('The following are puppeteer specific settings.'))
|
|
56
|
-
|
|
57
|
-
console.log(
|
|
58
|
-
'\nLearn more:\n https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pagepdfoptions\n',
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
COLOR.command(
|
|
62
|
-
null,
|
|
63
|
-
'--pdf-scale',
|
|
64
|
-
' Scale of the webpage rendering. Defaults to 1. Scale amount must be between 0.1 and 2.',
|
|
65
|
-
)
|
|
66
|
-
COLOR.command(
|
|
67
|
-
null,
|
|
68
|
-
'--pdf-displayHeaderFooter',
|
|
69
|
-
' Display header and footer. Defaults to false.',
|
|
70
|
-
)
|
|
71
|
-
COLOR.command(
|
|
72
|
-
null,
|
|
73
|
-
'--pdf-headerTemplate',
|
|
74
|
-
' HTML template for the print header, inject classes date, title, url, pageNumber, totalPages',
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
COLOR.command(
|
|
78
|
-
null,
|
|
79
|
-
'--pdf-footerTemplate',
|
|
80
|
-
' HTML template for the print footer. Should use the same format as the headerTemplate',
|
|
81
|
-
)
|
|
82
|
-
COLOR.command(
|
|
83
|
-
null,
|
|
84
|
-
'--pdf-printBackground',
|
|
85
|
-
' Print background graphics. Defaults to false',
|
|
86
|
-
)
|
|
87
|
-
COLOR.command(
|
|
88
|
-
null,
|
|
89
|
-
'--pdf-landscape',
|
|
90
|
-
' Paper orientation. Defaults to false.',
|
|
91
|
-
)
|
|
92
|
-
COLOR.command(
|
|
93
|
-
null,
|
|
94
|
-
'--pdf-pageRanges',
|
|
95
|
-
' Paper ranges to print, e.g., "1-5, 8, 11-13"',
|
|
96
|
-
)
|
|
97
|
-
COLOR.command(
|
|
98
|
-
null,
|
|
99
|
-
'--pdf-format',
|
|
100
|
-
' Paper format. If set, takes priority over width or height options. Defaults to a4.',
|
|
101
|
-
)
|
|
102
|
-
COLOR.command(
|
|
103
|
-
null,
|
|
104
|
-
'--pdf-width',
|
|
105
|
-
' Paper width, accepts values labeled with units.',
|
|
106
|
-
)
|
|
107
|
-
COLOR.command(
|
|
108
|
-
null,
|
|
109
|
-
'--pdf-height',
|
|
110
|
-
' Paper height, accepts values labeled with units.',
|
|
111
|
-
)
|
|
112
|
-
COLOR.command(
|
|
113
|
-
null,
|
|
114
|
-
'--pdf-margin-top',
|
|
115
|
-
' Top margin, accepts values labeled with units.',
|
|
116
|
-
)
|
|
117
|
-
COLOR.command(
|
|
118
|
-
null,
|
|
119
|
-
'--pdf-margin-right',
|
|
120
|
-
' Right margin, accepts values labeled with units.',
|
|
121
|
-
)
|
|
122
|
-
COLOR.command(
|
|
123
|
-
null,
|
|
124
|
-
'--pdf-margin-bottom',
|
|
125
|
-
' Bottom margin, accepts values labeled with units.',
|
|
126
|
-
)
|
|
127
|
-
COLOR.command(
|
|
128
|
-
null,
|
|
129
|
-
'--pdf-margin-left',
|
|
130
|
-
' Left margin, accepts values labeled with units. ',
|
|
131
|
-
)
|
|
132
|
-
COLOR.command(
|
|
133
|
-
null,
|
|
134
|
-
'--pdf-preferCSSPageSize',
|
|
135
|
-
' Give any CSS @page size declared in the page priority over what is declared in width and height or format options.',
|
|
136
|
-
)
|
|
137
|
-
COLOR.command(
|
|
138
|
-
null,
|
|
139
|
-
'--pdf-omitBackground',
|
|
140
|
-
' Hides default white background and allows capturing screenshots with transparency. Defaults to true. ',
|
|
141
|
-
)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Configuration options for PDF export.
|
|
146
|
-
*/
|
|
147
|
-
export interface PdfExportArguments {
|
|
148
|
-
input: string
|
|
149
|
-
output: string
|
|
150
|
-
|
|
151
|
-
// PDF-specific settings
|
|
152
|
-
'pdf-preview'?: boolean
|
|
153
|
-
'pdf-scale'?: number
|
|
154
|
-
'pdf-displayHeaderFooter'?: boolean
|
|
155
|
-
'pdf-headerTemplate'?: string
|
|
156
|
-
'pdf-footerTemplate'?: string
|
|
157
|
-
'pdf-printBackground'?: boolean
|
|
158
|
-
'pdf-landscape'?: boolean
|
|
159
|
-
'pdf-format'?: string
|
|
160
|
-
'pdf-width'?: string | number
|
|
161
|
-
'pdf-height'?: string | number
|
|
162
|
-
'pdf-margin-top'?: string | number
|
|
163
|
-
'pdf-margin-bottom'?: string | number
|
|
164
|
-
'pdf-margin-right'?: string | number
|
|
165
|
-
'pdf-margin-left'?: string | number
|
|
166
|
-
'pdf-preferCSSPageSize'?: boolean
|
|
167
|
-
'pdf-omitBackground'?: boolean
|
|
168
|
-
'pdf-timeout'?: number
|
|
169
|
-
'pdf-pageRanges'?: string
|
|
170
|
-
|
|
171
|
-
'pdf-stylesheet'?: string
|
|
172
|
-
'pdf-theme'?: string
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
export const format = 'pdf'
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Exports a LiaScript course to PDF format using Puppeteer.
|
|
179
|
-
*
|
|
180
|
-
* This function launches a headless Chrome browser, loads the LiaScript content,
|
|
181
|
-
* applies any custom styling or themes, and generates a PDF file.
|
|
182
|
-
*
|
|
183
|
-
* @param argument - Configuration options for the PDF export
|
|
184
|
-
* @throws {Error} If browser launch fails, page navigation fails, or PDF generation fails
|
|
185
|
-
*
|
|
186
|
-
* @example
|
|
187
|
-
* ```typescript
|
|
188
|
-
* await exporter({
|
|
189
|
-
* input: './course.md',
|
|
190
|
-
* output: './output',
|
|
191
|
-
* 'pdf-format': 'a4',
|
|
192
|
-
* 'pdf-printBackground': true
|
|
193
|
-
* })
|
|
194
|
-
* ```
|
|
195
|
-
*/
|
|
196
|
-
export async function exporter(argument: PdfExportArguments) {
|
|
197
|
-
const dirname = helper.dirname()
|
|
198
|
-
|
|
199
|
-
let url = `file://${dirname}/assets/pdf/index.html?`
|
|
200
|
-
|
|
201
|
-
if (helper.isURL(argument.input)) {
|
|
202
|
-
url += argument.input
|
|
203
|
-
} else {
|
|
204
|
-
url += 'file://' + path.resolve(argument.input)
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
let browser: Browser | null = null
|
|
208
|
-
let page: Page | null = null
|
|
209
|
-
|
|
210
|
-
try {
|
|
211
|
-
// Configure browser launch options
|
|
212
|
-
const launchOptions: any = {
|
|
213
|
-
pipe: true,
|
|
214
|
-
args: [
|
|
215
|
-
'--no-sandbox',
|
|
216
|
-
'--disable-web-security',
|
|
217
|
-
'--disable-features=IsolateOrigins',
|
|
218
|
-
'--disable-site-isolation-trials',
|
|
219
|
-
'--unhandled-rejections=strict',
|
|
220
|
-
'--disable-features=BlockInsecurePrivateNetworkRequests',
|
|
221
|
-
'--allow-file-access-from-files',
|
|
222
|
-
'--enable-local-file-accesses',
|
|
223
|
-
'--enable-features=ExperimentalJavaScript',
|
|
224
|
-
],
|
|
225
|
-
headless: !argument['pdf-preview'],
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Use custom executable path if provided, otherwise use Chrome channel
|
|
229
|
-
if (process.env.PUPPETEER_EXECUTABLE_PATH) {
|
|
230
|
-
launchOptions.executablePath = process.env.PUPPETEER_EXECUTABLE_PATH
|
|
231
|
-
} else {
|
|
232
|
-
launchOptions.channel = 'chrome'
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
try {
|
|
236
|
-
browser = await puppeteer.launch(launchOptions)
|
|
237
|
-
} catch (launchError) {
|
|
238
|
-
throw new Error(
|
|
239
|
-
`Failed to launch browser. Make sure Chrome is installed. ${launchError}`,
|
|
240
|
-
)
|
|
241
|
-
}
|
|
242
|
-
page = await browser.newPage()
|
|
243
|
-
|
|
244
|
-
console.log(
|
|
245
|
-
'Loading course content... This may take a while for large courses.',
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
// Handle alert dialogs automatically to prevent blocking
|
|
249
|
-
page.on('dialog', async (dialog) => {
|
|
250
|
-
console.log(`[Dialog ${dialog.type()}]: ${dialog.message()}`)
|
|
251
|
-
await dialog.accept()
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
// Set up render done listener BEFORE navigating to catch the signal
|
|
255
|
-
let renderDoneResolve: () => void
|
|
256
|
-
const renderDonePromise = new Promise<void>((resolve) => {
|
|
257
|
-
renderDoneResolve = resolve
|
|
258
|
-
})
|
|
259
|
-
|
|
260
|
-
page.on('console', (msg) => {
|
|
261
|
-
const text = msg.text()
|
|
262
|
-
if (text.startsWith('__RENDER_DONE__')) {
|
|
263
|
-
console.log('got render done signal:', text)
|
|
264
|
-
renderDoneResolve()
|
|
265
|
-
}
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
await page.setExtraHTTPHeaders({
|
|
269
|
-
referer: 'https://liascript.github.io/',
|
|
270
|
-
})
|
|
271
|
-
// Wait for page to load completely
|
|
272
|
-
// Using 'networkidle2' ensures all network requests are complete
|
|
273
|
-
// Timeout set to 0 (unlimited) to handle large courses
|
|
274
|
-
await page.goto(url, {
|
|
275
|
-
waitUntil: 'networkidle2',
|
|
276
|
-
timeout: DEFAULT_TIMEOUT_MS,
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
if (argument['pdf-stylesheet']) {
|
|
280
|
-
const href = path.resolve(dirname + '/../', argument['pdf-stylesheet'])
|
|
281
|
-
|
|
282
|
-
try {
|
|
283
|
-
await page.evaluate(async (href) => {
|
|
284
|
-
const link = document.createElement('link')
|
|
285
|
-
link.rel = 'stylesheet'
|
|
286
|
-
link.href = href
|
|
287
|
-
|
|
288
|
-
const promise = new Promise((resolve, reject) => {
|
|
289
|
-
link.onload = resolve
|
|
290
|
-
link.onerror = reject
|
|
291
|
-
})
|
|
292
|
-
document.head.appendChild(link)
|
|
293
|
-
await promise
|
|
294
|
-
}, href)
|
|
295
|
-
} catch (e) {
|
|
296
|
-
throw new Error(
|
|
297
|
-
`Failed to load custom stylesheet from '${argument['pdf-stylesheet']}': ${e}`,
|
|
298
|
-
)
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
if (argument['pdf-theme']) {
|
|
303
|
-
try {
|
|
304
|
-
await page.evaluate(async (theme) => {
|
|
305
|
-
document.documentElement.classList.remove('lia-theme-default')
|
|
306
|
-
document.documentElement.classList.add('lia-theme-' + theme)
|
|
307
|
-
}, argument['pdf-theme'])
|
|
308
|
-
} catch (e) {
|
|
309
|
-
throw new Error(
|
|
310
|
-
`Failed to apply theme '${argument['pdf-theme']}': ${e}`,
|
|
311
|
-
)
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
if (!argument['pdf-preview']) {
|
|
316
|
-
// Wait for LiaScript to signal rendering is complete
|
|
317
|
-
await renderDonePromise
|
|
318
|
-
|
|
319
|
-
// Additional wait time for any final rendering
|
|
320
|
-
if (argument['pdf-timeout']) {
|
|
321
|
-
await helper.sleep(argument['pdf-timeout'])
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
await toPDF(argument, page)
|
|
325
|
-
} else {
|
|
326
|
-
console.log('Preview mode enabled - browser will remain open')
|
|
327
|
-
}
|
|
328
|
-
} catch (e) {
|
|
329
|
-
const error = e as Error
|
|
330
|
-
console.error('PDF export failed:', error.message)
|
|
331
|
-
throw new Error(`Failed to export PDF: ${error.message}`)
|
|
332
|
-
} finally {
|
|
333
|
-
// Clean up resources based on mode
|
|
334
|
-
if (argument['pdf-preview']) {
|
|
335
|
-
// In preview mode, keep browser open but inform user
|
|
336
|
-
console.log('Browser kept open for preview. Close manually when done.')
|
|
337
|
-
} else {
|
|
338
|
-
// In normal mode, always close browser and page
|
|
339
|
-
if (page) {
|
|
340
|
-
try {
|
|
341
|
-
await page.close()
|
|
342
|
-
} catch (closeError) {
|
|
343
|
-
console.error('Failed to close page:', closeError)
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (browser) {
|
|
348
|
-
try {
|
|
349
|
-
await browser.close()
|
|
350
|
-
} catch (closeError) {
|
|
351
|
-
console.error('Failed to close browser:', closeError)
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Generates a PDF file from a Puppeteer page.
|
|
360
|
-
*
|
|
361
|
-
* Emulates screen media type for proper rendering and applies all PDF-specific
|
|
362
|
-
* settings like margins, format, scaling, etc.
|
|
363
|
-
*
|
|
364
|
-
* @param argument - PDF export configuration options
|
|
365
|
-
* @param page - Puppeteer page instance containing the rendered content
|
|
366
|
-
* @throws {Error} If PDF generation fails or media type emulation fails
|
|
367
|
-
*/
|
|
368
|
-
async function toPDF(argument: PdfExportArguments, page: Page) {
|
|
369
|
-
try {
|
|
370
|
-
await page.emulateMediaType('screen')
|
|
371
|
-
} catch (e) {
|
|
372
|
-
throw new Error(`Failed to emulate media type: ${e}`)
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
try {
|
|
376
|
-
await page.pdf({
|
|
377
|
-
path: argument.output + '.pdf',
|
|
378
|
-
format: (argument['pdf-format'] as any) || DEFAULT_FORMAT,
|
|
379
|
-
printBackground:
|
|
380
|
-
argument['pdf-printBackground'] ?? DEFAULT_PRINT_BACKGROUND,
|
|
381
|
-
displayHeaderFooter:
|
|
382
|
-
argument['pdf-displayHeaderFooter'] ?? DEFAULT_DISPLAY_HEADER_FOOTER,
|
|
383
|
-
margin: {
|
|
384
|
-
top: argument['pdf-margin-top'] || DEFAULT_MARGIN_TOP,
|
|
385
|
-
bottom: argument['pdf-margin-bottom'] || DEFAULT_MARGIN_BOTTOM,
|
|
386
|
-
left: argument['pdf-margin-left'] || DEFAULT_MARGIN_LEFT,
|
|
387
|
-
right: argument['pdf-margin-right'] || DEFAULT_MARGIN_RIGHT,
|
|
388
|
-
},
|
|
389
|
-
scale: argument['pdf-scale'] ?? DEFAULT_SCALE,
|
|
390
|
-
headerTemplate: argument['pdf-headerTemplate'],
|
|
391
|
-
footerTemplate: argument['pdf-footerTemplate'] ?? '',
|
|
392
|
-
landscape: argument['pdf-landscape'] ?? DEFAULT_LANDSCAPE,
|
|
393
|
-
width: argument['pdf-width'] ?? '',
|
|
394
|
-
height: argument['pdf-height'] ?? '',
|
|
395
|
-
pageRanges: argument['pdf-pageRanges'],
|
|
396
|
-
preferCSSPageSize: argument['pdf-preferCSSPageSize'],
|
|
397
|
-
omitBackground: argument['pdf-omitBackground'] ?? DEFAULT_OMIT_BACKGROUND,
|
|
398
|
-
})
|
|
399
|
-
console.log(`PDF successfully generated: ${argument.output}.pdf`)
|
|
400
|
-
} catch (e) {
|
|
401
|
-
const error = e as Error
|
|
402
|
-
throw new Error(
|
|
403
|
-
`Failed to generate PDF at '${argument.output}.pdf': ${error.message}`,
|
|
404
|
-
)
|
|
405
|
-
}
|
|
406
|
-
}
|
package/src/export/presets.ts
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
import * as COLOR from '../colorize'
|
|
2
|
-
import * as fs from 'fs-extra'
|
|
3
|
-
import * as path from 'path'
|
|
4
|
-
import YAML from 'yaml'
|
|
5
|
-
import { Preset, PresetsConfig } from '../types'
|
|
6
|
-
|
|
7
|
-
export const format = 'presets'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Displays help information about preset functionality
|
|
11
|
-
*/
|
|
12
|
-
export function help() {
|
|
13
|
-
console.log('')
|
|
14
|
-
console.log(COLOR.heading('Presets:'), '\n')
|
|
15
|
-
|
|
16
|
-
COLOR.info(
|
|
17
|
-
'Presets provide pre-configured export settings optimized for specific Learning Management Systems (LMS). Use presets to quickly export your LiaScript course with tested configurations.',
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
console.log('\nUsage examples:\n')
|
|
21
|
-
console.log(' List all available presets:')
|
|
22
|
-
console.log(COLOR.italic(' liaex -f presets\n'))
|
|
23
|
-
|
|
24
|
-
console.log(' Show configuration for a specific preset:')
|
|
25
|
-
console.log(COLOR.italic(' liaex -f presets --moodle\n'))
|
|
26
|
-
|
|
27
|
-
console.log(' Export with preset configuration:')
|
|
28
|
-
console.log(
|
|
29
|
-
COLOR.italic(' liaex -i course.md -f presets --moodle -o output\n'),
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
console.log(' Override preset parameters with additional flags:')
|
|
33
|
-
console.log(
|
|
34
|
-
COLOR.italic(
|
|
35
|
-
' liaex -i course.md -f presets --moodle --scorm-organization "My Org" -o output\n',
|
|
36
|
-
),
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
COLOR.info(
|
|
40
|
-
'Note: You can add any format-specific parameters (like --scorm-organization, --scorm-iframe, etc.) to override the preset defaults.',
|
|
41
|
-
)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Load and parse the presets.yaml file
|
|
46
|
-
* @returns Parsed presets configuration
|
|
47
|
-
*/
|
|
48
|
-
export function loadPresets(): PresetsConfig {
|
|
49
|
-
try {
|
|
50
|
-
const dirname = path.resolve(__dirname, '..')
|
|
51
|
-
const presetsPath = path.join(dirname, 'presets.yaml')
|
|
52
|
-
|
|
53
|
-
if (!fs.existsSync(presetsPath)) {
|
|
54
|
-
throw new Error(`Presets file not found at: ${presetsPath}`)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const fileContents = fs.readFileSync(presetsPath, 'utf8')
|
|
58
|
-
const data = YAML.parse(fileContents) as PresetsConfig
|
|
59
|
-
|
|
60
|
-
if (!data || !data.presets || !Array.isArray(data.presets)) {
|
|
61
|
-
throw new Error('Invalid presets.yaml structure')
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return data
|
|
65
|
-
} catch (error) {
|
|
66
|
-
console.error('\x1b[31mError loading presets:\x1b[0m', error)
|
|
67
|
-
throw error
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Find a preset by its ID
|
|
73
|
-
* @param presetId - The preset identifier
|
|
74
|
-
* @returns The preset configuration or undefined
|
|
75
|
-
*/
|
|
76
|
-
export function findPreset(presetId: string): Preset | undefined {
|
|
77
|
-
const config = loadPresets()
|
|
78
|
-
return config.presets.find((p) => p.id === presetId)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* List all available presets with their descriptions
|
|
83
|
-
*/
|
|
84
|
-
export function listPresets(): void {
|
|
85
|
-
const config = loadPresets()
|
|
86
|
-
|
|
87
|
-
console.log('')
|
|
88
|
-
console.log(COLOR.heading('Available Presets:'))
|
|
89
|
-
console.log('')
|
|
90
|
-
|
|
91
|
-
config.presets.forEach((preset) => {
|
|
92
|
-
console.log(` ${preset.logo.icon} ${COLOR.bold(preset.id)}`)
|
|
93
|
-
console.log(` ${preset.name} - ${preset.subtitle}`)
|
|
94
|
-
|
|
95
|
-
// Remove HTML tags from description for console output
|
|
96
|
-
const cleanDesc = preset.description.en
|
|
97
|
-
.replace(/<[^>]*>/g, '')
|
|
98
|
-
.replace(/\s+/g, ' ')
|
|
99
|
-
.trim()
|
|
100
|
-
|
|
101
|
-
console.log(` ${COLOR.italic(cleanDesc)}`)
|
|
102
|
-
console.log('')
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
console.log('\nUsage:')
|
|
106
|
-
console.log(
|
|
107
|
-
COLOR.italic(
|
|
108
|
-
' liaex -i <input.md> -f presets --<preset-id> [-o <output>]',
|
|
109
|
-
),
|
|
110
|
-
)
|
|
111
|
-
console.log(
|
|
112
|
-
COLOR.italic(
|
|
113
|
-
' liaex -i <input.md> -f presets --<preset-id> [--scorm-organization "..."] [-o <output>]\n',
|
|
114
|
-
),
|
|
115
|
-
)
|
|
116
|
-
console.log('Tip: Add format-specific flags to override preset defaults.\n')
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Display configuration parameters for a specific preset
|
|
121
|
-
* @param presetId - The preset identifier
|
|
122
|
-
*/
|
|
123
|
-
export function showPresetConfig(presetId: string): void {
|
|
124
|
-
const preset = findPreset(presetId)
|
|
125
|
-
|
|
126
|
-
if (!preset) {
|
|
127
|
-
console.error(`\x1b[31mPreset '${presetId}' not found.\x1b[0m`)
|
|
128
|
-
console.log(
|
|
129
|
-
'\nRun ' +
|
|
130
|
-
COLOR.italic('liaex -f presets') +
|
|
131
|
-
' to see all available presets.\n',
|
|
132
|
-
)
|
|
133
|
-
process.exit(1)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
console.log('')
|
|
137
|
-
console.log(
|
|
138
|
-
`${preset.logo} ${COLOR.heading(preset.name)} - ${preset.subtitle}`,
|
|
139
|
-
)
|
|
140
|
-
console.log('')
|
|
141
|
-
|
|
142
|
-
// Remove HTML tags from description
|
|
143
|
-
const cleanDesc = preset.description
|
|
144
|
-
.replace(/<[^>]*>/g, '')
|
|
145
|
-
.replace(/\s+/g, ' ')
|
|
146
|
-
.trim()
|
|
147
|
-
|
|
148
|
-
console.log(COLOR.italic(cleanDesc))
|
|
149
|
-
console.log('')
|
|
150
|
-
console.log(COLOR.bold('Configuration Parameters:'))
|
|
151
|
-
console.log('')
|
|
152
|
-
|
|
153
|
-
Object.entries(preset.options).forEach(([key, value]) => {
|
|
154
|
-
const displayValue =
|
|
155
|
-
typeof value === 'string' ? (value === '' ? '""' : value) : String(value)
|
|
156
|
-
console.log(` ${COLOR.bold(key)}: ${displayValue}`)
|
|
157
|
-
})
|
|
158
|
-
|
|
159
|
-
console.log('')
|
|
160
|
-
console.log('Usage:')
|
|
161
|
-
console.log(
|
|
162
|
-
COLOR.italic(
|
|
163
|
-
` liaex -i <input.md> -f presets --${presetId} [-o <output>]`,
|
|
164
|
-
),
|
|
165
|
-
)
|
|
166
|
-
console.log('')
|
|
167
|
-
console.log(COLOR.bold('Override Parameters:'))
|
|
168
|
-
console.log(
|
|
169
|
-
' You can override any parameter by adding the corresponding flag:',
|
|
170
|
-
)
|
|
171
|
-
console.log(
|
|
172
|
-
COLOR.italic(
|
|
173
|
-
` liaex -i <input.md> -f presets --${presetId} --scorm-organization "Custom" -o output`,
|
|
174
|
-
),
|
|
175
|
-
)
|
|
176
|
-
console.log('')
|
|
177
|
-
console.log(
|
|
178
|
-
' Available override flags: --scorm-organization, --scorm-masteryScore,',
|
|
179
|
-
)
|
|
180
|
-
console.log(
|
|
181
|
-
' --scorm-typicalDuration, --scorm-iframe, --scorm-embed, and more.\n',
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Get preset options merged with command-line arguments
|
|
187
|
-
* @param presetId - The preset identifier
|
|
188
|
-
* @param cliArgs - Command-line arguments to override preset values
|
|
189
|
-
* @returns Merged configuration
|
|
190
|
-
*/
|
|
191
|
-
export function getPresetOptions(presetId: string, cliArgs: any): any {
|
|
192
|
-
const preset = findPreset(presetId)
|
|
193
|
-
|
|
194
|
-
if (!preset) {
|
|
195
|
-
console.error(`\x1b[31mPreset '${presetId}' not found.\x1b[0m`)
|
|
196
|
-
process.exit(1)
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Map preset options to CLI argument format
|
|
200
|
-
const presetArgs: any = {
|
|
201
|
-
format: preset.options.format || preset.format,
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Map common options
|
|
205
|
-
if (preset.options.scormOrganization !== undefined) {
|
|
206
|
-
presetArgs['scorm-organization'] = preset.options.scormOrganization
|
|
207
|
-
}
|
|
208
|
-
if (preset.options.typicalDuration !== undefined) {
|
|
209
|
-
presetArgs['scorm-typicalDuration'] = preset.options.typicalDuration
|
|
210
|
-
}
|
|
211
|
-
if (preset.options.scormIframe !== undefined) {
|
|
212
|
-
presetArgs['scorm-iframe'] = preset.options.scormIframe
|
|
213
|
-
}
|
|
214
|
-
if (preset.options.scormEmbed !== undefined) {
|
|
215
|
-
presetArgs['scorm-embed'] = preset.options.scormEmbed
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Merge with CLI args, CLI args take precedence
|
|
219
|
-
return { ...presetArgs, ...cliArgs }
|
|
220
|
-
}
|