commit
365fabdf67
|
@ -0,0 +1 @@
|
|||
tbls
|
|
@ -0,0 +1,33 @@
|
|||
# tbls
|
||||
|
||||
for expanding random table entries
|
||||
|
||||
## Requirements
|
||||
|
||||
Built with
|
||||
Fennel 1.3.1 on PUC Lua 5.4
|
||||
|
||||
## Usage
|
||||
|
||||
You can run the script: `fennel src/main.fnl`.
|
||||
|
||||
Or you can compile a binary and use that.
|
||||
See `just compile`.
|
||||
|
||||
## Roadmap
|
||||
|
||||
- [x] random table entries (ADDED in vHydrogen)
|
||||
- [x] expanding macros (ADDED in vHydrogen)
|
||||
- [ ] table files plugin: syntax highlighting + folding
|
||||
- [ ] expansion filters
|
||||
|
||||
## 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 perchance:
|
||||
https://perchance.org/welcome
|
|
@ -0,0 +1,48 @@
|
|||
## Tutorial
|
||||
|
||||
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
|
||||
...
|
||||
Ten
|
||||
Eleven
|
||||
Twelve
|
||||
Thief
|
||||
Queen
|
||||
King
|
||||
Beast
|
||||
```
|
||||
|
||||
`tbls` might return "Whistles" from suit.
|
||||
Or "Twelve" from card.
|
||||
|
||||
But wait there's more.
|
||||
`tbls` will also expand macros found in table entries.
|
||||
|
||||
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.
|
||||
And it will expand the text.
|
||||
So this might end up being "Thief of Shovels"
|
||||
or "Twelve or Cups".
|
|
@ -0,0 +1,9 @@
|
|||
%rec: meta
|
||||
%doc: project metadata
|
||||
%type: version rec version
|
||||
|
||||
name: tbls
|
||||
author: dozens@tilde.team
|
||||
created: 2024-07-31
|
||||
updated: 2024-08-01
|
||||
version: Hydrogen
|
|
@ -0,0 +1,481 @@
|
|||
%rec: version
|
||||
%doc: a table of version names for "tables" based on the most famous table
|
||||
%type: Number int
|
||||
%type: Symbol,Name line
|
||||
%allowed: Number Symbol Name
|
||||
%mandatory: Number Symbol Name
|
||||
%unique: Number Symbol Name
|
||||
%sort: Number
|
||||
%key: Name
|
||||
|
||||
Number: 1
|
||||
Symbol: H
|
||||
Name: Hydrogen
|
||||
|
||||
Number: 2
|
||||
Symbol: He
|
||||
Name: Helium
|
||||
|
||||
Number: 3
|
||||
Symbol: Li
|
||||
Name: Lithium
|
||||
|
||||
Number: 4
|
||||
Symbol: Be
|
||||
Name: Beryllium
|
||||
|
||||
Number: 5
|
||||
Symbol: B
|
||||
Name: Boron
|
||||
|
||||
Number: 6
|
||||
Symbol: C
|
||||
Name: Carbon
|
||||
|
||||
Number: 7
|
||||
Symbol: N
|
||||
Name: Nitrogen
|
||||
|
||||
Number: 8
|
||||
Symbol: O
|
||||
Name: Oxygen
|
||||
|
||||
Number: 9
|
||||
Symbol: F
|
||||
Name: Fluorine
|
||||
|
||||
Number: 10
|
||||
Symbol: Ne
|
||||
Name: Neon
|
||||
|
||||
Number: 11
|
||||
Symbol: Na
|
||||
Name: Sodium
|
||||
|
||||
Number: 12
|
||||
Symbol: Mg
|
||||
Name: Magnesium
|
||||
|
||||
Number: 13
|
||||
Symbol: Al
|
||||
Name: Aluminum
|
||||
|
||||
Number: 14
|
||||
Symbol: Si
|
||||
Name: Silicon
|
||||
|
||||
Number: 15
|
||||
Symbol: P
|
||||
Name: Phosphorus
|
||||
|
||||
Number: 16
|
||||
Symbol: S
|
||||
Name: Sulfur
|
||||
|
||||
Number: 17
|
||||
Symbol: Cl
|
||||
Name: Chlorine
|
||||
|
||||
Number: 18
|
||||
Symbol: Ar
|
||||
Name: Argon
|
||||
|
||||
Number: 19
|
||||
Symbol: K
|
||||
Name: Potassium
|
||||
|
||||
Number: 20
|
||||
Symbol: Ca
|
||||
Name: Calcium
|
||||
|
||||
Number: 21
|
||||
Symbol: Sc
|
||||
Name: Scandium
|
||||
|
||||
Number: 22
|
||||
Symbol: Ti
|
||||
Name: Titanium
|
||||
|
||||
Number: 23
|
||||
Symbol: V
|
||||
Name: Vanadium
|
||||
|
||||
Number: 24
|
||||
Symbol: Cr
|
||||
Name: Chromium
|
||||
|
||||
Number: 25
|
||||
Symbol: Mn
|
||||
Name: Manganese
|
||||
|
||||
Number: 26
|
||||
Symbol: Fe
|
||||
Name: Iron
|
||||
|
||||
Number: 27
|
||||
Symbol: Co
|
||||
Name: Cobalt
|
||||
|
||||
Number: 28
|
||||
Symbol: Ni
|
||||
Name: Nickel
|
||||
|
||||
Number: 29
|
||||
Symbol: Cu
|
||||
Name: Copper
|
||||
|
||||
Number: 30
|
||||
Symbol: Zn
|
||||
Name: Zinc
|
||||
|
||||
Number: 31
|
||||
Symbol: Ga
|
||||
Name: Gallium
|
||||
|
||||
Number: 32
|
||||
Symbol: Ge
|
||||
Name: Germanium
|
||||
|
||||
Number: 33
|
||||
Symbol: As
|
||||
Name: Arsenic
|
||||
|
||||
Number: 34
|
||||
Symbol: Se
|
||||
Name: Selenium
|
||||
|
||||
Number: 35
|
||||
Symbol: Br
|
||||
Name: Bromine
|
||||
|
||||
Number: 36
|
||||
Symbol: Kr
|
||||
Name: Krypton
|
||||
|
||||
Number: 37
|
||||
Symbol: Rb
|
||||
Name: Rubidium
|
||||
|
||||
Number: 38
|
||||
Symbol: Sr
|
||||
Name: Strontium
|
||||
|
||||
Number: 39
|
||||
Symbol: Y
|
||||
Name: Yttrium
|
||||
|
||||
Number: 40
|
||||
Symbol: Zr
|
||||
Name: Zirconium
|
||||
|
||||
Number: 41
|
||||
Symbol: Nb
|
||||
Name: Niobium
|
||||
|
||||
Number: 42
|
||||
Symbol: Mo
|
||||
Name: Molybdenum
|
||||
|
||||
Number: 43
|
||||
Symbol: Tc
|
||||
Name: Technetium
|
||||
|
||||
Number: 44
|
||||
Symbol: Ru
|
||||
Name: Ruthenium
|
||||
|
||||
Number: 45
|
||||
Symbol: Rh
|
||||
Name: Rhodium
|
||||
|
||||
Number: 46
|
||||
Symbol: Pd
|
||||
Name: Palladium
|
||||
|
||||
Number: 47
|
||||
Symbol: Ag
|
||||
Name: Silver
|
||||
|
||||
Number: 48
|
||||
Symbol: Cd
|
||||
Name: Cadmium
|
||||
|
||||
Number: 49
|
||||
Symbol: In
|
||||
Name: Indium
|
||||
|
||||
Number: 50
|
||||
Symbol: Sn
|
||||
Name: Tin
|
||||
|
||||
Number: 51
|
||||
Symbol: Sb
|
||||
Name: Antimony
|
||||
|
||||
Number: 52
|
||||
Symbol: Te
|
||||
Name: Tellurium
|
||||
|
||||
Number: 53
|
||||
Symbol: I
|
||||
Name: Iodine
|
||||
|
||||
Number: 54
|
||||
Symbol: Xe
|
||||
Name: Xenon
|
||||
|
||||
Number: 55
|
||||
Symbol: Cs
|
||||
Name: Cesium
|
||||
|
||||
Number: 56
|
||||
Symbol: Ba
|
||||
Name: Barium
|
||||
|
||||
Number: 57
|
||||
Symbol: La
|
||||
Name: Lanthanum
|
||||
|
||||
Number: 58
|
||||
Symbol: Ce
|
||||
Name: Cerium
|
||||
|
||||
Number: 59
|
||||
Symbol: Pr
|
||||
Name: Praseodymium
|
||||
|
||||
Number: 60
|
||||
Symbol: Nd
|
||||
Name: Neodymium
|
||||
|
||||
Number: 61
|
||||
Symbol: Pm
|
||||
Name: Promethium
|
||||
|
||||
Number: 62
|
||||
Symbol: Sm
|
||||
Name: Samarium
|
||||
|
||||
Number: 63
|
||||
Symbol: Eu
|
||||
Name: Europium
|
||||
|
||||
Number: 64
|
||||
Symbol: Gd
|
||||
Name: Gadolinium
|
||||
|
||||
Number: 65
|
||||
Symbol: Tb
|
||||
Name: Terbium
|
||||
|
||||
Number: 66
|
||||
Symbol: Dy
|
||||
Name: Dysprosium
|
||||
|
||||
Number: 67
|
||||
Symbol: Ho
|
||||
Name: Holmium
|
||||
|
||||
Number: 68
|
||||
Symbol: Er
|
||||
Name: Erbium
|
||||
|
||||
Number: 69
|
||||
Symbol: Tm
|
||||
Name: Thulium
|
||||
|
||||
Number: 70
|
||||
Symbol: Yb
|
||||
Name: Ytterbium
|
||||
|
||||
Number: 71
|
||||
Symbol: Lu
|
||||
Name: Lutetium
|
||||
|
||||
Number: 72
|
||||
Symbol: Hf
|
||||
Name: Hafnium
|
||||
|
||||
Number: 73
|
||||
Symbol: Ta
|
||||
Name: Tantalum
|
||||
|
||||
Number: 74
|
||||
Symbol: W
|
||||
Name: Tungsten
|
||||
|
||||
Number: 75
|
||||
Symbol: Re
|
||||
Name: Rhenium
|
||||
|
||||
Number: 76
|
||||
Symbol: Os
|
||||
Name: Osmium
|
||||
|
||||
Number: 77
|
||||
Symbol: Ir
|
||||
Name: Iridium
|
||||
|
||||
Number: 78
|
||||
Symbol: Pt
|
||||
Name: Platinum
|
||||
|
||||
Number: 79
|
||||
Symbol: Au
|
||||
Name: Gold
|
||||
|
||||
Number: 80
|
||||
Symbol: Hg
|
||||
Name: Mercury
|
||||
|
||||
Number: 81
|
||||
Symbol: Tl
|
||||
Name: Thallium
|
||||
|
||||
Number: 82
|
||||
Symbol: Pb
|
||||
Name: Lead
|
||||
|
||||
Number: 83
|
||||
Symbol: Bi
|
||||
Name: Bismuth
|
||||
|
||||
Number: 84
|
||||
Symbol: Po
|
||||
Name: Polonium
|
||||
|
||||
Number: 85
|
||||
Symbol: At
|
||||
Name: Astatine
|
||||
|
||||
Number: 86
|
||||
Symbol: Rn
|
||||
Name: Radon
|
||||
|
||||
Number: 87
|
||||
Symbol: Fr
|
||||
Name: Francium
|
||||
|
||||
Number: 88
|
||||
Symbol: Ra
|
||||
Name: Radium
|
||||
|
||||
Number: 89
|
||||
Symbol: Ac
|
||||
Name: Actinium
|
||||
|
||||
Number: 90
|
||||
Symbol: Th
|
||||
Name: Thorium
|
||||
|
||||
Number: 91
|
||||
Symbol: Pa
|
||||
Name: Protactinium
|
||||
|
||||
Number: 92
|
||||
Symbol: U
|
||||
Name: Uranium
|
||||
|
||||
Number: 93
|
||||
Symbol: Np
|
||||
Name: Neptunium
|
||||
|
||||
Number: 94
|
||||
Symbol: Pu
|
||||
Name: Plutonium
|
||||
|
||||
Number: 95
|
||||
Symbol: Am
|
||||
Name: Americium
|
||||
|
||||
Number: 96
|
||||
Symbol: Cm
|
||||
Name: Curium
|
||||
|
||||
Number: 97
|
||||
Symbol: Bk
|
||||
Name: Berkelium
|
||||
|
||||
Number: 98
|
||||
Symbol: Cf
|
||||
Name: Californium
|
||||
|
||||
Number: 99
|
||||
Symbol: Es
|
||||
Name: Einsteinium
|
||||
|
||||
Number: 100
|
||||
Symbol: Fm
|
||||
Name: Fermium
|
||||
|
||||
Number: 101
|
||||
Symbol: Md
|
||||
Name: Mendelevium
|
||||
|
||||
Number: 102
|
||||
Symbol: No
|
||||
Name: Nobelium
|
||||
|
||||
Number: 103
|
||||
Symbol: Lr
|
||||
Name: Lawrencium
|
||||
|
||||
Number: 104
|
||||
Symbol: Rf
|
||||
Name: Rutherfordium
|
||||
|
||||
Number: 105
|
||||
Symbol: Db
|
||||
Name: Dubnium
|
||||
|
||||
Number: 106
|
||||
Symbol: Sg
|
||||
Name: Seaborgium
|
||||
|
||||
Number: 107
|
||||
Symbol: Bh
|
||||
Name: Bohrium
|
||||
|
||||
Number: 108
|
||||
Symbol: Hs
|
||||
Name: Hassium
|
||||
|
||||
Number: 109
|
||||
Symbol: Mt
|
||||
Name: Meitnerium
|
||||
|
||||
Number: 110
|
||||
Symbol: Ds
|
||||
Name: Darmstadtium
|
||||
|
||||
Number: 111
|
||||
Symbol: Rg
|
||||
Name: Roentgenium
|
||||
|
||||
Number: 112
|
||||
Symbol: Cn
|
||||
Name: Copernicium
|
||||
|
||||
Number: 113
|
||||
Symbol: Nh
|
||||
Name: Nihonium
|
||||
|
||||
Number: 114
|
||||
Symbol: Fl
|
||||
Name: Flerovium
|
||||
|
||||
Number: 115
|
||||
Symbol: Mc
|
||||
Name: Moscovium
|
||||
|
||||
Number: 116
|
||||
Symbol: Lv
|
||||
Name: Livermorium
|
||||
|
||||
Number: 117
|
||||
Symbol: Ts
|
||||
Name: Tennessine
|
||||
|
||||
Number: 118
|
||||
Symbol: Og
|
||||
Name: Oganesson
|
|
@ -0,0 +1,34 @@
|
|||
# show all recipes
|
||||
default:
|
||||
just --list --unsorted
|
||||
|
||||
# compile binary
|
||||
compile:
|
||||
fennel --compile-binary src/main.fnl tbls /usr/local/lib/liblua.a /usr/local/include/lua5.4
|
||||
|
||||
# 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
|
|
@ -0,0 +1,49 @@
|
|||
(local {
|
||||
: flatten
|
||||
: create-corpus
|
||||
} (require :src.story))
|
||||
|
||||
(fn show-help []
|
||||
(print "Usage: tbls [options]")
|
||||
(print)
|
||||
(print "Basic Options:")
|
||||
(print " -h|--help print this message and exit")
|
||||
(print " -i|--input <file> name of 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)
|
||||
(print "You must specify an input file")
|
||||
(print "You must specify either a string or a key to serve as an origin"))
|
||||
|
||||
(fn parse-args [t]
|
||||
(if (= 0 (length t))
|
||||
(do
|
||||
(show-help)
|
||||
(os.exit 0)))
|
||||
(fn inner [t opts]
|
||||
(if (= 0 (length t)) opts
|
||||
(do
|
||||
(case t
|
||||
(where [a] (or (= a "-h") (= a "--help")))
|
||||
(do
|
||||
(show-help)
|
||||
(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")))
|
||||
(set opts.key key)
|
||||
(where [a str] (or (= a "-s") (= a "--origin-table-string")))
|
||||
(set opts.string str))
|
||||
(let [next-t (icollect [i v (ipairs t)] (if (> i 2) v))]
|
||||
(inner next-t opts)))))
|
||||
(inner t {}))
|
||||
|
||||
(fn main []
|
||||
(let [opts (parse-args arg)
|
||||
corpus (create-corpus opts.input)
|
||||
]
|
||||
(if opts.key
|
||||
(print (flatten corpus (. corpus opts.key)))
|
||||
(print (flatten corpus opts.string)))))
|
||||
|
||||
(main)
|
|
@ -0,0 +1,80 @@
|
|||
;; helper funs
|
||||
(local tbl {
|
||||
:contains? (fn contains [t x]
|
||||
"does sequence t contain element x?"
|
||||
(accumulate [found false
|
||||
_ v (ipairs t)
|
||||
&until found] ; escape early
|
||||
(or found (= x v))))
|
||||
:keys (fn keys [t]
|
||||
"takes a table returns a sequential list of its keys"
|
||||
(local out [])
|
||||
(each [k v (pairs t)] (table.insert out k))
|
||||
out)
|
||||
})
|
||||
(fn has-key? [t k]
|
||||
(tbl.contains? (tbl.keys t) k))
|
||||
|
||||
|
||||
(fn lines [filename callback]
|
||||
(case (pcall #(with-open [file (io.open filename)] (each [line (file:lines)] (callback line))))
|
||||
(false err) (print (string.format "Error: Could not open file %s\n%s" filename err))))
|
||||
|
||||
(fn _create-corpus [lines data]
|
||||
(var current-key nil)
|
||||
(var corpus {})
|
||||
(lines data
|
||||
#(let [key (string.match $1 "^::%s+([%a-]+)")
|
||||
blank? (or (= nil $1) (= "" $1))
|
||||
comment? (string.match $1 "^#")
|
||||
]
|
||||
(when (and (not blank?) (not comment?))
|
||||
(if (not key)
|
||||
(let [list (. corpus current-key)]
|
||||
(table.insert list $1)
|
||||
(tset corpus current-key list))
|
||||
(do
|
||||
(set current-key key)
|
||||
(tset corpus current-key []))))))
|
||||
corpus)
|
||||
(local create-corpus (partial _create-corpus lines))
|
||||
|
||||
(fn one-of [t]
|
||||
"returns a random element of a sequential or non-sequential table"
|
||||
(let [len (accumulate [l 0 _ _ (pairs t)] (+ l 1)) ;; do it the hard way
|
||||
;; because nonseq tables
|
||||
;; have no length?
|
||||
handle (io.popen "echo $RANDOM")
|
||||
output (handle:read "*a")
|
||||
random (output:gsub "[\n\r]" "")
|
||||
seed (math.randomseed random) ;; SIDE EFFECT
|
||||
whatever (handle:close) ;; SIDE EFFECT
|
||||
idx (math.random len)
|
||||
keys (accumulate [acc [] k v (pairs t)] (do (table.insert acc k) acc))
|
||||
rndkey (. keys idx)
|
||||
]
|
||||
(. t rndkey)))
|
||||
|
||||
(fn flatten [corpus origin]
|
||||
(let [str (case (type origin)
|
||||
"string" origin
|
||||
"table" (one-of origin)
|
||||
_ (error "Origin must be a table or a string"))
|
||||
template-pattern "%[[%a-]+%]" ; [word]
|
||||
word-pattern "%[([%a-]+)%]" ; word
|
||||
(i j) (string.find str template-pattern) ; indices
|
||||
word (string.match str word-pattern)] ; the actual keyword
|
||||
(if (not i)
|
||||
str
|
||||
(do
|
||||
(assert (has-key? corpus 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))
|
||||
(one-of (. corpus word))
|
||||
(string.sub str (+ j 1)))]
|
||||
(flatten corpus next-str j)))))) ;; this is a tail call!
|
||||
|
||||
{: create-corpus
|
||||
: flatten
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,23 @@
|
|||
(let [{
|
||||
: flatten
|
||||
: create-corpus
|
||||
} (require :src.story)]
|
||||
|
||||
(let [corpus (create-corpus "test/morpheme-word-epithet.txt")
|
||||
origin-key :name
|
||||
origin-table ["[morpheme][word] [epithet]"
|
||||
"[prefix] [morpheme][word] [epithet]"
|
||||
"[prefix] [morpheme][word]"
|
||||
]
|
||||
origin-string "[morpheme][word] [epithet]"
|
||||
get-story-with-key
|
||||
(partial flatten corpus (. corpus origin-key))
|
||||
get-story-with-table
|
||||
(partial flatten corpus origin-table)
|
||||
get-story-with-string
|
||||
(partial flatten corpus origin-string)
|
||||
]
|
||||
(print "\n== Cast of Characters ==")
|
||||
(for [_ 1 4] (print (get-story-with-key)))
|
||||
(for [_ 1 4] (print (get-story-with-table)))
|
||||
(for [_ 1 4] (print (get-story-with-string)))))
|
Loading…
Reference in New Issue