📝🗄️
parent
7ec9978919
commit
a5a1df24f0
126
README.md
126
README.md
|
@ -2,18 +2,127 @@
|
||||||
|
|
||||||
for expanding random table entries
|
for expanding random table entries
|
||||||
|
|
||||||
|
1. [Requirements](#requirements)
|
||||||
|
2. [Installing](#installing)
|
||||||
|
3. [Architecture](#architecture)
|
||||||
|
4. [Tutorial](#tutorial)
|
||||||
|
* [Random Selections](#random-selections)
|
||||||
|
* [Expansion](#expansion)
|
||||||
|
* [Filters](#filters)
|
||||||
|
5. [Roadmap](#roadmap)
|
||||||
|
6. [Resources](#resources)
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
Built with
|
- Fennel 1.3.1 on PUC Lua 5.4
|
||||||
Fennel 1.3.1 on PUC Lua 5.4
|
- gnu recutils 1.9: for querying metadata
|
||||||
|
- just 1.34.0: just a task runner
|
||||||
|
|
||||||
## Usage
|
## Installing
|
||||||
|
|
||||||
You can run the script: `fennel src/main.fnl`.
|
You can run the script: `fennel src/main.fnl`.
|
||||||
|
|
||||||
Or you can compile a binary and use that.
|
Or you can compile a binary and use that.
|
||||||
See `just compile`.
|
See `just compile`.
|
||||||
|
|
||||||
|
There is also a vim plugin for the `tbls` format.
|
||||||
|
See `vim-tbls/README.md`.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- `src/story.fnl`: core of the project. where all the file handling and text parsing happens
|
||||||
|
- `src/main.fnl`: wrapper for story.fnl. the ui.
|
||||||
|
- `src/filter.fnl` logic for applying filters to strings
|
||||||
|
- `lib/*.fnl` libraries and helper functions
|
||||||
|
|
||||||
|
![Autogenerated Dependency Graph][deps]
|
||||||
|
|
||||||
|
[deps]: doc/deps.png "Autogenerated Dependency Graph"
|
||||||
|
|
||||||
|
## Tutorial
|
||||||
|
|
||||||
|
### Random Selections
|
||||||
|
|
||||||
|
At its most basic, `tbls` selects a random element from a table.
|
||||||
|
|
||||||
|
Suppose you have a few tables:
|
||||||
|
|
||||||
|
```
|
||||||
|
:: suit
|
||||||
|
Hearts
|
||||||
|
Bells
|
||||||
|
Whistles
|
||||||
|
Cups
|
||||||
|
Knives
|
||||||
|
Shovels
|
||||||
|
|
||||||
|
:: card
|
||||||
|
Ace
|
||||||
|
One
|
||||||
|
Two
|
||||||
|
[...]
|
||||||
|
Queen
|
||||||
|
King
|
||||||
|
Beast
|
||||||
|
```
|
||||||
|
|
||||||
|
`tbls` might return "Whistles" from suit.
|
||||||
|
Or "Two" from card.
|
||||||
|
|
||||||
|
### Expansion
|
||||||
|
|
||||||
|
But wait there's more.
|
||||||
|
`tbls` will also expand certain text found in a table entry.
|
||||||
|
|
||||||
|
Let's add another table:
|
||||||
|
|
||||||
|
```
|
||||||
|
:: draw
|
||||||
|
[card] of [suit]
|
||||||
|
```
|
||||||
|
|
||||||
|
When you place the name of a table in `[squarebrackets]`,
|
||||||
|
then `tbls` views that as a placeholder
|
||||||
|
for a random item from that table.
|
||||||
|
It will expand that text.
|
||||||
|
So 'draw' might end up being "Thief of Shovels"
|
||||||
|
or "Twelve or Cups".
|
||||||
|
|
||||||
|
### Filters
|
||||||
|
|
||||||
|
`tbls` can run arbitary filters on text after expanding it.
|
||||||
|
Example filters can be found in `lib/filters.fnl`.
|
||||||
|
|
||||||
|
To apply filters,
|
||||||
|
dot-chain them at the end
|
||||||
|
of a table reference.
|
||||||
|
|
||||||
|
Consider the following tables:
|
||||||
|
|
||||||
|
```
|
||||||
|
:: origin
|
||||||
|
Evelyn eats one [fruit.c]
|
||||||
|
Evelyn eats many [fruit.c.s]
|
||||||
|
|
||||||
|
:: fruit
|
||||||
|
banana
|
||||||
|
apple
|
||||||
|
pear
|
||||||
|
```
|
||||||
|
|
||||||
|
`s`, `plural`, and `pluralize`
|
||||||
|
are all different ways
|
||||||
|
to call the 'plural' filter function.
|
||||||
|
`c` is 'capitalize.'
|
||||||
|
|
||||||
|
Example output:
|
||||||
|
|
||||||
|
```
|
||||||
|
Evelyn eats one Pear
|
||||||
|
Evelyn eats many Bananas
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
- [x] random table entries (ADDED in vHydrogen)
|
- [x] random table entries (ADDED in vHydrogen)
|
||||||
|
@ -25,10 +134,13 @@ See `just compile`.
|
||||||
## Resources
|
## Resources
|
||||||
|
|
||||||
inspired heavily by tracery:
|
inspired heavily by tracery:
|
||||||
https://github.com/galaxykate/tracery
|
<https://github.com/galaxykate/tracery>
|
||||||
|
|
||||||
and paper elemental's list-to-html generator:
|
and this list-to-html geneator from slight adjustments:
|
||||||
https://paperelemental.blogspot.com/p/list-to-html-generator.html
|
<https://slightadjustments.blogspot.com/p/generator.html>
|
||||||
|
|
||||||
|
but also paper elemental's:
|
||||||
|
<https://paperelemental.blogspot.com/p/list-to-html-generator.html>
|
||||||
|
|
||||||
and perchance:
|
and perchance:
|
||||||
https://perchance.org/welcome
|
<https://perchance.org/welcome>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Tutorial
|
## Tutorial
|
||||||
|
|
||||||
## Random Selections
|
### Random Selections
|
||||||
|
|
||||||
At its most basic, `tbls` selects a random element from a table.
|
At its most basic, `tbls` selects a random element from a table.
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ Beast
|
||||||
`tbls` might return "Whistles" from suit.
|
`tbls` might return "Whistles" from suit.
|
||||||
Or "Two" from card.
|
Or "Two" from card.
|
||||||
|
|
||||||
## Expansion
|
### Expansion
|
||||||
|
|
||||||
But wait there's more.
|
But wait there's more.
|
||||||
`tbls` will also expand certain text found in a table entry.
|
`tbls` will also expand certain text found in a table entry.
|
||||||
|
@ -47,10 +47,10 @@ It will expand that text.
|
||||||
So 'draw' might end up being "Thief of Shovels"
|
So 'draw' might end up being "Thief of Shovels"
|
||||||
or "Twelve or Cups".
|
or "Twelve or Cups".
|
||||||
|
|
||||||
## Filters
|
### Filters
|
||||||
|
|
||||||
`tbls` can run arbitary filters on text after expanding it.
|
`tbls` can run arbitary filters on text after expanding it.
|
||||||
Example filters can be found in `src/flib.fnl`.
|
Example filters can be found in `lib/filters.fnl`.
|
||||||
|
|
||||||
To apply filters,
|
To apply filters,
|
||||||
dot-chain them at the end
|
dot-chain them at the end
|
||||||
|
@ -60,8 +60,8 @@ Consider the following tables:
|
||||||
|
|
||||||
```
|
```
|
||||||
:: origin
|
:: origin
|
||||||
Evelyn eats one [fruit]
|
Evelyn eats one [fruit.c]
|
||||||
Evelyn eats many [fruit.s]
|
Evelyn eats many [fruit.c.s]
|
||||||
|
|
||||||
:: fruit
|
:: fruit
|
||||||
banana
|
banana
|
||||||
|
@ -72,10 +72,11 @@ pear
|
||||||
`s`, `plural`, and `pluralize`
|
`s`, `plural`, and `pluralize`
|
||||||
are all different ways
|
are all different ways
|
||||||
to call the 'plural' filter function.
|
to call the 'plural' filter function.
|
||||||
|
`c` is 'capitalize.'
|
||||||
|
|
||||||
Example output:
|
Example output:
|
||||||
|
|
||||||
```
|
```
|
||||||
Evelyn eats one pear
|
Evelyn eats one Pear
|
||||||
Evelyn eats one bananas
|
Evelyn eats many Bananas
|
||||||
```
|
```
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
|
@ -0,0 +1,65 @@
|
||||||
|
changequote(<!,!>)dnl Or else `code blocks` confuse m4
|
||||||
|
# tbls
|
||||||
|
|
||||||
|
for expanding random table entries
|
||||||
|
|
||||||
|
1. [Requirements](#requirements)
|
||||||
|
2. [Installing](#installing)
|
||||||
|
3. [Architecture](#architecture)
|
||||||
|
4. [Tutorial](#tutorial)
|
||||||
|
* [Random Selections](#random-selections)
|
||||||
|
* [Expansion](#expansion)
|
||||||
|
* [Filters](#filters)
|
||||||
|
5. [Roadmap](#roadmap)
|
||||||
|
6. [Resources](#resources)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Fennel 1.3.1 on PUC Lua 5.4
|
||||||
|
- gnu recutils 1.9: for querying metadata
|
||||||
|
- just 1.34.0: just a task runner
|
||||||
|
|
||||||
|
## Installing
|
||||||
|
|
||||||
|
You can run the script: `fennel src/main.fnl`.
|
||||||
|
|
||||||
|
Or you can compile a binary and use that.
|
||||||
|
See `just compile`.
|
||||||
|
|
||||||
|
There is also a vim plugin for the `tbls` format.
|
||||||
|
See `vim-tbls/README.md`.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
- `src/story.fnl`: core of the project. where all the file handling and text parsing happens
|
||||||
|
- `src/main.fnl`: wrapper for story.fnl. the ui.
|
||||||
|
- `src/filter.fnl` logic for applying filters to strings
|
||||||
|
- `lib/*.fnl` libraries and helper functions
|
||||||
|
|
||||||
|
![Autogenerated Dependency Graph][deps]
|
||||||
|
|
||||||
|
[deps]: doc/deps.png "Autogenerated Dependency Graph"
|
||||||
|
|
||||||
|
include(<!doc/Tutorial.md!>)
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- [x] random table entries (ADDED in vHydrogen)
|
||||||
|
- [x] expanding macros (ADDED in vHydrogen)
|
||||||
|
- [x] table files plugin: syntax highlighting + folding (ADDED vHelium)
|
||||||
|
- [x] expansion filters (ADDED vHelium)
|
||||||
|
- [ ] table context
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
inspired heavily by tracery:
|
||||||
|
<https://github.com/galaxykate/tracery>
|
||||||
|
|
||||||
|
and this list-to-html geneator from slight adjustments:
|
||||||
|
<https://slightadjustments.blogspot.com/p/generator.html>
|
||||||
|
|
||||||
|
but also paper elemental's:
|
||||||
|
<https://paperelemental.blogspot.com/p/list-to-html-generator.html>
|
||||||
|
|
||||||
|
and perchance:
|
||||||
|
<https://perchance.org/welcome>
|
95
justfile
95
justfile
|
@ -1,42 +1,85 @@
|
||||||
|
set quiet
|
||||||
|
|
||||||
# show all recipes
|
# show all recipes
|
||||||
default:
|
default:
|
||||||
just --list --unsorted
|
just --list --unsorted
|
||||||
|
|
||||||
# compile binary
|
# compile binary
|
||||||
|
[group('build')]
|
||||||
compile:
|
compile:
|
||||||
fennel --compile-binary src/main.fnl tbls /usr/local/lib/liblua.a /usr/local/include/lua5.4
|
fennel --compile-binary src/main.fnl tbls /usr/local/lib/liblua.a /usr/local/include/lua5.4
|
||||||
|
alias build := compile
|
||||||
|
|
||||||
# run test file
|
# install all
|
||||||
_test-story:
|
[group('install')]
|
||||||
fennel test/story.test.fnl
|
install: install-plugin install-binary
|
||||||
|
|
||||||
# test main
|
|
||||||
_test-main:
|
|
||||||
for i in $(seq 1 10); do fennel src/main.fnl -i test/morpheme-word-epithet.txt -k name; done
|
|
||||||
|
|
||||||
# run all tests
|
|
||||||
test: _test-main _test-story
|
|
||||||
|
|
||||||
# bump version
|
|
||||||
bump:
|
|
||||||
#!/usr/local/bin/bash
|
|
||||||
currname=$(recsel doc/meta.rec -P version)
|
|
||||||
currnum=$(recsel doc/versions.rec -e "Name = '$currname'" -P Number)
|
|
||||||
nextnum=$((currnum + 1))
|
|
||||||
nextname=$(recsel doc/versions.rec -e "Number = $nextnum" -P Name)
|
|
||||||
echo "Bumping version from $currname to $nextname:"
|
|
||||||
recset doc/meta.rec -f version -s $nextname
|
|
||||||
recset doc/meta.rec -f updated -S $(gdate +'%Y-%m-%d')
|
|
||||||
recsel doc/meta.rec
|
|
||||||
|
|
||||||
# show full metadata
|
|
||||||
meta:
|
|
||||||
awk 'FNR==1{print ""}{print}' doc/*.rec | recsel -t meta -j version
|
|
||||||
|
|
||||||
# install vim plugin
|
# install vim plugin
|
||||||
|
[group('install')]
|
||||||
install-plugin:
|
install-plugin:
|
||||||
cp -r vim-tbls/* ~/.config/nvim
|
cp -r vim-tbls/* ~/.config/nvim
|
||||||
|
|
||||||
# install binary
|
# install binary
|
||||||
|
[group('install')]
|
||||||
install-binary: compile
|
install-binary: compile
|
||||||
cp tbls ~/bin
|
cp tbls ~/bin
|
||||||
|
|
||||||
|
# run all tests
|
||||||
|
[group('test')]
|
||||||
|
test: test-main test-story
|
||||||
|
|
||||||
|
# run test file
|
||||||
|
[group('test')]
|
||||||
|
test-story:
|
||||||
|
fennel test/story.test.fnl
|
||||||
|
|
||||||
|
# test main
|
||||||
|
[group('test')]
|
||||||
|
test-main:
|
||||||
|
for i in $(seq 1 10); do fennel src/main.fnl -i test/morpheme-word-epithet.txt -k name; done
|
||||||
|
|
||||||
|
# build all docs
|
||||||
|
[group('docs')]
|
||||||
|
docs: deps readme
|
||||||
|
|
||||||
|
# build readme
|
||||||
|
[group('docs')]
|
||||||
|
readme:
|
||||||
|
m4 doc/src/readme.m4 > README.md
|
||||||
|
|
||||||
|
# create dependency graph
|
||||||
|
[group('docs')]
|
||||||
|
deps:
|
||||||
|
ag require src \
|
||||||
|
| sed 's/\(.*\.fnl\).*require :\([^\.]*\)\.\([^)]*\)).*/"\1" -> "\2\/\3.fnl"/' \
|
||||||
|
| awk 'BEGIN { print "digraph {" } { print } END { print "}" }' \
|
||||||
|
| dot -Tpng \
|
||||||
|
> doc/deps.png
|
||||||
|
|
||||||
|
# create dependency graph but sixel
|
||||||
|
[group('docs')]
|
||||||
|
depsxl:
|
||||||
|
ag require src \
|
||||||
|
| sed 's/\(.*\.fnl\).*require :\([^\.]*\)\.\([^)]*\)).*/"\1" -> "\2\/\3.fnl"/' \
|
||||||
|
| awk 'BEGIN { print "digraph {" } { print } END { print "}" }' \
|
||||||
|
| dot -Tpng \
|
||||||
|
| magick - -geometry 800 sixel:-
|
||||||
|
|
||||||
|
# bump version
|
||||||
|
[group('docs')]
|
||||||
|
bump:
|
||||||
|
#!/usr/local/bin/bash
|
||||||
|
currname=$(recsel doc/v/meta.rec -P version)
|
||||||
|
currnum=$(recsel doc/v/versions.rec -e "Name = '$currname'" -P Number)
|
||||||
|
nextnum=$((currnum + 1))
|
||||||
|
nextname=$(recsel doc/v/versions.rec -e "Number = $nextnum" -P Name)
|
||||||
|
echo "Bumping version from $currname to $nextname:"
|
||||||
|
recset doc/v/meta.rec -f version -s $nextname
|
||||||
|
recset doc/v/meta.rec -f updated -S $(gdate +'%Y-%m-%d')
|
||||||
|
recsel doc/v/meta.rec
|
||||||
|
|
||||||
|
# show full metadata
|
||||||
|
[group('docs')]
|
||||||
|
meta:
|
||||||
|
awk 'FNR==1{print ""}{print}' doc/v/*.rec | recsel -t meta -j version
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
(local {: contains?} (require :src.table))
|
(local {: contains?} (require :lib.table))
|
||||||
(local {:split split-full} (require :src.string))
|
(local {:split split-full} (require :lib.string))
|
||||||
(local split (partial split-full "[^%.]*"))
|
(local split (partial split-full "[^%.]*"))
|
||||||
|
|
||||||
(fn filter [s]
|
(fn filter [s]
|
||||||
(let [filters (require :src.flib)
|
(let [filters (require :lib.filters)
|
||||||
[str & funs] (split s)]
|
[str & funs] (split s)]
|
||||||
(var res str)
|
(var res str)
|
||||||
(each [_ f (ipairs funs)]
|
(each [_ f (ipairs funs)]
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
(print)
|
(print)
|
||||||
(print "Basic Options:")
|
(print "Basic Options:")
|
||||||
(print " -h|--help print this message and exit")
|
(print " -h|--help print this message and exit")
|
||||||
|
(print " -v|--version print version and exit")
|
||||||
(print " -i|--input <file> name of input file")
|
(print " -i|--input <file> name of input file")
|
||||||
(print " -k|--origin-table-key <key> name of a table in the input file")
|
(print " -k|--origin-table-key <key> name of a table in the input file")
|
||||||
(print " -s|--origin-table-string <string> a string template")
|
(print " -s|--origin-table-string <string> a string template")
|
||||||
|
@ -28,6 +29,12 @@
|
||||||
(do
|
(do
|
||||||
(show-help)
|
(show-help)
|
||||||
(os.exit 0))
|
(os.exit 0))
|
||||||
|
(where [a] (or (= a "-v") (= a "--version")))
|
||||||
|
(let [handle (io.popen "recsel doc/meta.rec -P version")
|
||||||
|
result (handle:read "*a")]
|
||||||
|
(print result)
|
||||||
|
(handle:close)
|
||||||
|
(os.exit 0))
|
||||||
(where [a input] (or (= a "-i") (= a "--input")))
|
(where [a input] (or (= a "-i") (= a "--input")))
|
||||||
(set opts.input input)
|
(set opts.input input)
|
||||||
(where [a key] (or (= a "-k") (= a "--origin-table-key")))
|
(where [a key] (or (= a "-k") (= a "--origin-table-key")))
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
;; helper funs
|
;; helper funs
|
||||||
(local tbl (require :src.table))
|
(local tbl (require :lib.table))
|
||||||
(local {: filter} (require :src.filter))
|
(local {: filter} (require :src.filter))
|
||||||
(local {:split _split} (require :src.string))
|
(local split
|
||||||
(local split (partial _split "[^%.]*"))
|
(partial (. (require :lib.string) :split) "[^%.]*"))
|
||||||
|
|
||||||
(fn lines [filename callback]
|
(fn lines [filename callback]
|
||||||
(case (pcall #(with-open [file (io.open filename)] (each [line (file:lines)] (callback line))))
|
(case (pcall #(with-open [file (io.open filename)] (each [line (file:lines)] (callback line))))
|
||||||
|
@ -58,7 +58,9 @@
|
||||||
str
|
str
|
||||||
(do
|
(do
|
||||||
(assert (tbl.has-key? corpus word)
|
(assert (tbl.has-key? corpus word)
|
||||||
(string.format "Error trying to expand \"%s\". Corpus does not contain a table called \"%s\"" str word))
|
(string.format
|
||||||
|
"Error trying to expand \"%s\". Corpus does not contain a table called \"%s\""
|
||||||
|
str word))
|
||||||
(let [next-str (string.format "%s%s%s"
|
(let [next-str (string.format "%s%s%s"
|
||||||
(string.sub str 1 (- i 1))
|
(string.sub str 1 (- i 1))
|
||||||
(if (length fs)
|
(if (length fs)
|
||||||
|
|
Loading…
Reference in New Issue