helium

main vHelium
Dozens B. McCuzzins 2024-08-03 17:09:10 -06:00
parent 365fabdf67
commit 7ec9978919
17 changed files with 550 additions and 383 deletions

View File

@ -18,8 +18,9 @@ See `just compile`.
- [x] random table entries (ADDED in vHydrogen)
- [x] expanding macros (ADDED in vHydrogen)
- [ ] table files plugin: syntax highlighting + folding
- [ ] expansion filters
- [x] table files plugin: syntax highlighting + folding (ADDED vHelium)
- [x] expansion filters (ADDED vHelium)
- [ ] table context
## Resources

15
doc/History.md 100644
View File

@ -0,0 +1,15 @@
# History
`tbls` began as the Story module for a board game I was writing.
When I completed all the features for the board game itself,
I wanted to add some kind of a generative story engine
based on the state of the game
and on player moves.
This ended up complicating the game quite a bit,
and also I couldn't figure out how or where
to actually incorporate the story.
So I scrapped it for that particular project,
but continued to develop the story engine on its own.
It became `tbls`.

View File

@ -1,4 +1,6 @@
## Tutorial
# Tutorial
## Random Selections
At its most basic, `tbls` selects a random element from a table.
@ -17,21 +19,19 @@ Shovels
Ace
One
Two
...
Ten
Eleven
Twelve
Thief
[...]
Queen
King
Beast
```
`tbls` might return "Whistles" from suit.
Or "Twelve" from card.
Or "Two" from card.
## Expansion
But wait there's more.
`tbls` will also expand macros found in table entries.
`tbls` will also expand certain text found in a table entry.
Let's add another table:
@ -43,6 +43,39 @@ Let's add another table:
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"
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 `src/flib.fnl`.
To apply filters,
dot-chain them at the end
of a table reference.
Consider the following tables:
```
:: origin
Evelyn eats one [fruit]
Evelyn eats many [fruit.s]
:: fruit
banana
apple
pear
```
`s`, `plural`, and `pluralize`
are all different ways
to call the 'plural' filter function.
Example output:
```
Evelyn eats one pear
Evelyn eats one bananas
```

View File

@ -5,5 +5,5 @@
name: tbls
author: dozens@tilde.team
created: 2024-07-31
updated: 2024-08-01
version: Hydrogen
updated: 2024-08-03
version: Helium

View File

@ -32,3 +32,11 @@ bump:
# show full metadata
meta:
awk 'FNR==1{print ""}{print}' doc/*.rec | recsel -t meta -j version
# install vim plugin
install-plugin:
cp -r vim-tbls/* ~/.config/nvim
# install binary
install-binary: compile
cp tbls ~/bin

16
src/filter.fnl 100644
View File

@ -0,0 +1,16 @@
(local {: contains?} (require :src.table))
(local {:split split-full} (require :src.string))
(local split (partial split-full "[^%.]*"))
(fn filter [s]
(let [filters (require :src.flib)
[str & funs] (split s)]
(var res str)
(each [_ f (ipairs funs)]
(each [_ filter (pairs filters)]
(when (contains? filter.call f)
(set res (filter.fun res)))))
res))
{: filter
}

30
src/flib.fnl 100644
View File

@ -0,0 +1,30 @@
(fn capitalize [s]
(s:gsub "." string.upper 1))
(fn uppercase [s]
(string.upper s))
(fn lowercase [s]
(string.lower s))
(fn plural [s]
(.. s :s))
{
:capitalize {
:call [:c :cap :capital :capitalize]
:fun capitalize
}
:uppercase {
:call [:u :upper :uppercase]
:fun uppercase
}
:lowercase {
:call [:l :lower :lowercase]
:fun lowercase
}
:plural {
:call [:s :plural :pluralize]
:fun plural
}
}

View File

@ -40,8 +40,7 @@
(fn main []
(let [opts (parse-args arg)
corpus (create-corpus opts.input)
]
corpus (create-corpus opts.input)]
(if opts.key
(print (flatten corpus (. corpus opts.key)))
(print (flatten corpus opts.string)))))

View File

@ -1,20 +1,8 @@
;; 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))
(local tbl (require :src.table))
(local {: filter} (require :src.filter))
(local {:split _split} (require :src.string))
(local split (partial _split "[^%.]*"))
(fn lines [filename callback]
(case (pcall #(with-open [file (io.open filename)] (each [line (file:lines)] (callback line))))
@ -22,7 +10,7 @@
(fn _create-corpus [lines data]
(var current-key nil)
(var corpus {})
(local corpus {})
(lines data
#(let [key (string.match $1 "^::%s+([%a-]+)")
blank? (or (= nil $1) (= "" $1))
@ -50,7 +38,7 @@
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))
keys (accumulate [acc [] k _ (pairs t)] (do (table.insert acc k) acc))
rndkey (. keys idx)
]
(. t rndkey)))
@ -60,18 +48,22 @@
"string" origin
"table" (one-of origin)
_ (error "Origin must be a table or a string"))
template-pattern "%[[%a-]+%]" ; [word]
word-pattern "%[([%a-]+)%]" ; word
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
raw-word (or (string.match str word-pattern) str)
[word & fs] (split raw-word)
]
(if (not i)
str
(do
(assert (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))
(let [next-str (string.format "%s%s%s"
(string.sub str 1 (- i 1))
(one-of (. corpus word))
(if (length fs)
(filter (.. (one-of (. corpus word)) "." (table.concat fs ".")))
(one-of (. corpus word)))
(string.sub str (+ j 1)))]
(flatten corpus next-str j)))))) ;; this is a tail call!

7
src/string.fnl 100644
View File

@ -0,0 +1,7 @@
(fn split [pattern str]
(let [res []]
(each [seg (str:gmatch pattern)]
(table.insert res seg))
res))
{: split}

20
src/table.fnl 100644
View File

@ -0,0 +1,20 @@
(fn contains? [t x]
"does sequence t contain element x?"
(accumulate [found false
_ v (ipairs t)
&until found] ; escape early
(or found (= x v))))
(fn keys [t]
"takes a table returns a sequential list of its keys"
(local out [])
(each [k _ (pairs t)] (table.insert out k))
out)
(fn has-key? [t k]
(contains? (keys t) k))
{: contains?
: keys
: has-key?
}

View File

@ -2,349 +2,350 @@
:: name
## Entry point / origin
[morpheme][word] [epithet]
[prefix] [morpheme][word]
[prefix] [morpheme][word] [epithet]
[morpheme][word]'[morpheme]
[morpheme] [morpheme][word]
[morpheme.c][word] [epithet]
[prefix] [morpheme.c][word]
[prefix] [morpheme.c][word.s]
[prefix] [morpheme.c][word] [epithet]
[morpheme.c][word]'[morpheme.c]
[morpheme.c] [morpheme.c][word]
:: morpheme
## A random sound
Brog
Guyn
Driz
Oy
Poin
Broin
Dray
Hoy
Khu
Elbb
Zee
Teg
Thig
Volor
Moror
Zarn
Zark
Zarzl
Zhong
Zok
Krinc
Prunc
Seld
Serd
Quo
Quog
Wast
Writ
Wub
Eem
Eo
Ev
Wuld
Rond
Trop
Yhoo
Urdd
Ing
Ogg
Phef
Aph
Fro
Drov
Frol
Gis
Hirn
Wilk
Rof
Roch
Thip
Throg
Teng
Tirk
Tenk
Twu
Twal
Yuth
Yirg
Ull
Uk
Iv
Irch
Ok
Ort
Ool
Oon
Oos
Oop
Pur
Purth
Pux
Pix
Ang
Ank
Ack
Arr
Arc
Sor
Shri
Sarc
Sib
Spo
Snil
Dral
Dax
Druz
Droon
Tiong
Snid
Phra
Vang
Gawp
Hool
Grul
Dhoop
Jair
Qim
Quisl
Fiaz
Prax
Aal
Righ
Ugh
Yog
Yig
Yair
Var
Vaq
Skog
Drij
Volg
Dem
Ghil
Uvar
Err
Azil
Obil
Zanzil
Zhat
Blug
Blig
Hroo
Waf
Xar
Grar
Lorp
Vuh
Ee
Ay
Oo
Ux
Ix
Whal
Mun
Ilun
Fargl
Xab
Frang
Bao
Bif
Xif
Zij
Quix
Vonch
Van
Klanc
Lug
Nirm
Zirm
Sil
Wev
Vil
Vran
Quiv
Squan
Squank
Squop
Akun
Apar
Epar
Iq
Exy
Eny
Ery
Uth
Ist
Ost
Hrosh
Imb
Omb
Onk
Arem
Urum
Irim
Irik
Eliv
Wep
Wroov
Droov
Seef
Hiqa
Ayy
Jaal
Khee
Ish
Xiliv
Whij
Koj
Krong
Swue
Aur
Eth
Qeth
Neth
Veth
Yeth
Aer
Aen
Ain
Aun
Uon
Xiv
Ung
Ong
Eng
Ehal
Dhar
Dhom
Hom
Kom
Rom
Qom
Eez
Dhezz
Elpz
Upz
Akz
Auz
Goaz
Goz
Mepz
Tepz
Crunz
Grenz
Purb
Ony
Igy
Eart
Ehng
Leng
Jub
Zhoon
Zhewt
Juju
Lhop
Lhow
Ewl
Ewil
Avul
Ap
Ip
Ep
Eb
En
El
Ek
Eh
Ez
Es
Ej
Ol
Om
Ob
Oc
Ot
Oz
Os
Oq
Mork
Morg
Borg
Franken
Pranken
Lankim
Khim
Khem
Vinken
Inken
Swohd
Glup
Blubil
Bulbil
Ziz
Miz
Lilip
Soong
Yolp
Grang
Grunc
Gharn
Bral
Criv
Durn
Flom
Griv
Harn
Jurn
Klom
Larn
Mird
Norl
Plen
Qarn
Rilk
Skiv
Tarm
Ulm
Vorn
Wim
Yorn
Blen
Cril
Dorn
Frel
Glim
Jiln
Kren
Lom
Morn
Nix
Polm
Quen
Ralk
Shil
Trok
Ulk
Vlim
Yiln
Brim
Crev
Dril
Flon
Gril
Jorn
Kliv
Lorn
Mirk
Norn
Plim
Qril
Rik
Skon
Trel
Ulv
Vril
brog
guyn
driz
oy
poin
broin
dray
hoy
khu
elbb
zee
teg
thig
volor
moror
zarn
zark
zarzl
zhong
zok
krinc
prunc
seld
serd
quo
quog
wast
writ
wub
eem
eo
ev
wuld
rond
trop
yhoo
urdd
ing
ogg
phef
aph
fro
drov
frol
gis
hirn
wilk
rof
roch
thip
throg
teng
tirk
tenk
twu
twal
yuth
yirg
ull
uk
iv
irch
ok
ort
ool
oon
oos
oop
pur
purth
pux
pix
ang
ank
ack
arr
arc
sor
shri
sarc
sib
spo
snil
dral
dax
druz
droon
tiong
snid
phra
vang
gawp
hool
grul
dhoop
jair
qim
quisl
fiaz
prax
aal
righ
ugh
yog
yig
yair
var
vaq
skog
drij
volg
dem
ghil
uvar
err
azil
obil
zanzil
zhat
blug
blig
hroo
waf
xar
grar
lorp
vuh
ee
ay
oo
ux
ix
whal
mun
ilun
fargl
xab
frang
bao
bif
xif
zij
quix
vonch
van
klanc
lug
nirm
zirm
sil
wev
vil
vran
quiv
squan
squank
squop
akun
apar
epar
iq
exy
eny
ery
uth
ist
ost
hrosh
imb
omb
onk
arem
urum
irim
irik
eliv
wep
wroov
droov
seef
hiqa
ayy
jaal
khee
ish
xiliv
whij
koj
krong
swue
aur
eth
qeth
neth
veth
yeth
aer
aen
ain
aun
uon
xiv
ung
ong
eng
ehal
dhar
dhom
hom
kom
rom
qom
eez
dhezz
elpz
upz
akz
auz
goaz
goz
mepz
tepz
crunz
grenz
purb
ony
igy
eart
ehng
leng
jub
zhoon
zhewt
juju
lhop
lhow
ewl
ewil
avul
ap
ip
ep
eb
en
el
ek
eh
ez
es
ej
ol
om
ob
oc
ot
oz
os
oq
mork
morg
borg
franken
pranken
lankim
khim
khem
vinken
inken
swohd
glup
blubil
bulbil
ziz
miz
lilip
soong
yolp
grang
grunc
gharn
bral
criv
durn
flom
griv
harn
jurn
klom
larn
mird
norl
plen
qarn
rilk
skiv
tarm
ulm
vorn
wim
yorn
blen
cril
dorn
frel
glim
jiln
kren
lom
morn
nix
polm
quen
ralk
shil
trok
ulk
vlim
yiln
brim
crev
dril
flon
gril
jorn
kliv
lorn
mirk
norn
plim
qril
rik
skon
trel
ulv
vril
:: word
## A regular old word
@ -1011,3 +1012,4 @@ Sister
Sour
Pickled
The Machine known as
# vim:set filetype=tbls:

View File

@ -5,11 +5,11 @@
(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-table ["[morpheme.c][word] [epithet]"
"[prefix] [morpheme.c][word] [epithet]"
"[prefix] [morpheme.c][word]"
]
origin-string "[morpheme][word] [epithet]"
origin-string "[morpheme.c][word] [epithet]"
get-story-with-key
(partial flatten corpus (. corpus origin-key))
get-story-with-table

25
vim-tbls/README.md 100644
View File

@ -0,0 +1,25 @@
# vim-tbls
syntax, filtetype detection, folding, and navigation for tbls files
## installing
1. find out where your `syntax` and `ftdetect` files are. e.g. `$HOME/.config/nvim/` or `$HOME/.vim/`.
2. copy `syntax/tbls.vim` and `ftdetect/tbls.vim` to the appropriate folders
after installing, any `.tbl` file should be detected.
to use syntax for, e.g. a `.txt` file, in vim do `:set filetype=tbls`
## using
the syntax defines a foldable table block as the region between a `:: header` and a blank line.
all folding commands should work.
(e.g. `zj` and `zk` to jump to next fold. see `:help fold`.)
the plugin file sets the foldmethod to syntax,
so your tables should start out folded if folding in enabled.
the plugin file also maps `]]` and `[[`
(next section and previous section, respectively)
to jump between table headers.

View File

@ -0,0 +1 @@
au BufRead,BufNewFile *.tbl set filetype=tbls

View File

@ -0,0 +1,3 @@
setlocal foldmethod=syntax
nnoremap <silent><buffer> ]] m':call search('^::', "W")<CR>
nnoremap <silent><buffer> [[ m':call search('^::', "bW")<CR>

View File

@ -0,0 +1,15 @@
if exists("b:current_syntax")
finish
endif
syntax match tblsComment "^#.*$"
syntax match tblsTitle "^:\+ .*$"
syntax match tblsRef "\[[^\]]*\]"
syntax region tblsTable start=":: .*" end="^$" fold transparent
highlight default link tblsComment Comment
highlight default link tblsTitle Statement
highlight default link tblsRef Type
let b:current_syntax = "tbls"