~cadence/PE-DIA

a328f6b4fac8b2a4bc10476a7a9e7bb7ece98008 — Cadence Ember 1 year, 8 months ago 7f55a86
Convert to Deno
4 files changed, 92 insertions(+), 43 deletions(-)

M README.md
M parser.js
M processor.js
A start.js
M README.md => README.md +39 -9
@@ 2,23 2,53 @@

A dialog editor for Wonderland Adventures custom adventures that takes its input as structured text files.

## Get the code
## Usage: On the World Wide Web

You need to install [node.js](https://nodejs.org) to run PE-DIA.
Coming soon?

(Windows users: Run the installer. If it asks, make sure that you add it to PATH. You may need to restart the computer.)
## Usage: Windows users

Clone or [download](https://git.sr.ht/~cadence/crumpet/archive/main.tar.gz) PE-DIA.
### Installing PE-DIA for the first time

(Windows users: you may need [7-Zip](https://7-zip.org) in order to open tar.gz files.)
PE-DIA officially supports Windows 8 and later.

## Usage
You need to install Deno to run PE-DIA. To install Deno, follow these instructions:

See `template.md` for an example of how to use your own text files.
1. Open the start menu and type "powershell". Click the "Windows PowerShell" item.
2. In the command window, run these commands and wait for Deno to install. You need to right-click to paste.

Invoke the program with `node processor.js template.md > 1.dia` or similar.
```
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
iwr deno.land/x/install@v0.1.4/install.ps1 | iex
```

(Windows users: Shift-right-click in the file manager and "open command window here" to be able to run that command.)
Now you can download PE-DIA: https://cadence.moe/friends/PE-DIA.zip

### Using PE-DIA

1. Open the folder where you downloaded the PE-DIA files. Hold shift, right-click the background of that folder, and choose "open command prompt here" or "open powershell here".
2. In the command window, run this command to use PE-DIA. You need to right-click to paste.

```
deno run --allow-read start.js template.md > 1.dia
```

- `template.md` is the text file to read from. You can change this to read from a different file.
- `1.dia` is the dialog file to write out to. You can change this to write to a different file.
- Everything else needs to stay the same.

## Usage: Linux users

### Installing PE-DIA for the first time

1. [Install Deno.](https://deno.land)
2. Clone this repo.

### Using PE-DIA

```
deno run --allow-read start.js template.md > 1.dia
```

## License


M parser.js => parser.js +1 -3
@@ 9,7 9,7 @@ const tf = {
	lc: s => s.toLowerCase()
}

class Parser {
export class Parser {
	constructor(string) {
		this.string = string;
		this.substore = [];


@@ 195,5 195,3 @@ class Parser {
		Object.assign(this, this.substore.pop())
	}
}

module.exports.Parser = Parser

M processor.js => processor.js +18 -31
@@ 1,7 1,6 @@
//@ts-check

const fs = require("fs")
const {Parser} = require("./parser")
import {Parser} from "./parser.js"

const interchanges = []



@@ 50,24 49,34 @@ function wordwrap(str, width) {
class MSStream {
	/** @param {fs.WriteStream} stream */
	constructor(stream) {
		this.arrays = []
		this.stream = stream
	}

	push(array) {
		this.arrays.push(array)
	}

	writeInt(int) {
		const uint8length = 8
		const uint8capacity = (1 << uint8length) - 1
		const array = new Uint8Array(4).map((_, i) => {
		const array = Array(4).fill().map((_, i) => {
			// output byte based on position. it's little-endian, so produce the least significant byte first.
			const scale = uint8length * i
			const mask = uint8capacity << scale // mask higher bits further in the array
			return (mask & int) >> scale
		})
		this.stream.write(array)
		this.push(array)
	}

	writeString(string) {
		this.writeInt(string.length)
		this.stream.write(string, "ascii")
		const array = [...string].map(c => c.charCodeAt())
		this.push(array)
	}

	writeOut() {
		return this.stream.write(Uint8Array.from(this.arrays.flat()))
	}
}



@@ 353,7 362,7 @@ class Choice {
	}
}

function loadDialog(fileContents) {
export function loadDialog(fileContents) {
	fileContents = fileContents.split("\n").filter(line => !line.startsWith("~")).join("\n")
	const parser = new Parser(fileContents)
	while (parser.hasRemaining()) {


@@ 361,9 370,9 @@ function loadDialog(fileContents) {
	}
}

function saveDialog(stream) {
	const msstream = new MSStream(stream)
export function saveDialog(stream) {
	// interchange and reply data
	const msstream = new MSStream(stream)
	msstream.writeInt(interchanges.length)
	for (const interchange of interchanges) {
		interchange.writeTo(msstream)


@@ 371,27 380,5 @@ function saveDialog(stream) {
	// askabout data
	msstream.writeInt(0)
	msstream.writeString("Created with PE-DIA.")
	msstream.writeOut()
}

// ok here's where it does the thing

const filename = process.argv[2]
if (!filename) {
	throw new Error("Supply the .md file to read as a command line parameter. (Try 'template.md' for an example.)")
}
if (!fs.existsSync(filename)) {
	throw new Error(`File '${filename}' does not exist.`)
}
if (process.stdout.isTTY) {
	throw new Error("You should definitely save the output to a file. To do this, end your command with an arrow and a filename, like: > 1.dia")
}

// load the file
let fileContents = fs.readFileSync(filename, "utf8")
fileContents = fileContents.replace(/\r\n/g, "\n")
loadDialog(fileContents)

// save the file
// const stream = fs.createWriteStream("1.dia", {encoding: null})
const stream = process.stdout
saveDialog(stream)

A start.js => start.js +34 -0
@@ 0,0 1,34 @@
// here's where it does the thing

import {loadDialog, saveDialog} from "./processor.js"

function die(message) {
	console.error("Error: " + message)
	Deno.exit(1)
}

const filename = Deno.args[0]
if (!filename) {
	die("Supply the .md file to read as a command line parameter. (Try 'template.md' for an example.)")
}
if (Deno.isatty(Deno.stdout.rid)) {
	die("You need to save the output to a file. To do this, end your command with an arrow and a filename, like this:\ndeno run --allow-read start.js input.md > 1.dia")
}

// request permissions to read
const status = await Deno.permissions.request({name: "read", path: filename})
if (status.state === "denied") {
	die("No permissions to read the input file. Give PE-DIA permission by adding --allow-read to your command, like this:\ndeno run --allow-read start.js input.md > 1.dia")
}

// load the file
let fileContents = await Deno.readTextFile(filename)
fileContents = fileContents.replace(/\r\n/g, "\n")
loadDialog(fileContents)

// save the file
// const stream = fs.createWriteStream("1.dia", {encoding: null})
const stream = Deno.stdout
saveDialog(stream)

console.error("Success! All done.")