diff --git a/README.md b/README.md index f9c2473..4955f01 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,127 @@ 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 -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`. 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" + +## 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 - [x] random table entries (ADDED in vHydrogen) @@ -25,10 +134,13 @@ See `just compile`. ## Resources inspired heavily by tracery: -https://github.com/galaxykate/tracery + -and paper elemental's list-to-html generator: -https://paperelemental.blogspot.com/p/list-to-html-generator.html +and this list-to-html geneator from slight adjustments: + + +but also paper elemental's: + and perchance: -https://perchance.org/welcome + diff --git a/doc/Tutorial.md b/doc/Tutorial.md index e13616f..9ae6f01 100644 --- a/doc/Tutorial.md +++ b/doc/Tutorial.md @@ -1,6 +1,6 @@ -# Tutorial +## Tutorial -## Random Selections +### Random Selections At its most basic, `tbls` selects a random element from a table. @@ -28,7 +28,7 @@ Beast `tbls` might return "Whistles" from suit. Or "Two" from card. -## Expansion +### Expansion But wait there's more. `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" or "Twelve or Cups". -## Filters +### Filters `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, dot-chain them at the end @@ -60,8 +60,8 @@ Consider the following tables: ``` :: origin -Evelyn eats one [fruit] -Evelyn eats many [fruit.s] +Evelyn eats one [fruit.c] +Evelyn eats many [fruit.c.s] :: fruit banana @@ -72,10 +72,11 @@ 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 one bananas +Evelyn eats one Pear +Evelyn eats many Bananas ``` diff --git a/doc/deps.png b/doc/deps.png new file mode 100644 index 0000000..0d786e0 Binary files /dev/null and b/doc/deps.png differ diff --git a/doc/src/readme.m4 b/doc/src/readme.m4 new file mode 100644 index 0000000..a523173 --- /dev/null +++ b/doc/src/readme.m4 @@ -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() + +## 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: + + +and this list-to-html geneator from slight adjustments: + + +but also paper elemental's: + + +and perchance: + diff --git a/doc/meta.rec b/doc/v/meta.rec similarity index 100% rename from doc/meta.rec rename to doc/v/meta.rec diff --git a/doc/versions.rec b/doc/v/versions.rec similarity index 100% rename from doc/versions.rec rename to doc/v/versions.rec diff --git a/justfile b/justfile index 95eb57c..b473948 100644 --- a/justfile +++ b/justfile @@ -1,42 +1,85 @@ +set quiet + # show all recipes default: just --list --unsorted # compile binary +[group('build')] compile: fennel --compile-binary src/main.fnl tbls /usr/local/lib/liblua.a /usr/local/include/lua5.4 +alias build := compile -# run test file -_test-story: - fennel test/story.test.fnl - -# 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 all +[group('install')] +install: install-plugin install-binary # install vim plugin +[group('install')] install-plugin: cp -r vim-tbls/* ~/.config/nvim # install binary +[group('install')] install-binary: compile 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 + diff --git a/src/flib.fnl b/lib/filters.fnl similarity index 100% rename from src/flib.fnl rename to lib/filters.fnl diff --git a/src/string.fnl b/lib/string.fnl similarity index 100% rename from src/string.fnl rename to lib/string.fnl diff --git a/src/table.fnl b/lib/table.fnl similarity index 100% rename from src/table.fnl rename to lib/table.fnl diff --git a/src/filter.fnl b/src/filter.fnl index 29d7c5b..6d81223 100644 --- a/src/filter.fnl +++ b/src/filter.fnl @@ -1,9 +1,9 @@ -(local {: contains?} (require :src.table)) -(local {:split split-full} (require :src.string)) +(local {: contains?} (require :lib.table)) +(local {:split split-full} (require :lib.string)) (local split (partial split-full "[^%.]*")) (fn filter [s] - (let [filters (require :src.flib) + (let [filters (require :lib.filters) [str & funs] (split s)] (var res str) (each [_ f (ipairs funs)] diff --git a/src/main.fnl b/src/main.fnl index a509950..0c230ee 100644 --- a/src/main.fnl +++ b/src/main.fnl @@ -8,6 +8,7 @@ (print) (print "Basic Options:") (print " -h|--help print this message and exit") + (print " -v|--version print version and exit") (print " -i|--input name of input file") (print " -k|--origin-table-key name of a table in the input file") (print " -s|--origin-table-string a string template") @@ -28,6 +29,12 @@ (do (show-help) (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"))) (set opts.input input) (where [a key] (or (= a "-k") (= a "--origin-table-key"))) diff --git a/src/story.fnl b/src/story.fnl index 2b5b68c..d5c3597 100644 --- a/src/story.fnl +++ b/src/story.fnl @@ -1,8 +1,8 @@ ;; helper funs -(local tbl (require :src.table)) +(local tbl (require :lib.table)) (local {: filter} (require :src.filter)) -(local {:split _split} (require :src.string)) -(local split (partial _split "[^%.]*")) +(local split + (partial (. (require :lib.string) :split) "[^%.]*")) (fn lines [filename callback] (case (pcall #(with-open [file (io.open filename)] (each [line (file:lines)] (callback line)))) @@ -58,7 +58,9 @@ str (do (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" (string.sub str 1 (- i 1)) (if (length fs)