Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions builder/tbdocs.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,11 @@ const TASKS = {
runOnMain: true,
async execute({ config: { config } }, ctx) {
const { pages, staticFiles } = await discover(ctx.srcRoot, config.exclude ?? []);
for (const entry of config.bundle_extra ?? []) {
const srcPath = path.resolve(ctx.srcRoot, entry.src);
const stat = await fs.stat(srcPath);
staticFiles.push({ srcPath, srcRel: entry.dest, destRel: entry.dest, size: stat.size });
}
return { pages, staticFiles, config };
},
submit(out, state) {
Expand Down
97 changes: 97 additions & 0 deletions docs/Features/Packages/Import-export tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
---
title: Import/Export Tool
parent: Package Management
grand_parent: Features
nav_order: 7
permalink: /Features/Packages/Import-Export-Tool
---

# Import/export tool

A standalone command-line tool for unpacking `.twinproj` and `.twinpack`
files to a directory tree, and for repacking a directory tree back into a
binary project file. Useful for inspecting package contents, batch-editing
source files outside the IDE, or integrating twinBASIC projects into
version-control workflows.

> [!WARNING]
>
> There is no official support for reading or writing project files outside of the twinBASIC executable. This tool may break when the IDE is updated.

Two functionally identical, single-file implementations are provided -- pick
whichever runtime you already have installed:

| Runtime | Download |
|---------|----------|
| Node.js 18+ | <a href="downloads/impexp.mjs" download>impexp.mjs</a> |
| Python 3.6+ | <a href="downloads/impexp.py" download>impexp.py</a> |

Neither script has any external dependencies.

## Usage

```
impexp import <file.twinproj|.twinpack> [output_dir]
impexp export <input_dir> <output.twinproj|.twinpack>
impexp --self-test
```

### Import (unpack)

Reads a `.twinproj` or `.twinpack` binary and extracts its contents to a
directory on disk. If `output_dir` is omitted, a directory named after the
project root entry is created in the current working directory.

```
node impexp.mjs import MyPackage.twinpack
```

```
python impexp.py import MyProject.twinproj unpacked/
```

### Export (pack)

Scans a directory tree and writes a `.twinproj` or `.twinpack` binary. The
directory name becomes the root entry name in the output file. Well-known
directory and file names (`Sources`, `Resources`, `Settings`, etc.) are
tagged with the correct `mark2` category values automatically.

```
node impexp.mjs export unpacked/ MyProject.twinproj
```

```
python impexp.py export unpacked/ MyPackage.twinpack
```

### Self-test

Both implementations include a built-in test suite that exercises parsing,
serialization, and full round-trip fidelity.

```
node impexp.mjs --self-test
python impexp.py --self-test
```

## Round-trip notes

Importing and re-exporting a binary file preserves all file contents
byte-for-byte. The following metadata fields are reset to defaults on a
disk round-trip (they are not stored on the filesystem):

- **mark1** (revision counter) -- directories get `0x0000`; files get
`0x0002`.
- **Revision entries** -- always written as zero.
- **Entry order** -- directories first, then files, sorted alphabetically
within each group.

The IDE regenerates these fields when the project is opened, so the
round-tripped file is fully functional.

## See also

- [TWINPACK File Format](File-Format) -- binary format specification
- [Creating a TWINPACK Package](Creating-TWINPACK)
- [Importing a Package from a TWINPACK File](Importing-TWINPACK)
1 change: 1 addition & 0 deletions docs/Features/Packages/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ Please be aware that TWINPACK files currently contain the full source code of yo
- [Linked Packages](Linked) -- storing a package in a shared location rather than embedding it in each project file.
- [Updating a Package](Updating) -- removing an outdated package and installing a newer version from TWINSERV.
- [TWINPACK File Format](File-Format) -- binary format specification for `.twinproj` and `.twinpack` files.
- [Import/Export Tool](Import-Export-Tool) -- standalone command-line tool for unpacking and repacking `.twinproj` and `.twinpack` files.

[^1]: A service of TWINBASIC LTD offered to the user community.
9 changes: 9 additions & 0 deletions docs/_config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ offline_exclude:
#
# Patterns that start with * must be quoted so YAML does not interpret them
# as alias references.
# Extra files from outside the docs tree to bundle as site assets.
# Each entry maps a source path (relative to docs/) to a destination
# path in the built site. Injected during the discover phase.
bundle_extra:
- src: ../scripts/impexp.mjs
dest: Features/Packages/downloads/impexp.mjs
- src: ../scripts/impexp.py
dest: Features/Packages/downloads/impexp.py

exclude:
# Underscore-prefixed files and directories -- catches _config.yml,
# _book.yml, _site, _site-offline, _site-pdf, _pdf, _includes,
Expand Down
Loading