@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.
Files changed (72) hide show
  1. package/dist/assets/capacitor/{index.bfe7363b.js → index.a7f021f7.js} +1 -1
  2. package/dist/assets/capacitor/index.html +1 -1
  3. package/dist/assets/capacitor/{jszip.min.f6eda75b.js → jszip.min.43389eb1.js} +1 -1
  4. package/dist/assets/capacitor/{trystero-ipfs.min.b27a61d7.js → trystero-ipfs.min.f25fe3e7.js} +1 -1
  5. package/dist/assets/indexeddb/{index.599a57d6.js → index.4aceca2f.js} +1 -1
  6. package/dist/assets/indexeddb/index.html +1 -1
  7. package/dist/assets/indexeddb/{jszip.min.63142cc8.js → jszip.min.4fbcc13f.js} +1 -1
  8. package/dist/assets/scorm2004/{index.7a5820ab.js → index.33bec53a.js} +1 -1
  9. package/dist/assets/scorm2004/index.html +1 -1
  10. package/dist/assets/scorm2004/{jszip.min.63142cc8.js → jszip.min.4fbcc13f.js} +1 -1
  11. package/dist/assets/xapi/{index.018a032a.js → index.f2e89e49.js} +1 -1
  12. package/dist/assets/xapi/index.html +1 -1
  13. package/dist/assets/xapi/{jszip.min.eaecf580.js → jszip.min.19c66d77.js} +1 -1
  14. package/dist/index.js +47 -47
  15. package/dist/server/presets.json +94 -0
  16. package/dist/server/presets.yaml +120 -0
  17. package/dist/server/public/app.js +1 -0
  18. package/dist/server/public/assets/android.svg +38 -0
  19. package/dist/server/public/assets/cmi.svg +154 -0
  20. package/dist/server/public/assets/docx.svg +20 -0
  21. package/dist/server/public/assets/edX.svg +75 -0
  22. package/dist/server/public/assets/edx.svg +75 -0
  23. package/dist/server/public/assets/epub.svg +18 -0
  24. package/dist/server/public/assets/icon.svg +82 -0
  25. package/dist/server/public/assets/ilias.png +0 -0
  26. package/dist/server/public/assets/json.svg +4 -0
  27. package/dist/server/public/assets/learnworlds.png +0 -0
  28. package/dist/server/public/assets/moodle.svg +190 -0
  29. package/dist/server/public/assets/opal.png +0 -0
  30. package/dist/server/public/assets/openolat.png +0 -0
  31. package/dist/server/public/assets/pdf.svg +4 -0
  32. package/dist/server/public/assets/rdf.svg +4 -0
  33. package/dist/server/public/assets/scorm.png +0 -0
  34. package/dist/server/public/assets/web.png +0 -0
  35. package/dist/server/public/assets/xapi.png +0 -0
  36. package/dist/server/public/i18n.js +1 -0
  37. package/dist/server/public/index.html +1587 -0
  38. package/dist/server/public/locales/de.json +247 -0
  39. package/dist/server/public/locales/en.json +247 -0
  40. package/dist/server/public/status.html +251 -0
  41. package/dist/server/public/styles.css +712 -0
  42. package/package.json +5 -1
  43. package/.parcelrc +0 -3
  44. package/DESKTOP_APP_README.md +0 -58
  45. package/DOCKERHUB_DESCRIPTION.md +0 -52
  46. package/Dockerfile +0 -129
  47. package/PLAYSTORE_GUIDE.md +0 -172
  48. package/action.yml +0 -157
  49. package/custom.css +0 -10
  50. package/electron-builder.json +0 -149
  51. package/src/cli.ts +0 -69
  52. package/src/colorize.ts +0 -115
  53. package/src/export/android.ts +0 -419
  54. package/src/export/docx.ts +0 -1025
  55. package/src/export/epub.ts +0 -1306
  56. package/src/export/h5p.ts +0 -390
  57. package/src/export/helper.ts +0 -360
  58. package/src/export/ims.ts +0 -191
  59. package/src/export/pdf.ts +0 -406
  60. package/src/export/presets.ts +0 -220
  61. package/src/export/project.ts +0 -829
  62. package/src/export/rdf.ts +0 -551
  63. package/src/export/scorm12.ts +0 -167
  64. package/src/export/scorm2004.ts +0 -140
  65. package/src/export/web.ts +0 -306
  66. package/src/export/xapi.ts +0 -424
  67. package/src/exporter.ts +0 -296
  68. package/src/index.ts +0 -96
  69. package/src/parser.ts +0 -373
  70. package/src/presets.yaml +0 -219
  71. package/src/types.ts +0 -82
  72. 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
- }
@@ -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
- }