stata demos refresh

This commit is contained in:
SheetJS 2024-04-11 13:44:06 -04:00
parent 98a3b79e9c
commit 2e44e0c2c8
3 changed files with 75 additions and 13 deletions

@ -118,7 +118,12 @@ builder requires a proper `package.json` that includes the SheetJS dependency.
:::note Tested Deployments
This example was last tested on 2024-02-21 against BunJS 1.0.28 on macOS 14.3.1.
This demo was last tested in the following deployments:
| Architecture | BunJS | Date |
|:-------------|:--------|:-----------|
| `darwin-x64` | `1.1.3` | 2024-04-10 |
| `win10-x64` | `1.1.3` | 2024-04-10 |
:::

@ -46,7 +46,12 @@ This demo covers Stata extensions. For directly processing Stata DTA files, the
:::note Tested Deployments
This demo was last tested by SheetJS users on 2023 November 15.
This demo was tested by SheetJS users in the following deployments:
| Architecture | Date |
|:-------------|:-----------|
| `darwin-x64` | 2024-04-10 |
| `win10-x64` | 2024-04-10 |
:::
@ -106,10 +111,49 @@ flowchart LR
Stata C extensions are shared libraries or DLLs that use special Stata methods
for parsing arguments and returning values.
Arguments are passed to the `stata_call` function in the DLL.
#### Structure
Arguments are passed to the `stata_call` function in the plugin.[^4] The
function receives the argument count and an array of C strings:
```c title="stata_call declaration"
STDLL stata_call(int argc, char *argv[]);
```
For example, `argc` is 2 and `argv` has two C strings in the following command:
```stata
plugin call cleanfile, "pres.numbers" verbose
* arguments start
* argv[0] ^^^^^^^^^^^^
* argv[1] ^^^^^^^
* argc = 2
```
#### Communication
`SF_display` and `SF_error` display text and error messages respectively.
Message text follows the "Stata Markup and Control Language"[^5].
`{stata ...}` is a special directive that displays the arguments and creates a
clickable link. Clicking the link will run the string.
For example, a plugin may attempt to print a link:
```c title="SF_display C plugin example"
SF_display("{stata import excel \"sheetjs.tmp.xlsx\", firstrow} will read the first sheet and use headers\n");
```
The function will print the following text to the terminal:
<pre>
<span {...b}>import excel "sheetjs.tmp.xlsx", firstrow</span> will read the first sheet and use headers{'\n'}
</pre>
The blue text is clickable. When a user clicks the text, the command
`import excel "sheetjs.tmp.xlsx", firstrow` will be executed.
### Duktape JS Engine
This demo uses the [Duktape JavaScript engine](/docs/demos/engines/duktape). The
@ -410,4 +454,6 @@ browse Name Index
[^1]: Run `help import excel` in Stata or see ["import excel"](https://www.stata.com/manuals/dimportexcel.pdf) in the Stata documentation.
[^2]: See [`read` in "Reading Files"](/docs/api/parse-options)
[^3]: See [`write` in "Writing Files"](/docs/api/write-options)
[^3]: See [`write` in "Writing Files"](/docs/api/write-options)
[^4]: See ["Creating and using Stata plugins"](https://www.stata.com/plugins/#sect8) in the Stata website
[^5]: run `help smcl` in Stata or see ["smcl"](https://www.stata.com/manuals/psmcl.pdf) in the Stata documentation.

@ -32,6 +32,18 @@ reported to [the issue tracker](https://git.sheetjs.com/sheetjs/sheetjs/issues).
:::
:::info Limitations
In Stata parlance, versions 102-105, 108, 110-115, and 117-121 are supported.
This corresponds to the known file versions across all releases through Stata 18.
Consistent with spreadsheet software limitations, the first 1048576 observations
and 16384 variables are extracted.
Alias variables (supported in DTA versions 120-121) are not processed.
:::
## Live Demo
This demo fetches a [sample DTA file](pathname:///dta/pres.dta), parses the data
@ -54,14 +66,14 @@ function SheetJSDTA() {
const [__html, setHTML] = React.useState("");
const [text, setText] = React.useState("");
const process = (u8) => {
const process = (ab) => {
try {
/* Initial Setup */
if(typeof DTA == "undefined") return setText("ERROR: Reload this page!");
DTA.set_utils(XLSX.utils);
/* Parse DTA */
const wb = DTA.parse(u8);
const wb = DTA.parse(new Uint8Array(ab));
/* Generate HTML */
setHTML(XLSX.utils.sheet_to_html(wb.Sheets[wb.SheetNames[0]]));
@ -69,19 +81,18 @@ function SheetJSDTA() {
} catch(e) { setText("ERROR: " + (e && e.message || e)); }
};
/* Fetch test file on load */
React.useEffect(() => { (async() => {
/* Fetch file */
process(new Uint8Array(await (await fetch("/dta/pres.dta")).arrayBuffer()));
process(await (await fetch("/dta/pres.dta")).arrayBuffer());
})(); }, []);
const goodstyle = { backgroundColor: "#C6EFCE", color: "#006100" };
const badstyle = { backgroundColor: "#FFC7CE", color: "#9C0006" };
const good = { backgroundColor: "#C6EFCE", color: "#006100" };
const bad = { backgroundColor: "#FFC7CE", color: "#9C0006" };
return ( <>
{/* Import Button */}
<input type="file" onChange={async(e) => {
process(new Uint8Array(await e.target.files[0].arrayBuffer()));
process(await e.target.files[0].arrayBuffer());
}}/>
{text && <code style={/ERROR/.test(text)?badstyle:goodstyle}>{text}</code>}
{text && <code style={/ERROR/.test(text)?bad:good}>{text}</code>}
<div dangerouslySetInnerHTML={{ __html }}/>
</> );
}