forked from sheetjs/docs.sheetjs.com
osa
This commit is contained in:
parent
5ff93dc4b7
commit
e197ed24c8
@ -64,12 +64,12 @@ This data loader returns Base64 strings:
|
||||
```ts title="src/env.d.ts"
|
||||
/// <reference types="astro/client" />
|
||||
declare module '*.numbers' {
|
||||
const data: string;
|
||||
export default data;
|
||||
const data: string;
|
||||
export default data;
|
||||
}
|
||||
declare module '*.xlsx' {
|
||||
const data: string;
|
||||
export default data;
|
||||
const data: string;
|
||||
export default data;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -183,10 +183,10 @@ The following lines must be added to `ios/App/App/Info.plist`:
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<!-- highlight-start -->
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<!-- highlight-end -->
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
```
|
||||
|
@ -77,7 +77,7 @@ function SheetJSAlaSQL() {
|
||||
if(typeof alasql=="undefined") return setRows([{Nom:"alasql undefined"}]);
|
||||
const blob = await (await fetch(url)).blob();
|
||||
const data = URL.createObjectURL(blob);
|
||||
const res = await alasql.promise(q1,[data]);
|
||||
const res = await alasql.promise(q1,[data]);
|
||||
setRows(res);
|
||||
await alasql.promise(q2, [res]);
|
||||
}, []);
|
||||
|
247
docz/docs/03-demos/10-extensions/05-osa.md
Normal file
247
docz/docs/03-demos/10-extensions/05-osa.md
Normal file
@ -0,0 +1,247 @@
|
||||
---
|
||||
title: AppleScript and OSA
|
||||
pagination_prev: demos/cloud/index
|
||||
pagination_next: demos/bigdata/index
|
||||
---
|
||||
|
||||
Open Scripting Architecture (OSA), a built-in feature in macOS introduced in
|
||||
1993, enables users to communicate with applications with a standardized
|
||||
language and grammar. macOS releases starting from Yosemite (OSX 10.10) include
|
||||
native support for scripting with JavaScript.
|
||||
|
||||
The [Standalone scripts](/docs/getting-started/installation/standalone) can be
|
||||
parsed and evaluated from the JS engine. Once evaluated, the `XLSX` variable is
|
||||
available as a global. A JS stub can expose methods from AppleScript scripts.
|
||||
|
||||
:::note
|
||||
|
||||
This demo was last tested on 2022 April 18 in macOS Monterey.
|
||||
|
||||
:::
|
||||
|
||||
## Integration details
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs groupId="osa">
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
The following snippet reads a file into a binary string:
|
||||
|
||||
```js
|
||||
ObjC.import("Foundation");
|
||||
function get_bstr(path) {
|
||||
/* create NSString from the file contents using a binary encoding */
|
||||
var str = $.NSString.stringWithContentsOfFileEncodingError(path, $.NSISOLatin1StringEncoding, null);
|
||||
/* return the value as a JS object */
|
||||
return ObjC.unwrap(str);
|
||||
}
|
||||
```
|
||||
|
||||
_Loading the Library_
|
||||
|
||||
Assuming the standalone library is in the same directory as the source file,
|
||||
the script can be evaluated with `eval`:
|
||||
|
||||
```js
|
||||
var src = get_bstr("./xlsx.full.min.js");
|
||||
eval(src);
|
||||
```
|
||||
|
||||
_Parsing Files_
|
||||
|
||||
The same method can be used to read binary strings and parse with `type: "binary"`:
|
||||
|
||||
```js
|
||||
var file = get_bstr("./pres.numbers");
|
||||
var wb = XLSX.read(file);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="as" label="AppleScript">
|
||||
|
||||
The core idea is to push the processing logic to a stub JS file.
|
||||
|
||||
_JS Stub_
|
||||
|
||||
The JS stub will be evaluated in the JavaScript context. The same technique from
|
||||
the JavaScript section works in the stub:
|
||||
|
||||
```js
|
||||
ObjC.import("Foundation");
|
||||
|
||||
function get_bstr(path) {
|
||||
var str = $.NSString.stringWithContentsOfFileEncodingError(path, $.NSISOLatin1StringEncoding, null);
|
||||
return ObjC.unwrap(str);
|
||||
}
|
||||
|
||||
/* this will be called when AppleScript initializes the JS engine */
|
||||
eval(get_bstr("./xlsx.full.min.js"));
|
||||
```
|
||||
|
||||
It is more efficient to offload as much work as possible into the stub. For
|
||||
example, this function parses a workbook file from the filesystem and generates
|
||||
a CSV without passing intermediate values back to AppleScript:
|
||||
|
||||
```js
|
||||
/* this method will be exposed as `wb_to_csv` */
|
||||
function wb_to_csv(path) {
|
||||
/* read file */
|
||||
var filedata = get_bstr(path);
|
||||
var wb = XLSX.read(filedata, { type: "binary" });
|
||||
return XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);
|
||||
}
|
||||
```
|
||||
|
||||
_Loading the Stub_
|
||||
|
||||
Assuming the stub is saved to `xlsx.stub.js`, the following handler creates a
|
||||
context and evaluates the standalone library:
|
||||
|
||||
```applescript
|
||||
on getContext()
|
||||
-- get contents of xlsx.stub.js
|
||||
set UnixPath to POSIX path of ((path to me as text) & "::")
|
||||
set libpath to POSIX path of (UnixPath & "xlsx.stub.js")
|
||||
set {src, err} to current application's NSString's stringWithContentsOfFile:libpath encoding:(current application's NSISOLatin1StringEncoding) |error|:(reference)
|
||||
if src is missing value then error (err's localizedDescription()) as text
|
||||
|
||||
-- create scripting context and evaluate the stub
|
||||
set lang to current application's OSALanguage's languageForName:"JavaScript"
|
||||
set osa to current application's OSAScript's alloc()'s initWithSource:src language:lang
|
||||
return osa
|
||||
end getContext
|
||||
```
|
||||
|
||||
_Evaluating JS Code_
|
||||
|
||||
When calling a function, the result is an array whose first item is the value of
|
||||
the evaluated code. A small helper function extracts the raw result:
|
||||
|
||||
```applescript
|
||||
on extractResult(res)
|
||||
return item 1 of ((current application's NSArray's arrayWithObject:res) as list)
|
||||
end extractResult
|
||||
```
|
||||
|
||||
With everything defined, `executeHandlerWithName` will run functions defined in
|
||||
the stub. For example:
|
||||
|
||||
```applescript
|
||||
set osa to getContext()
|
||||
set {res, err} to osa's executeHandlerWithName:"wb_to_csv" arguments:{"pres.numbers"} |error|:(reference)
|
||||
extractResult(res)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Complete Demo
|
||||
|
||||
This example will read from a specified filename and print the first worksheet
|
||||
data in CSV format.
|
||||
|
||||
0) Download the standalone script and test file:
|
||||
|
||||
```bash
|
||||
curl -LO https://sheetjs.com/pres.numbers
|
||||
curl -LO https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js
|
||||
```
|
||||
|
||||
<Tabs groupId="osa">
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
1) Save the following script to `sheetosa.js`:
|
||||
|
||||
```js title="sheetosa.js"
|
||||
#!/usr/bin/env osascript -l JavaScript
|
||||
|
||||
ObjC.import("Foundation");
|
||||
function get_bstr(path) {
|
||||
var str = $.NSString.stringWithContentsOfFileEncodingError(path, $.NSISOLatin1StringEncoding, null);
|
||||
return ObjC.unwrap(str);
|
||||
}
|
||||
eval(get_bstr("./xlsx.full.min.js"));
|
||||
|
||||
function run(argv) {
|
||||
var filedata = get_bstr(argv[0]);
|
||||
var wb = XLSX.read(filedata, { type: "binary" });
|
||||
console.log(XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]));
|
||||
}
|
||||
```
|
||||
|
||||
2) Make the script executable:
|
||||
|
||||
```bash
|
||||
chmod +x sheetosa.js
|
||||
```
|
||||
|
||||
3) Run the script, passing the path to the test file as an argument:
|
||||
|
||||
```bash
|
||||
./sheetosa.js pres.numbers
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="as" label="AppleScript">
|
||||
|
||||
1) Save the following script to `xlsx.stub.js`:
|
||||
|
||||
```js title="xlsx.stub.js"
|
||||
ObjC.import("Foundation");
|
||||
function get_bstr(path) {
|
||||
var str = $.NSString.stringWithContentsOfFileEncodingError(path, $.NSISOLatin1StringEncoding, null);
|
||||
return ObjC.unwrap(str);
|
||||
}
|
||||
eval(get_bstr("./xlsx.full.min.js"));
|
||||
|
||||
function wb_to_csv(path) {
|
||||
var filedata = get_bstr(path);
|
||||
var wb = XLSX.read(filedata, { type: "binary" });
|
||||
return XLSX.utils.sheet_to_csv(wb.Sheets[wb.SheetNames[0]]);
|
||||
}
|
||||
```
|
||||
|
||||
2) Save the following script to `sheetosa.scpt`:
|
||||
|
||||
```applescript title="sheetosa.scpt"
|
||||
#!/usr/bin/env osascript
|
||||
use AppleScript version "2.7"
|
||||
use scripting additions
|
||||
use framework "Foundation"
|
||||
use framework "OSAKit"
|
||||
|
||||
set osa to getContext()
|
||||
set {res, err} to osa's executeHandlerWithName:"wb_to_csv" arguments:{"pres.numbers"} |error|:(reference)
|
||||
extractResult(res)
|
||||
|
||||
on getContext()
|
||||
set UnixPath to POSIX path of ((path to me as text) & "::")
|
||||
set libpath to POSIX path of (UnixPath & "xlsx.shim.js")
|
||||
set {src, err} to current application's NSString's stringWithContentsOfFile:libpath encoding:(current application's NSISOLatin1StringEncoding) |error|:(reference)
|
||||
|
||||
set lang to current application's OSALanguage's languageForName:"JavaScript"
|
||||
set osa to current application's OSAScript's alloc()'s initWithSource:src language:lang
|
||||
return osa
|
||||
end getContext
|
||||
|
||||
on extractResult(res)
|
||||
return item 1 of ((current application's NSArray's arrayWithObject:res) as list)
|
||||
end extractResult
|
||||
```
|
||||
|
||||
3) Make the script executable:
|
||||
|
||||
```bash
|
||||
chmod +x sheetosa.scpt
|
||||
```
|
||||
|
||||
3) Run the script (it is hardcoded to read `pres.numbers`):
|
||||
|
||||
```bash
|
||||
./sheetosa.scpt
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
@ -142,7 +142,7 @@ const config = {
|
||||
prism: {
|
||||
theme: lightCodeTheme,
|
||||
darkTheme: darkCodeTheme,
|
||||
additionalLanguages: [ "swift", "java", "csharp", "perl", "ruby", "cpp" ],
|
||||
additionalLanguages: [ "swift", "java", "csharp", "perl", "ruby", "cpp", "applescript" ],
|
||||
},
|
||||
liveCodeBlock: {
|
||||
playgroundPosition: 'top'
|
||||
|
Loading…
Reference in New Issue
Block a user