diff --git a/docz/docs/02-getting-started/01-installation/05-extendscript.md b/docz/docs/02-getting-started/01-installation/05-extendscript.md
index 2d7fd3f..63a02a1 100644
--- a/docz/docs/02-getting-started/01-installation/05-extendscript.md
+++ b/docz/docs/02-getting-started/01-installation/05-extendscript.md
@@ -22,6 +22,20 @@ After downloading the script, it can be directly referenced with `#include`:
#include "xlsx.extendscript.js"
```
-For local deployments, the scripts can be placed in the `Scripts` folder. For
-Photoshop CS6 on Windows 10, the path is typically
-`C:\Program Files\Adobe\Adobe Photoshop CS6 (64 Bit)\Presets\Scripts`
+For local deployments, the scripts can be placed in the `Scripts` folder. The
+path is application-specific.
+
+| App | Location |
+|:----------|:-----------------------------------------------------------------|
+| Photoshop | `\Presets\Scripts` within the Application folder |
+| InDesign | Windows > Utilities > Scripts, click `☰` > "Reveal in Explorer" |
+
+:::note CEP usage
+
+The ExtendScript build should be used when performing spreadsheet operations
+from the host context (within a `jsx` script file).
+
+[The standalone scripts](/docs/getting-started/installation/standalone) should
+be added to CEP extension HTML.
+
+:::
\ No newline at end of file
diff --git a/docz/docs/03-demos/10-extensions/01-extendscript.md b/docz/docs/03-demos/10-extensions/01-extendscript.md
index ec99b64..28193f3 100644
--- a/docz/docs/03-demos/10-extensions/01-extendscript.md
+++ b/docz/docs/03-demos/10-extensions/01-extendscript.md
@@ -1,5 +1,5 @@
---
-title: Photoshop and Creative Suite
+title: Photoshop and InDesign
pagination_prev: demos/cloud/index
pagination_next: demos/bigdata/index
---
@@ -21,10 +21,27 @@ This demo intends to cover parts relevant to SheetJS. General setup as well as
general Adobe considerations are not covered here. A basic familiarity with
extension development is assumed.
-## ExtendScript Scripts
+:::note
-[Installation is straightforward:](/docs/getting-started/installation/extendscript) download a
-script and move it to your project directory.
+This demo was verified in the following deployments:
+
+| App | Platform | Date |
+|:----------|:-------------|:-----------|
+| Photoshop | ExtendScript | 2023-04-15 |
+| InDesign | ExtendScript | 2023-04-15 |
+| InDesign | CEP | 2023-04-15 |
+| InDesign | UXP | 2023-04-15 |
+
+:::
+
+## ExtendScript
+
+[The "ExtendScript" build](/docs/getting-started/installation/extendscript) can
+be included from a script in the same directory:
+
+```js
+#include "xlsx.extendscript.js"
+```
### Reading Files
@@ -47,46 +64,20 @@ var workbook = XLSX.readFile(thisFile.absoluteURI);
Complete Example (click to hide)
+
+
+
In this example, the script will show a dialog to select a file. After reading
the file, the workbook Author property will be extracted and the Photoshop doc
author (`activeDocument.info.author`) will be changed accordingly.
-This demo was verified in Photoshop CS6 64-bit on Windows 10.
-
-```js
-#target photoshop
-#include "xlsx.extendscript.js";
-
-function main_parse() {
- /* Show File Picker */
- var thisFile = File.openDialog("Select a spreadsheet");
- if(!thisFile) { alert("File not found!"); return; }
-
- /* Read file from disk */
- var workbook = XLSX.readFile(thisFile.absoluteURI);
-
- /* Get Workbook Author */
- var Props = workbook.Props; if(!Props) { alert("Missing Author!"); return; }
- var Author = Props.Author; if(!Author) { alert("Missing Author!"); return; }
-
- /* Change Document Author to Workbook Author */
- var info = activeDocument.info;
- alert("Changing Author from |" + info.author + "| to |" + Author + "|");
- info.author = Author;
-}
-
-main_parse();
-```
-
0) Download the [test workbook](pathname:///files/SheetJS.xlsb).
1) Download the following scripts:
- [`xlsx.extendscript.js`](https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.extendscript.js)
-- [`parse.jsx`](pathname:///live/parse.jsx)
+- [`parse.jsx`](pathname:///extendscript/parse.jsx)
-and place in the scripts directory. For CS6 Windows 10 the path is typically
-
-`C:\Program Files\Adobe\Adobe Photoshop CS6 (64 Bit)\Presets\Scripts`
+and place in the scripts directory.
2) Restart Photoshop and open a file (or create a new one)
@@ -96,7 +87,40 @@ and place in the scripts directory. For CS6 Windows 10 the path is typically
!["Changing Author" popup](pathname:///files/psparse.png)
-5) File > File Info... should show the updated Author field!
+5) Check the Author field of the document in File > File Info...
+
+
+
+
+In this example, the script will show a dialog to select a file. After reading
+the file, the script will store data in the document:
+
+- The first Text object in the "Title" TextFrame (the name of the TextFrame in
+the Layers window is "Title") will be set to the name of the first worksheet.
+
+- The data from the first sheet will be added to the "Table Frame" TextFrame.
+
+0) Download the [test workbook](https://sheetjs.com/pres.xlsx) and
+[InDesign template](pathname:///extendscript/Template.indd)
+
+1) Download the following scripts:
+- [`xlsx.extendscript.js`](https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.extendscript.js)
+- [`esidparse.jsx`](pathname:///extendscript/esidparse.jsx)
+
+Move to the scripts directory. To find the directory, activate Scripts panel
+(Windows > Utilities > Scripts), click `☰`, and select "Reveal in Explorer".
+
+2) Open the template
+
+3) Activate the Scripts panel. Expand the "User" folder and double-click
+`esidparse` in the list.
+
+4) In the "Select a spreadsheet" file picker, select the test file `pres.xlsx`
+
+A new table will be added and the title will be the name of the first worksheet.
+
+
+
@@ -121,46 +145,19 @@ XLSX.writeFile(workbook, thisFile.absoluteURI);
Complete Example (click to hide)
+
+
+
In this example, the script will show a dialog to select an output file. Once
selected, the library will create a new workbook with one worksheet. Cell `A1`
will be "Author" and cell `B1` will be the active Photoshop document Author.
The PS author is available as `activeDocument.info.author`.
-This demo was verified in Photoshop CS6 64-bit on Windows 10.
-
-```js
-#target photoshop
-#include "xlsx.extendscript.js";
-
-function main_write() {
- /* Show File Picker */
- var thisFile = File.saveDialog("Select an output file", "*.xlsx;*.xls");
- if(!thisFile) { alert("File not found!"); return; }
-
- /* Create new Worksheet */
- var ws = XLSX.utils.aoa_to_sheet([
- ["Author", activeDocument.info.author]
- ]);
-
- /* Create new Workbook and add worksheet */
- var wb = XLSX.utils.book_new();
- XLSX.utils.book_append_sheet(wb, ws, "Sheet1");
-
- /* Write file to disk */
- XLSX.writeFile(wb, thisFile.absoluteURI);
- alert("Created File " + thisFile.absoluteURI);
-}
-
-main_write();
-```
-
1) Download the following scripts:
- [`xlsx.extendscript.js`](https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.extendscript.js)
-- [`write.jsx`](pathname:///live/write.jsx)
+- [`write.jsx`](pathname:///extendscript/write.jsx)
-and place in the scripts directory. For CS6 Windows 10 the path is typically
-
-`C:\Program Files\Adobe\Adobe Photoshop CS6 (64 Bit)\Presets\Scripts`
+and place in the scripts directory.
2) Restart Photoshop and open a file (or create a new one)
@@ -169,21 +166,129 @@ and place in the scripts directory. For CS6 Windows 10 the path is typically
4) File > Scripts > write and use the popup to select the Documents folder.
Enter `SheetJSPSTest.xlsx` and press "Save"
-4) An alert will confirm that the file was created:
+5) An alert will confirm that the file was created:
!["Created File" popup](pathname:///files/pswrite.png)
-5) Open the generated `SheetJSPSTest.xlsx` file and compare to Photoshop author
+6) Open the generated `SheetJSPSTest.xlsx` file and compare to Photoshop author
+
+
+
+
+In this example, the script will show a dialog to select an output file. Once
+selected, the library will scan all text frames for table objects. Each table
+object will be scanned and a new worksheet will be created.
+
+0) Download the [InDesign document](pathname:///extendscript/Filled.indd)
+
+1) Download the following scripts:
+- [`xlsx.extendscript.js`](https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.extendscript.js)
+- [`esidwrite.jsx`](pathname:///extendscript/esidwrite.jsx)
+
+Move to the scripts directory. To find the directory, activate Scripts panel
+(Windows > Utilities > Scripts), click `☰`, and select "Reveal in Explorer".
+
+2) Open the document.
+
+3) Activate the Scripts panel. Expand the "User" folder and double-click
+`esidwrite` in the list. Use the popup to select the Documents folder. Enter
+`SheetJSIDTest.xlsx` and press "Save"
+
+4) An alert will confirm that the file was created. Open `SheetJSIDTest.xlsx`
+and compare to the InDesign doc.
+
+
+
## CEP
-[The standalone scripts](/docs/getting-started/installation/standalone) can be added to CEP
-extension HTML
+[The standalone scripts](/docs/getting-started/installation/standalone) can be
+added to CEP extension HTML. It should be downloaded from the CDN and included
+in the extension.
+
+For performing file operations in CEP extensions, NodeJS is not required! The
+manifest must include the following flags to enable `cep.fs`:
+
+```xml
+
+ --allow-file-access
+ --allow-file-access-from-files
+
+```
+
+The Base64 encoding is compatible with `type: "base64"`.
+
+**Reading Files**
+
+The typical flow is to read data from CEP and pass the data into the host
+ExtendScript context. The following snippet parses a workbook:
+
+```js
+/* show file picker (single file, no folders) */
+const fn = cep.fs.showOpenDialogEx(false, false, "Select File", "", ["xlsx"]);
+/* read data as Base64 string */
+const data = cep.fs.readFile(fn.data[0], cep.encoding.Base64);
+/* parse with SheetJS */
+const wb = XLSX.read(data.data, { type: "base64" });
+```
+
+**Writing Files**
+
+The typical flow is to invoke a function with `CSInterface#evalScript` that
+returns data from the host ExtendScript context. The callback should build the
+workbook and initiate a file save. The following snippet saves a workbook:
+
+```js
+/* generate XLSX as base64 string */
+const b64 = XLSX.write(wb, {type:"base64", bookType: "xlsx"})
+/* show file picker */
+const fn = cep.fs.showSaveDialogEx("Save File","",["xlsx"],"SheetJSIDCEP.xlsx");
+/* write file */
+cep.fs.writeFile(fn.data, b64, cep.encoding.Base64);
+```
## UXP
-UXP officially recommends `require` and NodeJS Modules for third party support.
+UXP uses bundled scripts with `.psjs` (PS) or `.idjs` (InDesign) extension. The
+official samples use `webpack` to build bundles.
-[Use the "Frameworks" instructions to download.](/docs/getting-started/installation/frameworks)
+[The "Frameworks" instructions](/docs/getting-started/installation/frameworks)
+describe installation steps for traditional `webpack` projects.
+
+Filesystem access is provided by the UXP storage module:
+
+```js
+const storage = require("uxp").storage;
+const ufs = storage.localFileSystem;
+```
+
+**Reading Files**
+
+The `getFileForOpening` method resolves to a `File` object. Reading the file
+with the `binary` format returns an `ArrayBuffer` object that can be parsed:
+
+```js
+/* show file picker (single file, no folders) */
+const file = await ufs.getFileForOpening({ types: ["xlsx", "xls", "xlsb"] });
+/* read data into an ArrayBuffer */
+const ab = await file.read({ format: storage.formats.binary });
+/* parse with SheetJS */
+const wb = XLSX.read(ab);
+```
+
+**Writing Files**
+
+The `getFileForSaving` method resolves to a `File` object. The workbook should
+be written with `type: "buffer"` for compatibility with the `binary` format:
+
+
+```js
+/* generate XLSX with type: "buffer" */
+const buf = XLSX.write(wb, { type: "buffer", bookType: "xlsx" });
+/* show file picker */
+const file = await ufs.getFileForSaving("SheetJSUXP.xlsx");
+/* write data */
+await file.write(buf, { data: storage.formats.binary });
+```
diff --git a/docz/static/extendscript/esidparse.jsx b/docz/static/extendscript/esidparse.jsx
new file mode 100644
index 0000000..8fb2802
--- /dev/null
+++ b/docz/static/extendscript/esidparse.jsx
@@ -0,0 +1,35 @@
+#include "xlsx.extendscript.js";
+
+function main_parse() {
+ /* Show File Picker */
+ var thisFile = File.openDialog("Select a spreadsheet");
+ if(!thisFile) { alert("File not found!"); return; }
+
+ /* Read file from disk */
+ var workbook = XLSX.readFile(thisFile.absoluteURI);
+ var wsname = workbook.SheetNames[0];
+ var data = XLSX.utils.sheet_to_json(workbook.Sheets[wsname], { header: 1, raw: false });
+
+ /* Set title */
+ app.activeDocument.textFrames.itemByName("Title").texts[0].contents = wsname;
+
+ /* Set table */
+ var tabeller = app.activeDocument.textFrames.itemByName("Table Frame");
+ var columns = data[0].length;
+ for(var R = 0; R < data.length; ++R) columns = Math.max(columns, data[R].length);
+ var table = tabeller.tables.add({
+ headerRowCount: 1,
+ bodyRowCount: data.length - 1,
+ columnCount: columns
+ });
+ for(R = 0; R < data.length; ++R) {
+ if(data[R] == null) continue;
+ for(var C = 0; C < data[R].length; ++C) {
+ if(data[R][C] == null) continue;
+ table.rows.item(R).cells.item(C).contents = data[R][C];
+ }
+ }
+
+}
+
+main_parse();
\ No newline at end of file
diff --git a/docz/static/extendscript/esidwrite.jsx b/docz/static/extendscript/esidwrite.jsx
new file mode 100644
index 0000000..28cc0fd
--- /dev/null
+++ b/docz/static/extendscript/esidwrite.jsx
@@ -0,0 +1,48 @@
+#include "xlsx.extendscript.js";
+
+function workbook_add_table(wb, table) {
+ /* Collect Data */
+ var data = [];
+ var cnt = table.rows.count();
+ for(var R = 0; R < cnt; ++R) {
+ var row = table.rows.item(R);
+ data[R] = [];
+ var ccnt = row.cells.count();
+ for(var C = 0; C < ccnt; ++C) {
+ var value = row.cells.item(C).contents;
+ data[R][C] = value;
+ }
+ }
+
+ if(data.length == 0) return;
+
+ /* Create Worksheet */
+ var ws = XLSX.utils.aoa_to_sheet(data);
+
+ /* Create new Workbook and add worksheet */
+ XLSX.utils.book_append_sheet(wb, ws);
+}
+
+function main_write() {
+ /* Show File Picker */
+ var thisFile = File.saveDialog("Select an output file", "*.xlsx;*.xls");
+ if(!thisFile) { alert("File not found!"); return; }
+
+ /* Create new Workbook */
+ var wb = XLSX.utils.book_new();
+
+ /* Find all tables and add them to workbook */
+ var tfcnt = app.activeDocument.textFrames.count();
+ for(var i = 0; i < tfcnt; ++i) {
+ var tf = app.activeDocument.textFrames.item(i);
+ var tcnt = tf.tables.count();
+ if(tcnt == 0) continue;
+ for(var j = 0; j < tcnt; ++j) workbook_add_table(wb, tf.tables.item(j));
+ }
+
+ /* Write file to disk */
+ XLSX.writeFile(wb, thisFile.absoluteURI);
+ alert("Created File " + thisFile.absoluteURI);
+}
+
+main_write();
\ No newline at end of file
diff --git a/docz/static/live/parse.jsx b/docz/static/extendscript/parse.jsx
similarity index 100%
rename from docz/static/live/parse.jsx
rename to docz/static/extendscript/parse.jsx
diff --git a/docz/static/live/write.jsx b/docz/static/extendscript/write.jsx
similarity index 100%
rename from docz/static/live/write.jsx
rename to docz/static/extendscript/write.jsx