@mulmocast/slide 0.1.0

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 (47) hide show
  1. package/README.md +458 -0
  2. package/lib/actions/bundle.d.ts +3 -0
  3. package/lib/actions/bundle.d.ts.map +1 -0
  4. package/lib/actions/bundle.js +60 -0
  5. package/lib/actions/bundle.js.map +1 -0
  6. package/lib/actions/common.d.ts +21 -0
  7. package/lib/actions/common.d.ts.map +1 -0
  8. package/lib/actions/common.js +159 -0
  9. package/lib/actions/common.js.map +1 -0
  10. package/lib/actions/movie.d.ts +3 -0
  11. package/lib/actions/movie.d.ts.map +1 -0
  12. package/lib/actions/movie.js +58 -0
  13. package/lib/actions/movie.js.map +1 -0
  14. package/lib/actions/upload.d.ts +6 -0
  15. package/lib/actions/upload.d.ts.map +1 -0
  16. package/lib/actions/upload.js +172 -0
  17. package/lib/actions/upload.js.map +1 -0
  18. package/lib/cli.d.ts +3 -0
  19. package/lib/cli.d.ts.map +1 -0
  20. package/lib/cli.js +301 -0
  21. package/lib/cli.js.map +1 -0
  22. package/lib/convert/marp.d.ts +22 -0
  23. package/lib/convert/marp.d.ts.map +1 -0
  24. package/lib/convert/marp.js +375 -0
  25. package/lib/convert/marp.js.map +1 -0
  26. package/lib/convert/pdf.d.ts +14 -0
  27. package/lib/convert/pdf.d.ts.map +1 -0
  28. package/lib/convert/pdf.js +130 -0
  29. package/lib/convert/pdf.js.map +1 -0
  30. package/lib/convert/pptx.d.ts +13 -0
  31. package/lib/convert/pptx.d.ts.map +1 -0
  32. package/lib/convert/pptx.js +138 -0
  33. package/lib/convert/pptx.js.map +1 -0
  34. package/lib/utils/lang.d.ts +16 -0
  35. package/lib/utils/lang.d.ts.map +1 -0
  36. package/lib/utils/lang.js +37 -0
  37. package/lib/utils/lang.js.map +1 -0
  38. package/lib/utils/llm.d.ts +21 -0
  39. package/lib/utils/llm.d.ts.map +1 -0
  40. package/lib/utils/llm.js +200 -0
  41. package/lib/utils/llm.js.map +1 -0
  42. package/lib/utils/pdf.d.ts +37 -0
  43. package/lib/utils/pdf.d.ts.map +1 -0
  44. package/lib/utils/pdf.js +142 -0
  45. package/lib/utils/pdf.js.map +1 -0
  46. package/package.json +67 -0
  47. package/tools/keynote/extract.scpt +195 -0
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@mulmocast/slide",
3
+ "version": "0.1.0",
4
+ "description": "Convert presentations (Keynote, PowerPoint, PDF, Marp) to MulmoScript format",
5
+ "homepage": "https://github.com/receptron/MulmoCast-Slides#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/receptron/MulmoCast-Slides/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/receptron/MulmoCast-Slides.git"
12
+ },
13
+ "license": "MIT",
14
+ "author": "receptron",
15
+ "type": "commonjs",
16
+ "main": "lib/cli.js",
17
+ "bin": {
18
+ "mulmo-slide": "./lib/cli.js"
19
+ },
20
+ "files": [
21
+ "lib",
22
+ "tools"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "test": "tsx --test ./tests/test_*.ts",
27
+ "lint": "eslint src/",
28
+ "lint:fix": "eslint src/ --fix",
29
+ "format": "prettier --write src/",
30
+ "cli": "tsx src/cli.ts",
31
+ "keynote": "tsx src/cli.ts keynote",
32
+ "pptx": "tsx src/cli.ts pptx",
33
+ "pdf": "tsx src/cli.ts pdf",
34
+ "marp": "tsx src/cli.ts marp",
35
+ "movie": "tsx src/cli.ts movie",
36
+ "bundle": "tsx src/cli.ts bundle",
37
+ "upload": "tsx src/cli.ts upload",
38
+ "test:keynote": "tsx src/cli.ts keynote samples/GraphAI.key",
39
+ "test:marp": "tsx src/cli.ts marp samples/sample.md",
40
+ "test:marp:theme": "tsx src/cli.ts marp samples/custom_theme_demo.md --theme samples/custom-ocean.css"
41
+ },
42
+ "dependencies": {
43
+ "@marp-team/marp-cli": "^4.0.0",
44
+ "dotenv": "^17.2.3",
45
+ "mulmocast": "^2.1.16",
46
+ "node-pptx-parser": "^1.0.1",
47
+ "openai": "^6.15.0",
48
+ "pdf-parse": "^2.4.5",
49
+ "ppt-png": "^2.2.0",
50
+ "tsx": "^4.7.0",
51
+ "yargs": "^18.0.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^25.0.3",
55
+ "@types/yargs": "^17.0.35",
56
+ "@typescript-eslint/eslint-plugin": "^8.51.0",
57
+ "@typescript-eslint/parser": "^8.51.0",
58
+ "eslint": "^9.39.2",
59
+ "eslint-config-prettier": "^10.1.8",
60
+ "eslint-plugin-prettier": "^5.5.4",
61
+ "prettier": "^3.7.4",
62
+ "typescript": "^5.9.3"
63
+ },
64
+ "resolutions": {
65
+ "unicorn-magic": "0.2.0"
66
+ }
67
+ }
@@ -0,0 +1,195 @@
1
+ -- Keynote Slides to MulmoScript Exporter
2
+ -- This script exports each slide of a Keynote presentation as an image
3
+ -- then, generate a MulmoScript using speaker note of each slide as text.
4
+ -- Usage: yarn keynote [path/to/presentation.key] [-l lang]
5
+ -- Supported languages: en, ja, fr, de (default: en)
6
+ -- Can also set MULMO_LANG environment variable
7
+
8
+ on run argv
9
+ -- Default language
10
+ set scriptLang to "en"
11
+ set inputPath to ""
12
+
13
+ -- Parse arguments
14
+ set i to 1
15
+ repeat while i ≤ (count of argv)
16
+ set currentArg to item i of argv
17
+ if currentArg is "-l" or currentArg is "--lang" then
18
+ if i + 1 ≤ (count of argv) then
19
+ set scriptLang to item (i + 1) of argv
20
+ set i to i + 2
21
+ else
22
+ set i to i + 1
23
+ end if
24
+ else if inputPath is "" then
25
+ set inputPath to currentArg
26
+ set i to i + 1
27
+ else
28
+ set i to i + 1
29
+ end if
30
+ end repeat
31
+
32
+ -- Check environment variable if lang not set via CLI
33
+ if scriptLang is "en" then
34
+ try
35
+ set envLang to do shell script "echo $MULMO_LANG"
36
+ if envLang is not "" then
37
+ set scriptLang to envLang
38
+ end if
39
+ end try
40
+ end if
41
+
42
+ -- Validate language
43
+ if scriptLang is not in {"en", "ja", "fr", "de"} then
44
+ display dialog "Invalid language: " & scriptLang & ". Using 'en' as default." buttons {"OK"} default button "OK"
45
+ set scriptLang to "en"
46
+ end if
47
+
48
+ -- Check if a file path was provided
49
+ if inputPath is not "" then
50
+
51
+ -- Convert relative path to absolute path using shell
52
+ set absolutePath to do shell script "cd \"$(dirname " & quoted form of inputPath & ")\"; echo \"$PWD/$(basename " & quoted form of inputPath & ")\""
53
+
54
+ -- Convert POSIX path to file reference
55
+ set keynoteFile to POSIX file absolutePath as alias
56
+ else
57
+ -- Ask user to select a Keynote file if no argument provided
58
+ set keynoteFile to choose file with prompt "Select a Keynote file:" of type {"com.apple.iwork.keynote.sffkey", "com.apple.iwork.keynote.key"}
59
+ end if
60
+
61
+ -- Get the file path and extract folder/filename info
62
+ set filePosixPath to POSIX path of keynoteFile
63
+
64
+ -- Extract basename (filename without extension)
65
+ set fileBasename to do shell script "basename " & quoted form of filePosixPath & " .key"
66
+
67
+ -- Get current working directory
68
+ set currentDirectory to do shell script "pwd"
69
+
70
+ -- Create output folder paths in scripts/<basename>/ directory
71
+ set outputFolder to currentDirectory & "/scripts/" & fileBasename
72
+ set outputImagesFolder to outputFolder & "/images"
73
+ set outputScriptFile to outputFolder & "/mulmo_script.json"
74
+
75
+ -- Create the output folders if they don't exist
76
+ do shell script "mkdir -p " & quoted form of outputImagesFolder
77
+
78
+ -- Remove all existing PNG files from the images folder
79
+ do shell script "rm -f " & quoted form of outputImagesFolder & "/*.png"
80
+
81
+ -- Open and export from Keynote
82
+ tell application "Keynote"
83
+ activate
84
+
85
+ -- Open the presentation
86
+ open keynoteFile
87
+
88
+ -- Wait for the document to open
89
+ delay 1
90
+
91
+ -- Get reference to the front document
92
+ set theDocument to front document
93
+
94
+ -- Get the number of slides
95
+ set slideCount to count of slides of theDocument
96
+
97
+ -- Collect speaker notes from all slides
98
+ set allNotes to {}
99
+ repeat with i from 1 to slideCount
100
+ set currentSlide to slide i of theDocument
101
+ set speakerNotes to presenter notes of currentSlide
102
+ set end of allNotes to speakerNotes
103
+ end repeat
104
+
105
+ -- Export all slides as images to the images folder
106
+ -- Keynote will create numbered image files automatically
107
+ export theDocument to POSIX file outputImagesFolder as slide images with properties {image format:PNG, compression factor:1.0}
108
+
109
+ -- Close the document without saving
110
+ close theDocument saving no
111
+ end tell
112
+
113
+ -- Clean up hidden characters from exported filenames and rename to match PPTX format
114
+ -- Remove carriage returns and Left-to-Right Mark (U+200E) characters
115
+ -- Also rename from images.001.png to <basename>-0.png format
116
+ -- Issue: https://discussions.apple.com/thread/255014422?sortBy=rank
117
+ do shell script "cd " & quoted form of outputImagesFolder & " && python3 << 'PYEOF'
118
+ import os
119
+ import re
120
+
121
+ basename = '" & fileBasename & "'
122
+
123
+ for filename in os.listdir('.'):
124
+ if os.path.isfile(filename) and filename.endswith('.png'):
125
+ # Clean hidden characters
126
+ clean_name = filename.replace('\\u200e', '').replace('\\r', '')
127
+
128
+ # Extract slide number from images.XXX.png format
129
+ match = re.match(r'.*\\.([0-9]+)\\.png$', clean_name)
130
+ if match:
131
+ slide_num = int(match.group(1)) - 1 # Convert to 0-indexed
132
+ new_name = f'{basename}-{slide_num}.png'
133
+ if filename != new_name:
134
+ os.rename(filename, new_name)
135
+ elif filename != clean_name:
136
+ os.rename(filename, clean_name)
137
+ PYEOF"
138
+
139
+ -- Create JSON file with beats
140
+ -- First, write notes to a temporary file
141
+ set tempFile to outputFolder & "/.temp_notes.txt"
142
+ set AppleScript's text item delimiters to (ASCII character 30) -- Use ASCII Record Separator as delimiter
143
+ set notesText to allNotes as text
144
+ set AppleScript's text item delimiters to ""
145
+ do shell script "printf '%s' " & quoted form of notesText & " > " & quoted form of tempFile
146
+
147
+ -- Then use Python to create JSON from the temp file with relative paths
148
+ do shell script "python3 << 'PYEOF'
149
+ import json
150
+
151
+ basename = '" & fileBasename & "'
152
+
153
+ # Read notes from temp file
154
+ with open('" & tempFile & "', 'r') as f:
155
+ content = f.read()
156
+
157
+ # Split by ASCII Record Separator (character 30)
158
+ notes = content.split(chr(30)) if content else []
159
+
160
+ # Create beats array with relative image paths (in images/ subdirectory)
161
+ beats = []
162
+ for i, note in enumerate(notes):
163
+ image_filename = f'./images/{basename}-{i}.png'
164
+ beats.append({
165
+ 'text': note,
166
+ 'image': {
167
+ 'type': 'image',
168
+ 'source': {
169
+ 'kind': 'path',
170
+ 'path': image_filename
171
+ }
172
+ }
173
+ })
174
+
175
+ # Create MulmoScript object with metadata
176
+ mulmocast = {
177
+ '$mulmocast': {
178
+ 'version': '1.1',
179
+ 'credit': 'closing'
180
+ },
181
+ 'lang': '" & scriptLang & "',
182
+ 'beats': beats
183
+ }
184
+
185
+ # Write JSON file
186
+ with open('" & outputScriptFile & "', 'w') as f:
187
+ json.dump(mulmocast, f, indent=2, ensure_ascii=False)
188
+ PYEOF"
189
+
190
+ -- Clean up temp file
191
+ do shell script "rm -f " & quoted form of tempFile
192
+
193
+ -- Export completed silently
194
+
195
+ end run