Finish adding JS API docs.
This commit is contained in:
parent
87eb5b7fbd
commit
fb90f825ed
@ -7,7 +7,8 @@ set languageMeta = {
|
||||
'c': { name: 'C', icon: '<svg viewBox="0 0 128 128"><path fill="#659AD3" d="M115.4 30.7L67.1 2.9c-.8-.5-1.9-.7-3.1-.7-1.2 0-2.3.3-3.1.7l-48 27.9c-1.7 1-2.9 3.5-2.9 5.4v55.7c0 1.1.2 2.4 1 3.5l106.8-62c-.6-1.2-1.5-2.1-2.4-2.7z"></path><path fill="#03599C" d="M10.7 95.3c.5.8 1.2 1.5 1.9 1.9l48.2 27.9c.8.5 1.9.7 3.1.7 1.2 0 2.3-.3 3.1-.7l48-27.9c1.7-1 2.9-3.5 2.9-5.4V36.1c0-.9-.1-1.9-.6-2.8l-106.6 62z"></path><path fill="#fff" d="M85.3 76.1C81.1 83.5 73.1 88.5 64 88.5c-13.5 0-24.5-11-24.5-24.5s11-24.5 24.5-24.5c9.1 0 17.1 5 21.3 12.5l13-7.5c-6.8-11.9-19.6-20-34.3-20-21.8 0-39.5 17.7-39.5 39.5s17.7 39.5 39.5 39.5c14.6 0 27.4-8 34.2-19.8l-12.9-7.6z"></path></svg>' },
|
||||
'javascript': { name: 'JavaScript', icon: '<svg viewBox="0 0 128 128"><path fill="#F0DB4F" d="M1.408 1.408h125.184v125.185H1.408z"></path><path fill="#323330" d="M116.347 96.736c-.917-5.711-4.641-10.508-15.672-14.981-3.832-1.761-8.104-3.022-9.377-5.926-.452-1.69-.512-2.642-.226-3.665.821-3.32 4.784-4.355 7.925-3.403 2.023.678 3.938 2.237 5.093 4.724 5.402-3.498 5.391-3.475 9.163-5.879-1.381-2.141-2.118-3.129-3.022-4.045-3.249-3.629-7.676-5.498-14.756-5.355l-3.688.477c-3.534.893-6.902 2.748-8.877 5.235-5.926 6.724-4.236 18.492 2.975 23.335 7.104 5.332 17.54 6.545 18.873 11.531 1.297 6.104-4.486 8.08-10.234 7.378-4.236-.881-6.592-3.034-9.139-6.949-4.688 2.713-4.688 2.713-9.508 5.485 1.143 2.499 2.344 3.63 4.26 5.795 9.068 9.198 31.76 8.746 35.83-5.176.165-.478 1.261-3.666.38-8.581zM69.462 58.943H57.753l-.048 30.272c0 6.438.333 12.34-.714 14.149-1.713 3.558-6.152 3.117-8.175 2.427-2.059-1.012-3.106-2.451-4.319-4.485-.333-.584-.583-1.036-.667-1.071l-9.52 5.83c1.583 3.249 3.915 6.069 6.902 7.901 4.462 2.678 10.459 3.499 16.731 2.059 4.082-1.189 7.604-3.652 9.448-7.401 2.666-4.915 2.094-10.864 2.07-17.444.06-10.735.001-21.468.001-32.237z"></path></svg>' },
|
||||
'typescript': { name: 'TypeScript', icon: '<svg viewBox="0 0 128 128"><path fill="#fff" d="M22.67 47h99.67v73.67H22.67z"></path><path data-name="original" fill="#007acc" d="M1.5 63.91v62.5h125v-125H1.5zm100.73-5a15.56 15.56 0 017.82 4.5 20.58 20.58 0 013 4c0 .16-5.4 3.81-8.69 5.85-.12.08-.6-.44-1.13-1.23a7.09 7.09 0 00-5.87-3.53c-3.79-.26-6.23 1.73-6.21 5a4.58 4.58 0 00.54 2.34c.83 1.73 2.38 2.76 7.24 4.86 8.95 3.85 12.78 6.39 15.16 10 2.66 4 3.25 10.46 1.45 15.24-2 5.2-6.9 8.73-13.83 9.9a38.32 38.32 0 01-9.52-.1 23 23 0 01-12.72-6.63c-1.15-1.27-3.39-4.58-3.25-4.82a9.34 9.34 0 011.15-.73L82 101l3.59-2.08.75 1.11a16.78 16.78 0 004.74 4.54c4 2.1 9.46 1.81 12.16-.62a5.43 5.43 0 00.69-6.92c-1-1.39-3-2.56-8.59-5-6.45-2.78-9.23-4.5-11.77-7.24a16.48 16.48 0 01-3.43-6.25 25 25 0 01-.22-8c1.33-6.23 6-10.58 12.82-11.87a31.66 31.66 0 019.49.26zm-29.34 5.24v5.12H56.66v46.23H45.15V69.26H28.88v-5a49.19 49.19 0 01.12-5.17C29.08 59 39 59 51 59h21.83z"></path></svg>' },
|
||||
'python': { name: 'Python', icon: '<svg viewBox="0 0 128 128"><linearGradient id="python-original-a" gradientUnits="userSpaceOnUse" x1="70.252" y1="1237.476" x2="170.659" y2="1151.089" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#5A9FD4"></stop><stop offset="1" stop-color="#306998"></stop></linearGradient><linearGradient id="python-original-b" gradientUnits="userSpaceOnUse" x1="209.474" y1="1098.811" x2="173.62" y2="1149.537" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#FFD43B"></stop><stop offset="1" stop-color="#FFE873"></stop></linearGradient><path fill="url(#python-original-a)" d="M63.391 1.988c-4.222.02-8.252.379-11.8 1.007-10.45 1.846-12.346 5.71-12.346 12.837v9.411h24.693v3.137H29.977c-7.176 0-13.46 4.313-15.426 12.521-2.268 9.405-2.368 15.275 0 25.096 1.755 7.311 5.947 12.519 13.124 12.519h8.491V67.234c0-8.151 7.051-15.34 15.426-15.34h24.665c6.866 0 12.346-5.654 12.346-12.548V15.833c0-6.693-5.646-11.72-12.346-12.837-4.244-.706-8.645-1.027-12.866-1.008zM50.037 9.557c2.55 0 4.634 2.117 4.634 4.721 0 2.593-2.083 4.69-4.634 4.69-2.56 0-4.633-2.097-4.633-4.69-.001-2.604 2.073-4.721 4.633-4.721z" transform="translate(0 10.26)"></path><path fill="url(#python-original-b)" d="M91.682 28.38v10.966c0 8.5-7.208 15.655-15.426 15.655H51.591c-6.756 0-12.346 5.783-12.346 12.549v23.515c0 6.691 5.818 10.628 12.346 12.547 7.816 2.297 15.312 2.713 24.665 0 6.216-1.801 12.346-5.423 12.346-12.547v-9.412H63.938v-3.138h37.012c7.176 0 9.852-5.005 12.348-12.519 2.578-7.735 2.467-15.174 0-25.096-1.774-7.145-5.161-12.521-12.348-12.521h-9.268zM77.809 87.927c2.561 0 4.634 2.097 4.634 4.692 0 2.602-2.074 4.719-4.634 4.719-2.55 0-4.633-2.117-4.633-4.719 0-2.595 2.083-4.692 4.633-4.692z" transform="translate(0 10.26)"></path><radialGradient id="python-original-c" cx="1825.678" cy="444.45" r="26.743" gradientTransform="matrix(0 -.24 -1.055 0 532.979 557.576)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#B8B8B8" stop-opacity=".498"></stop><stop offset="1" stop-color="#7F7F7F" stop-opacity="0"></stop></radialGradient><path opacity=".444" fill="url(#python-original-c)" d="M97.309 119.597c0 3.543-14.816 6.416-33.091 6.416-18.276 0-33.092-2.873-33.092-6.416 0-3.544 14.815-6.417 33.092-6.417 18.275 0 33.091 2.872 33.091 6.417z"></path></svg>' }
|
||||
'python': { name: 'Python', icon: '<svg viewBox="0 0 128 128"><linearGradient id="python-original-a" gradientUnits="userSpaceOnUse" x1="70.252" y1="1237.476" x2="170.659" y2="1151.089" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#5A9FD4"></stop><stop offset="1" stop-color="#306998"></stop></linearGradient><linearGradient id="python-original-b" gradientUnits="userSpaceOnUse" x1="209.474" y1="1098.811" x2="173.62" y2="1149.537" gradientTransform="matrix(.563 0 0 -.568 -29.215 707.817)"><stop offset="0" stop-color="#FFD43B"></stop><stop offset="1" stop-color="#FFE873"></stop></linearGradient><path fill="url(#python-original-a)" d="M63.391 1.988c-4.222.02-8.252.379-11.8 1.007-10.45 1.846-12.346 5.71-12.346 12.837v9.411h24.693v3.137H29.977c-7.176 0-13.46 4.313-15.426 12.521-2.268 9.405-2.368 15.275 0 25.096 1.755 7.311 5.947 12.519 13.124 12.519h8.491V67.234c0-8.151 7.051-15.34 15.426-15.34h24.665c6.866 0 12.346-5.654 12.346-12.548V15.833c0-6.693-5.646-11.72-12.346-12.837-4.244-.706-8.645-1.027-12.866-1.008zM50.037 9.557c2.55 0 4.634 2.117 4.634 4.721 0 2.593-2.083 4.69-4.634 4.69-2.56 0-4.633-2.097-4.633-4.69-.001-2.604 2.073-4.721 4.633-4.721z" transform="translate(0 10.26)"></path><path fill="url(#python-original-b)" d="M91.682 28.38v10.966c0 8.5-7.208 15.655-15.426 15.655H51.591c-6.756 0-12.346 5.783-12.346 12.549v23.515c0 6.691 5.818 10.628 12.346 12.547 7.816 2.297 15.312 2.713 24.665 0 6.216-1.801 12.346-5.423 12.346-12.547v-9.412H63.938v-3.138h37.012c7.176 0 9.852-5.005 12.348-12.519 2.578-7.735 2.467-15.174 0-25.096-1.774-7.145-5.161-12.521-12.348-12.521h-9.268zM77.809 87.927c2.561 0 4.634 2.097 4.634 4.692 0 2.602-2.074 4.719-4.634 4.719-2.55 0-4.633-2.117-4.633-4.719 0-2.595 2.083-4.692 4.633-4.692z" transform="translate(0 10.26)"></path><radialGradient id="python-original-c" cx="1825.678" cy="444.45" r="26.743" gradientTransform="matrix(0 -.24 -1.055 0 532.979 557.576)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#B8B8B8" stop-opacity=".498"></stop><stop offset="1" stop-color="#7F7F7F" stop-opacity="0"></stop></radialGradient><path opacity=".444" fill="url(#python-original-c)" d="M97.309 119.597c0 3.543-14.816 6.416-33.091 6.416-18.276 0-33.092-2.873-33.092-6.416 0-3.544 14.815-6.417 33.092-6.417 18.275 0 33.091 2.872 33.091 6.417z"></path></svg>' },
|
||||
'sh': { name: 'shell' }
|
||||
}
|
||||
%}
|
||||
|
||||
@ -26,7 +27,9 @@ set languageMeta = {
|
||||
h-12 {{ node.summaryClass }}
|
||||
"
|
||||
>
|
||||
<div class="w-[16px] h-[16px] hidden md:block">{{ languageMeta[example.language].icon | safe }}</div>
|
||||
{% if languageMeta[example.language].icon %}
|
||||
<div class="w-[16px] h-[16px] hidden md:block">{{ languageMeta[example.language].icon | safe }}</div>
|
||||
{% endif %}
|
||||
{{ example.name or languageMeta[example.language].name }}
|
||||
</summary>
|
||||
<pre
|
||||
|
@ -11,8 +11,6 @@ Section light
|
||||
TableOfContents
|
||||
|
||||
Block
|
||||
class max-w-prose
|
||||
|
||||
Heading 1 Terrace C Documentation
|
||||
class -ml-2
|
||||
|
||||
@ -29,6 +27,8 @@ Section light
|
||||
To use it, download and include the following files in your project tree:
|
||||
- [parser.h](https://git.thederf.com/thederf/Terrace/src/branch/main/packages/c/parser.h) - Core terrace parser
|
||||
- [document.h](https://git.thederf.com/thederf/Terrace/src/branch/main/packages/c/document.h) - (optional) Convenience functions for parsing of documents
|
||||
|
||||
A simple example program using to read each line from stdin and output parser information, looking for a "title" key:
|
||||
CodeBlock c
|
||||
// Provides getline() for reading from stdin
|
||||
#include <stdio.h>
|
||||
@ -79,6 +79,30 @@ Section light
|
||||
|
||||
Markdown
|
||||
|
||||
Heading 2 Core API
|
||||
class mt-12
|
||||
|
||||
Heading 3 terrace_linedata_t
|
||||
class my-6
|
||||
CodeBlock c
|
||||
// Holds the parsed information from each line.
|
||||
typedef struct terrace_linedata_s {
|
||||
// Which character is being used for indentation. Avoids having to specify it on each terrace_parse_line call.
|
||||
char indent;
|
||||
// How many indent characters are present in the current line before the first non-indent character.
|
||||
unsigned int level;
|
||||
// The number of characters before the start of the line's "head" section.
|
||||
// (Normally the same as `level`)
|
||||
unsigned int offsetHead;
|
||||
// The number of characters before the start of the line's "tail" section.
|
||||
unsigned int offsetTail;
|
||||
} terrace_linedata_t;
|
||||
|
||||
Heading 3 terrace_parse_line()
|
||||
class my-6
|
||||
CodeBlock c
|
||||
void terrace_parse_line(char* line, terrace_linedata_t *lineData)
|
||||
|
||||
Heading 2 Recipes
|
||||
class mt-12
|
||||
|
||||
@ -156,38 +180,6 @@ Section light
|
||||
free(line);
|
||||
}
|
||||
|
||||
|
||||
Heading 2 Core API
|
||||
class mt-12
|
||||
|
||||
Markdown
|
||||
In most cases, you'll use the [Document API](#document-api) instead.
|
||||
The Core API provides low-level parsing for individual lines.
|
||||
|
||||
Heading 3 terrace_linedata_t
|
||||
class my-6
|
||||
CodeBlock c
|
||||
// Holds the parsed information from each line.
|
||||
typedef struct terrace_linedata_s {
|
||||
// Which character is being used for indentation. Avoids having to specify it on each terrace_parse_line call.
|
||||
char indent;
|
||||
// How many indent characters are present in the current line before the first non-indent character.
|
||||
unsigned int level;
|
||||
// The number of characters before the start of the line's "head" section.
|
||||
// (Normally the same as `level`)
|
||||
unsigned int offsetHead;
|
||||
// The number of characters before the start of the line's "tail" section.
|
||||
unsigned int offsetTail;
|
||||
} terrace_linedata_t;
|
||||
|
||||
Heading 3 terrace_create_line_data()
|
||||
class my-6
|
||||
|
||||
Heading 3 terrace_parse_line()
|
||||
class my-6
|
||||
CodeBlock c
|
||||
void terrace_parse_line(char* line, terrace_linedata_t *lineData)
|
||||
|
||||
Heading 2 Contributing
|
||||
class mt-12
|
||||
|
||||
|
@ -11,15 +11,13 @@ Section light
|
||||
TableOfContents
|
||||
|
||||
Block
|
||||
class max-w-prose
|
||||
|
||||
Heading 1 Terrace JavaScript Documentation
|
||||
class -ml-2
|
||||
|
||||
Markdown
|
||||
Documentation is available for the following languages:
|
||||
- [C](/docs/c/) - 10% Complete
|
||||
- [JavaScript](/docs/javascript/) - 50% Complete
|
||||
- [JavaScript](/docs/javascript/) - 75% Complete
|
||||
- [Python](/docs/python/) - 0% Complete
|
||||
|
||||
Heading 2 Getting Started
|
||||
@ -37,132 +35,86 @@ Section light
|
||||
# Yarn (https://yarnpkg.com/)
|
||||
$ yarn add @terrace-lang/js
|
||||
|
||||
Heading 2 Recipes
|
||||
class mt-12
|
||||
|
||||
Heading 3 Read object properties
|
||||
class mb-2
|
||||
Markdown
|
||||
Read known properties from a Terrace block and write them to an object.
|
||||
CodeBlock javascript
|
||||
// Provides simple convenience functions over the core parser
|
||||
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
|
||||
import { useDocument } from '@terrace-lang/js/document'
|
||||
// A helper for iterating over a string line-by-line
|
||||
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
|
||||
import { createStringReader } from '@terrace-lang/js/readers/js-string'
|
||||
|
||||
const input = `
|
||||
object
|
||||
string_property An example string
|
||||
numeric_property An example property
|
||||
`
|
||||
|
||||
const output = {
|
||||
string_property: null,
|
||||
numeric_property: null
|
||||
}
|
||||
|
||||
// useDocument returns convenience functions
|
||||
const { next, level, head, tail, match } = useDocument(createStringReader(input))
|
||||
|
||||
// next() parses the next line in the document
|
||||
while (await next()) {
|
||||
// match('object') is equivalent to head() === 'object'
|
||||
// Essentially: "If the current line starts with 'object'"
|
||||
if (match('object')) {
|
||||
const objectLevel = level()
|
||||
// When we call next with a parent level it,
|
||||
// only iterates over lines inside the parent block
|
||||
while (await next(objectLevel)) {
|
||||
// tail() returns the part of the current line after the first space
|
||||
if (match('string_property')) output.string_property = tail()
|
||||
// parseFloat() here the string tail() to a numeric float value
|
||||
if (match('numeric_property')) output.numeric_property = parseFloat(tail())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.dir(output)
|
||||
|
||||
Markdown
|
||||
Read *all* properties as strings from a Terrace block and write them to an object.
|
||||
CodeBlock javascript
|
||||
// Provides simple convenience functions over the core parser
|
||||
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
|
||||
import { useDocument } from '@terrace-lang/js/document'
|
||||
// A helper for iterating over a string line-by-line
|
||||
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
|
||||
import { createStringReader } from '@terrace-lang/js/readers/js-string'
|
||||
|
||||
const input = `
|
||||
object
|
||||
property1 Value 1
|
||||
property2 Value 2
|
||||
random_property igazi3ii4quaC5OdoB5quohnah1beeNg
|
||||
`
|
||||
|
||||
const output = {}
|
||||
|
||||
// useDocument returns convenience functions
|
||||
const { next, level, head, tail, match } = useDocument(createStringReader(input))
|
||||
|
||||
// next() parses the next line in the document
|
||||
while (await next()) {
|
||||
// match('object') is equivalent to head() === 'object'
|
||||
// Essentially: "If the current line starts with 'object'"
|
||||
if (match('object')) {
|
||||
const objectLevel = level()
|
||||
// When we call next with a parent level it,
|
||||
// only iterates over lines inside the parent block
|
||||
while (await next(objectLevel)) {
|
||||
// Skip empty lines
|
||||
if (!line()) continue
|
||||
// Add any properties to the object as strings using the
|
||||
// line head() as the key and tail() as the value
|
||||
output[head()] = tail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.dir(output)
|
||||
|
||||
Heading 2 Core API
|
||||
class mt-12
|
||||
Markdown
|
||||
**TODO:** Document
|
||||
**Note:** The Core API uses C-style conventions to optimize memory management
|
||||
and improve portability to other environments and languages.
|
||||
It is unwieldy and does not follow JavaScript best practices.
|
||||
|
||||
For most projects you'll want to use the [Document API](#document-api) instead.
|
||||
It provides an ergonomic wrapper around the Core API and lets you focus on parsing
|
||||
your documents.
|
||||
|
||||
Heading 3 LineData
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
CodeBlock typescript
|
||||
// Type Definition
|
||||
// Holds the parsed information from each line.
|
||||
type LineData = {
|
||||
line: string;
|
||||
// Which character is being used for indentation. Avoids having to specify it on each parseLine call.
|
||||
indent: string;
|
||||
// How many indent characters are present in the current line before the first non-indent character.
|
||||
level: number;
|
||||
// The number of characters before the start of the line's "head" section.
|
||||
// (Normally the same as `level`)
|
||||
offsetHead: number;
|
||||
// The number of characters before the start of the line's "tail" section.
|
||||
offsetTail: number;
|
||||
}
|
||||
|
||||
Heading 3 createLineData()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
| indent | string | The character used for indentation in the document. Only a single character is permitted.
|
||||
| **@returns** | [LineData](#line-data) | A LineData instance with the specified indent character and all other values initialized to 0.
|
||||
|
||||
Initialize a LineData instance with default values to pass to [parseLine()](#parse-line).
|
||||
|
||||
CodeBlock typescript
|
||||
function createLineData(line: string = '', indent: string = ' '): LineData
|
||||
CodeBlock javascript
|
||||
// Type Definition
|
||||
function createLineData(indent: string = ' '): LineData
|
||||
|
||||
// Import Path
|
||||
import { createLineData } from '@terrace-lang/js/parser'
|
||||
|
||||
// Usage
|
||||
const lineData = createLineData(' ')
|
||||
console.dir(lineData)
|
||||
// { indent: ' ', level: 0, offsetHead: 0, offsetTail: 0 }
|
||||
// Use the same lineData object for all calls to parseLine in the same document.
|
||||
|
||||
Heading 3 parseLine()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
| line | string | A string containing a line to parse. Shouldn't end with a newline.
|
||||
| lineData | [LineData](#line-data) | A LineData object to store information about the current line, from [createLineData()](#create-line-data).<br/>**Mutated in-place!**
|
||||
|
||||
Core Terrace parser function, sets `level`, `offsetHead`, and `offsetTail` in a [LineData](#line-data) object based on the passed line.
|
||||
Note that this is a C-style function, `lineData` is treated as a reference and mutated in-place.
|
||||
|
||||
CodeBlock typescript
|
||||
// Type Definition
|
||||
function parseLine(lineData: LineData): LineData
|
||||
CodeBlock javascript
|
||||
import { parseLine } from '@terrace-lang/js/parser'
|
||||
|
||||
// Import Path
|
||||
import { createLineData, parseLine } from '@terrace-lang/js/parser'
|
||||
|
||||
// Usage
|
||||
const lineData = createLineData(' ')
|
||||
parseLine('title Example Title', lineData)
|
||||
console.dir(lineData)
|
||||
// { indent: ' ', level: 0, offsetHead: 0, offsetTail: 5 }
|
||||
|
||||
Heading 2 Document API
|
||||
class mt-12
|
||||
|
||||
Heading 3 useDocument()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
@ -179,7 +131,7 @@ Section light
|
||||
import { useDocument } from '@terrace-lang/js/document'
|
||||
|
||||
Heading 3 Document
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
Container for a handful of convenience functions for parsing documents.
|
||||
Obtained from [useDocument()](#usedocument) above
|
||||
@ -195,7 +147,7 @@ Section light
|
||||
}
|
||||
|
||||
Heading 3 Document.next()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
@ -230,7 +182,7 @@ Section light
|
||||
}
|
||||
|
||||
Heading 3 Document.level()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
@ -254,7 +206,7 @@ Section light
|
||||
const { level } = useDocument(...)
|
||||
|
||||
Heading 3 Document.line()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
@ -282,7 +234,7 @@ Section light
|
||||
const { line } = useDocument(...)
|
||||
|
||||
Heading 3 Document.head()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
@ -305,7 +257,7 @@ Section light
|
||||
const { head } = useDocument(...)
|
||||
|
||||
Heading 3 Document.tail()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
@ -327,7 +279,7 @@ Section light
|
||||
const { tail } = useDocument(...)
|
||||
|
||||
Heading 3 Document.match()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
@ -355,25 +307,69 @@ Section light
|
||||
Heading 2 Reader API
|
||||
class mt-12
|
||||
Markdown
|
||||
**TODO:** Document
|
||||
The [Document API](#document-api) requires `Reader` functions to iterate through lines
|
||||
in a document. A reader function simply returns a string (or a promise resolving to a string).
|
||||
Each time it is called, it returns the next line from whichever source it is pulling them.
|
||||
|
||||
Terrace provides a few built-in readers, but you are welcome to build your own instead.
|
||||
|
||||
Heading 3 Reader
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
Any function (async included) that returns the next line in a document when called and null when the end of the document has been reached.
|
||||
|
||||
CodeBlock typescript
|
||||
// Type Definition
|
||||
type Reader = () => string|null|Promise<string|null>
|
||||
|
||||
Heading 3 createStringReader()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
| source | string\|string[] | The lines to iterate over, as a multiline string or an array of line strings.
|
||||
| index | number | Optional - which line to start from.
|
||||
| **@returns** | [Reader](#reader) | A reader function that returns each line from the source document when called sequentially.
|
||||
|
||||
Get a simple [Reader](#reader) function that always returns the next line from a mutliline string or an array of line strings.
|
||||
CodeBlock typescript
|
||||
// Type Definition
|
||||
function createStringReader(path: string): Reader
|
||||
function createStringReader(source: string|string[], index: number = 0): Reader
|
||||
|
||||
// Import Path
|
||||
import { createStringReader } from '@terrace-lang/js/readers/js-string'
|
||||
|
||||
Markdown
|
||||
**Usage**
|
||||
CodeBlock typescript
|
||||
import { createStringReader, useDocument } from '@terrace-lang/js'
|
||||
|
||||
// Create a string reader with two lines
|
||||
const reader = createStringReader('title Example Title\n line2')
|
||||
// Also permitted:
|
||||
// const reader = createStringReader(['title Example Title', ' line 2'])
|
||||
|
||||
const { next, level, line } = useDocument(reader)
|
||||
await next()
|
||||
console.log(level(), line())
|
||||
// 0 title Example Title
|
||||
await next()
|
||||
console.log(level(), line())
|
||||
// 1 line 2
|
||||
|
||||
|
||||
Heading 3 createFileReader()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
| path | string | A path to the file to read.
|
||||
| **@returns** | [Reader](#reader) | A reader function that returns each line from the file when called sequentially
|
||||
|
||||
**Note:** Only available in Node.js environments.<br/>
|
||||
Get a [Reader](#reader) function that returns the next line from the specified file when called sequentially.
|
||||
|
||||
|
||||
CodeBlock typescript
|
||||
// Type Definition
|
||||
function createFileReader(path: string): Reader
|
||||
@ -381,14 +377,199 @@ Section light
|
||||
// Import Path
|
||||
import { createFileReader } from '@terrace-lang/js/readers/node-readline'
|
||||
|
||||
Markdown
|
||||
**Usage**
|
||||
CodeExample
|
||||
summary-class mb-[300px]
|
||||
pre-class max-h-[300px]
|
||||
javascript main.js
|
||||
import { createFileReader, useDocument } from '@terrace-lang/js'
|
||||
|
||||
// Read the file ./example.tce
|
||||
const { next, level, line } = useDocument(createFileReader('./example.tce'))
|
||||
await next()
|
||||
console.log(level(), line())
|
||||
// 0 title Example Title
|
||||
await next()
|
||||
console.log(level(), line())
|
||||
// 1 line 2
|
||||
|
||||
terrace example.tce
|
||||
title Example Title
|
||||
line 2
|
||||
|
||||
Heading 3 createStdinReader()
|
||||
class my-6
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
| **@returns** | [Reader](#reader) | A reader function that returns each line from `stdin` when called sequentially
|
||||
|
||||
**Note:** Only available in Node.js environments.<br/>
|
||||
Get a [Reader](#reader) function that returns the next line from standard input when called sequentially. Does not block stdin to wait for input. If no input is present it returns null immediately.
|
||||
CodeBlock typescript
|
||||
// Type Definition
|
||||
function createStdinReader(): Reader
|
||||
|
||||
// Import Path
|
||||
import { createStdinReader } from '@terrace-lang/js/readers/node-readline'
|
||||
Markdown
|
||||
**Usage**
|
||||
CodeExample
|
||||
summary-class mb-[250px]
|
||||
pre-class max-h-[250px]
|
||||
javascript main.js
|
||||
import { createStdinReader, useDocument } from '@terrace-lang/js'
|
||||
|
||||
// Read the contents of standard input
|
||||
const { next, level, line } = useDocument(createStdinReader())
|
||||
|
||||
while(await next()) {
|
||||
console.log(level(), line())
|
||||
// See `shell` panel above for output
|
||||
}
|
||||
|
||||
terrace example.tce
|
||||
title Example Title
|
||||
line 2
|
||||
|
||||
sh
|
||||
# Run main.js with the contents of example.tce piped to stdin
|
||||
$ cat example.tce > node ./main.js
|
||||
0 title Example Title
|
||||
1 line 2
|
||||
|
||||
Heading 3 createStreamReader()
|
||||
class mb-4 mt-12
|
||||
Markdown
|
||||
| Parameter | Type | Description
|
||||
| -------------- | --------------------- | -----------------------------------------------------------------------
|
||||
| stream | NodeJS.ReadStream|fs.ReadStream | A ReadStream compatible with Node.js `readline` APIs
|
||||
| **@returns** | [Reader](#reader) | A reader function that returns each line from `stdin` when called sequentially
|
||||
|
||||
**Note:** Only available in Node.js environments.<br/>
|
||||
Get a [Reader](#reader) function that always returns the next line from a passed read stream when called sequentially.
|
||||
CodeBlock typescript
|
||||
// Type Definition
|
||||
function createStreamReader(): Reader
|
||||
|
||||
// Import Path
|
||||
import { createStreamReader } from '@terrace-lang/js/readers/node-readline'
|
||||
Markdown
|
||||
**Usage**
|
||||
CodeExample
|
||||
summary-class mb-[320px]
|
||||
pre-class max-h-[320px]
|
||||
javascript main.js
|
||||
import fs from 'node:fs'
|
||||
import { createStreamReader, useDocument } from '@terrace-lang/js'
|
||||
|
||||
// Read the file ./example.tce - equivalent to the `createFileReader` example above.
|
||||
const reader = createStreamReader(fs.createReadStream('./example.tce'))
|
||||
const { next, level, line } = useDocument(reader)
|
||||
await next()
|
||||
console.log(level(), line())
|
||||
// 0 title Example Title
|
||||
await next()
|
||||
console.log(level(), line())
|
||||
// 1 line 2
|
||||
|
||||
terrace example.tce
|
||||
title Example Title
|
||||
line 2
|
||||
|
||||
Heading 2 Recipes
|
||||
class mt-12
|
||||
|
||||
Heading 3 Read object properties
|
||||
class mb-2
|
||||
Markdown
|
||||
Read known properties from a Terrace block and write them to an object.
|
||||
CodeBlock javascript
|
||||
// Provides simple convenience functions over the core parser
|
||||
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
|
||||
import { useDocument } from '@terrace-lang/js/document'
|
||||
// A helper for iterating over a string line-by-line
|
||||
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
|
||||
import { createStringReader } from '@terrace-lang/js/readers/js-string'
|
||||
|
||||
const input = `
|
||||
object
|
||||
string_property An example string
|
||||
numeric_property 4
|
||||
`
|
||||
|
||||
const output = {
|
||||
string_property: null,
|
||||
numeric_property: null
|
||||
}
|
||||
|
||||
// useDocument returns convenience functions
|
||||
const { next, level, head, tail, match } = useDocument(createStringReader(input))
|
||||
|
||||
// next() parses the next line in the document
|
||||
while (await next()) {
|
||||
// match('object') is equivalent to head() === 'object'
|
||||
// Essentially: "If the current line starts with 'object'"
|
||||
if (match('object')) {
|
||||
const objectLevel = level()
|
||||
// When we call next with a parent level it,
|
||||
// only iterates over lines inside the parent block
|
||||
while (await next(objectLevel)) {
|
||||
// tail() returns the part of the current line after the first space
|
||||
if (match('string_property')) output.string_property = tail()
|
||||
// parseFloat() here the string tail() to a numeric float value
|
||||
if (match('numeric_property')) output.numeric_property = parseFloat(tail())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.dir(output)
|
||||
// { string_property: 'An example string', numeric_property: 4 }
|
||||
|
||||
Markdown
|
||||
Read *all* properties as strings from a Terrace block and write them to an object.
|
||||
CodeBlock javascript
|
||||
// Provides simple convenience functions over the core parser
|
||||
// CommonJS: const { useDocument } = require('@terrace-lang/js/document')
|
||||
import { useDocument } from '@terrace-lang/js/document'
|
||||
// A helper for iterating over a string line-by-line
|
||||
// CommonJS: const { createStringReader } = require('@terrace-lang/js/readers/js-string')
|
||||
import { createStringReader } from '@terrace-lang/js/readers/js-string'
|
||||
|
||||
const input = `
|
||||
object
|
||||
property1 Value 1
|
||||
property2 Value 2
|
||||
random_property igazi3ii4quaC5OdoB5quohnah1beeNg
|
||||
`
|
||||
|
||||
const output = {}
|
||||
|
||||
// useDocument returns convenience functions
|
||||
const { next, level, head, tail, match } = useDocument(createStringReader(input))
|
||||
|
||||
// next() parses the next line in the document
|
||||
while (await next()) {
|
||||
// match('object') is equivalent to head() === 'object'
|
||||
// Essentially: "If the current line starts with 'object'"
|
||||
if (match('object')) {
|
||||
const objectLevel = level()
|
||||
// When we call next with a parent level,
|
||||
// it only iterates over lines inside the parent block
|
||||
while (await next(objectLevel)) {
|
||||
// Skip empty lines
|
||||
if (!line()) continue
|
||||
// Add any properties to the object as strings using the
|
||||
// line head() as the key and tail() as the value
|
||||
output[head()] = tail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.dir(output)
|
||||
// { property1: 'Value 1', property2: 'Value 2', random_property: 'igazi3ii4quaC5OdoB5quohnah1beeNg' }
|
||||
|
||||
|
||||
Heading 2 Contributing
|
||||
class mt-12
|
||||
|
@ -1,6 +1,6 @@
|
||||
const { contentAsText } = require('../helpers')
|
||||
|
||||
const languages = ['terrace', 'json', 'yaml', 'toml', 'javascript', 'typescript', 'c', 'python']
|
||||
const languages = ['terrace', 'json', 'yaml', 'toml', 'javascript', 'typescript', 'c', 'python', 'sh']
|
||||
|
||||
module.exports = async (doc, rootLevel) => {
|
||||
const { next, level, line, head, tail, match } = doc
|
||||
@ -23,7 +23,7 @@ module.exports = async (doc, rootLevel) => {
|
||||
node.examples.push({
|
||||
language: head(),
|
||||
name: tail() || '',
|
||||
code: await contentAsText(doc, exampleLevel)
|
||||
code: (await contentAsText(doc, exampleLevel)).trimEnd('\n')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,13 @@ module.exports = {
|
||||
fontFamily: {
|
||||
sans: ['Fredoka', ...defaultTheme.fontFamily.sans],
|
||||
},
|
||||
typography: {
|
||||
DEFAULT: {
|
||||
css: {
|
||||
maxWidth: '80ch'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
variants: {},
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Holds the parsed information from each line.
|
||||
export type LineData = {
|
||||
// Which character is being used for indentation. Avoids having to specify it on each terrace_parse_line call.
|
||||
// Which character is being used for indentation. Avoids having to specify it on each parseLine call.
|
||||
indent: string;
|
||||
// How many indent characters are present in the current line before the first non-indent character.
|
||||
level: number;
|
||||
@ -12,7 +12,7 @@ export type LineData = {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a LineData instance with default values.
|
||||
* Initialize a LineData instance with default values to pass to parseLine()
|
||||
* @param {string} indent The character to use for indenting lines. ONLY ONE CHARACTER IS CURRENTLY PERMITTED.
|
||||
* @returns {LineData} A LineData instance with the specified indent character and all other values initialized to 0.
|
||||
*/
|
||||
@ -21,10 +21,10 @@ export function createLineData(indent: string = ' '): LineData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Core Terrace parser function, sets level, offsetHead, and offsetTail in a LineData object based on the current line.
|
||||
* Core Terrace parser function, sets level, offsetHead, and offsetTail in a LineData object based on the passed line.
|
||||
* Note that this is a C-style function, lineData is treated as a reference and mutated in-place.
|
||||
* @param {string} line A string containing a line to parse. Shouldn't end with a newline.
|
||||
* @param {LineData} lineData A LineData object to store information about the current line in. **Mutated in-place!**
|
||||
* @param {LineData} lineData A LineData object to store information about the current line, from `createLineData()` **Mutated in-place!**
|
||||
*/
|
||||
export function parseLine(line: string, lineData: LineData) {
|
||||
if ((typeof lineData !== 'object' || !lineData) || typeof lineData.level !== 'number') throw new Error(`'lineData' must be an object with string line and numeric level properties`)
|
||||
|
@ -1,7 +1,15 @@
|
||||
import type { Reader } from './reader'
|
||||
|
||||
export function createStringReader(doc: string|string[], index = 0): Reader {
|
||||
const lines = Array.isArray(doc) ? doc : doc.split('\n')
|
||||
/**
|
||||
* Get a simple `Reader` function that always returns the next line
|
||||
* from a multiline string or an array of line strings.
|
||||
*
|
||||
* @param {string|string[]} source The lines to iterate over, as a multiline string or an array of line strings.
|
||||
* @param {number} index Optional - which line to start from.
|
||||
* @returns {Reader} A reader function that returns each line from the source document when called sequentially.
|
||||
*/
|
||||
export function createStringReader(source: string|string[], index: number = 0): Reader {
|
||||
const lines = Array.isArray(source) ? source : source.split('\n')
|
||||
|
||||
index--;
|
||||
|
||||
|
@ -2,18 +2,36 @@ import fs from 'node:fs'
|
||||
import readline from 'node:readline/promises'
|
||||
import type { Reader } from './reader'
|
||||
|
||||
|
||||
/**
|
||||
* Get a `Reader` function that always returns the next line from a passed read stream when called sequentially.
|
||||
* @param {NodeJS.ReadStream|fs.ReadStream} stream A ReadStream compatible with Node.js `readline` APIs
|
||||
* @returns {Reader} A reader function that returns each line from the stream when called sequentially
|
||||
*/
|
||||
export function createStreamReader(stream: NodeJS.ReadStream|fs.ReadStream): Reader {
|
||||
// A bit of a messy way of working with readline, but the most straightforward
|
||||
// way I found that allowed pulling lines with a promise-style interface.
|
||||
const iterator = readline.createInterface({
|
||||
input: stream
|
||||
})[Symbol.asyncIterator]()
|
||||
|
||||
return async () => (await iterator.next()).value
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a `Reader` function that always returns the next line from the specified file when called sequentially.
|
||||
* @param {string} path A path to the file to read.
|
||||
* @returns {Reader} A reader function that returns each line from the file when called sequentially
|
||||
*/
|
||||
export function createFileReader(path: string): Reader {
|
||||
const it = readline.createInterface({
|
||||
input: fs.createReadStream(path, 'utf-8'),
|
||||
})[Symbol.asyncIterator]()
|
||||
|
||||
return async () => (await it.next()).value
|
||||
return createStreamReader(fs.createReadStream(path, 'utf-8'))
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a `Reader` function that always returns the next line from `stdin` when called sequentially.
|
||||
* Does not block stdin to wait for input. If no input is present it returns null immediately.
|
||||
* @returns {Reader} A reader function that returns each line from the stdin when called sequentially.
|
||||
*/
|
||||
export function createStdinReader(): Reader {
|
||||
const it = readline.createInterface({
|
||||
input: process.stdin
|
||||
})[Symbol.asyncIterator]()
|
||||
|
||||
return async () => (await it.next()).value
|
||||
return createStreamReader(process.stdin)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user