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