Skip to content

Commit

Permalink
Merge branch 'development'
Browse files Browse the repository at this point in the history
  • Loading branch information
bradrn committed Jan 4, 2024
2 parents ac6149c + d39731f commit 3322fda
Show file tree
Hide file tree
Showing 44 changed files with 3,557 additions and 969 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ gui/build*
stub/
CMakeLists.txt.user
stack.yaml.lock
gui/brassica-web/static/*.js
gui/brassica-web/static/examples/
gui/brassica-web/dist/*.js
gui/brassica-web/dist/examples/
25 changes: 13 additions & 12 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,25 @@ Finally, use [NSIS](https://nsis.sourceforge.io/Main_Page) with the given `insta
## Online version

Building the online version of Brassica is slightly more difficult as it requires the WebAssembly backend of GHC.
It is easiest to get this using GHCup’s [WASM cross bindists](https://www.haskell.org/ghcup/guide/#cross-support).
You will also need [Wizer](https://github.com/bytecodealliance/wizer) to pre-initialise the WASM binary,
and [npm](https://www.npmjs.com/) for JavaScript package management.

Follow the instructions at [ghc-wasm-meta](https://gitlab.haskell.org/ghc/ghc-wasm-meta) to install this version.
Then:

1. In `./gui/brassica-interop-wasm`, run the following commands:
```
wasm32-wasi-cabal build brassica-interop-wasm
wizer --allow-wasi --wasm-bulk-memory true "$(wasm32-wasi-cabal list-bin -v0 brassica-interop-wasm)" -o "./dist/brassica-interop-wasm.wasm"
cabal build --project-file=cabal-wasm.project brassica-interop-wasm
wizer --allow-wasi --wasm-bulk-memory true "$(cabal --project-file=cabal-wasm.project list-bin -v0 brassica-interop-wasm)" -o "./dist/brassica-interop-wasm.wasm"
```
This will create a file `./gui/brassica-interop-wasm/dist/brassica-interop-wasm.wasm` containing the WASM binary.
2. In `./gui/brassica-web`, run the following commands to copy the required files into `./gui/brassica-web/static`:
```
npm install
npx webpack
cp ../brassica-interop-wasm/dist/brassica-interop-wasm.wasm static/
cp -r ../../examples/ static/
```
3. To test Brassica, you can now run a webserver in `./gui/brassica-web/static`,
for instance using `python -m http.server`.

(Note: it can also be convenient to set `CABAL_DIR` so that WASM packages are installed to a different location.)

2. In `./gui/brassica-web`, run `mkdir dist; ./cpfiles` to copy the asset files into `dist`.
Note that you’ll need to redo this every time you update a static file (HTML or CSS or WASM)!
3. Install JavaScript dependencies using `npm install`.

Now you can use [webpack](https://webpack.js.org/) to bundle the JavaScript files.
For instance, use `npx webpack serve` to run a development server,
or `npx webpack --mode=production` to prepare a release.
10 changes: 9 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# Brassica changelog

## Unreleased changes
## v0.2.0

- Allow grapheme to begin with star
- Allow lexeme sequences in categories using `{…}` syntax
- Allow backreferences to occur in the environment
- Allow user to choose separator used between multiple results (previously a space)
- Internal refactor: category expansion is now separate from parsing
- Add `--version` command-line option
- Store `MultiZipper` data in a `Vector` rather than a linked list (for performance)
- Bugfix: subtraction now removes all subtracted graphemes
- Store paradigm builder output in a tree data structure, allowing a more compact output format
- Documented abstract features in paradigm builder (previously present but undocumented)

## v0.1.1
Expand Down
128 changes: 45 additions & 83 deletions Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ Thus, to delete ⟨ʔ⟩ before a stop or the end of a word, the following rule
ʔ / / _ [p t k b d g #]
```

Sometimes you might want to match a sequence of zero or more graphemes.
Do this in a category by surrounding them with curly brackets `{`/`}`, as in:
```
[eː oː] / [{j ə} {w ə}]
[{ŋ g} ŋ] → [ŋ {}] / _#
```

You can also use multiple categories in the replacement.
In this case each is matched up one-to-one with a category in the target:
the first in the replacement with the first in the target,
Expand Down Expand Up @@ -580,7 +587,7 @@ For instance, the following rule will cause a nasal to assimilate in place of ar
╚══════════════════════╝
```

Backreferences can also be used in the target, in which case they match repeated or corresponding graphemes.
Backreferences can also be used in the target or environment, in which case they match repeated or corresponding graphemes.
For instance, consider a rule deleting ⟨ə⟩ between identical consonants.
This may be written:
```
Expand Down Expand Up @@ -815,7 +822,7 @@ Further modifications can then be made to the output while keeping the etymologi

Brassica includes an inbuilt paradigm builder.
It may be accessed using the ‘Tools⇒Paradigm Builder’ menu item in the graphical interface,
or by visiting <https://bradrn.com/brassica/builder/>.
or by visiting <https://bradrn.com/brassica/builder.html>.

The paradigm builder consists of three textboxes and a button.
The leftmost textbox contains a description of the paradigm using the syntax described below.
Expand Down Expand Up @@ -852,87 +859,42 @@ Thus an example of a basic paradigm definition would be as follows:
The output will then iterate through all combinations of these affixes.
For instance, applying the paradigm above to the root `kood` gives:

<details>
<summary>
(Click to show output)
</summary>
<pre>
<code>
zhaazhkoodwim
zhaawkoodwim
zhaaykoodwim
woozhkoodwim
woowkoodwim
wooykoodwim
yaazhkoodwim
yaawkoodwim
yaaykoodwim
zhaazhkood
zhaawkood
zhaaykood
woozhkood
woowkood
wooykood
yaazhkood
yaawkood
yaaykood
zhaazhkoodsoo
zhaawkoodsoo
zhaaykoodsoo
woozhkoodsoo
woowkoodsoo
wooykoodsoo
yaazhkoodsoo
yaawkoodsoo
yaaykoodsoo
zhaazhkoodaa
zhaawkoodaa
zhaaykoodaa
woozhkoodaa
woowkoodaa
wooykoodaa
yaazhkoodaa
yaawkoodaa
yaaykoodaa
zhaazhkoodwimen
zhaawkoodwimen
zhaaykoodwimen
woozhkoodwimen
woowkoodwimen
wooykoodwimen
yaazhkoodwimen
yaawkoodwimen
yaaykoodwimen
zhaazhkooden
zhaawkooden
zhaaykooden
woozhkooden
woowkooden
wooykooden
yaazhkooden
yaawkooden
yaaykooden
zhaazhkoodsooen
zhaawkoodsooen
zhaaykoodsooen
woozhkoodsooen
woowkoodsooen
wooykoodsooen
yaazhkoodsooen
yaawkoodsooen
yaaykoodsooen
zhaazhkoodaaen
zhaawkoodaaen
zhaaykoodaaen
woozhkoodaaen
woowkoodaaen
wooykoodaaen
yaazhkoodaaen
yaawkoodaaen
yaaykoodaaen
</code>
</pre>
</details>
```
zhaazhkoodwim zhaawkoodwim zhaaykoodwim
woozhkoodwim woowkoodwim wooykoodwim
yaazhkoodwim yaawkoodwim yaaykoodwim
zhaazhkood zhaawkood zhaaykood
woozhkood woowkood wooykood
yaazhkood yaawkood yaaykood
zhaazhkoodsoo zhaawkoodsoo zhaaykoodsoo
woozhkoodsoo woowkoodsoo wooykoodsoo
yaazhkoodsoo yaawkoodsoo yaaykoodsoo
zhaazhkoodaa zhaawkoodaa zhaaykoodaa
woozhkoodaa woowkoodaa wooykoodaa
yaazhkoodaa yaawkoodaa yaaykoodaa
zhaazhkoodwimen zhaawkoodwimen zhaaykoodwimen
woozhkoodwimen woowkoodwimen wooykoodwimen
yaazhkoodwimen yaawkoodwimen yaaykoodwimen
zhaazhkooden zhaawkooden zhaaykooden
woozhkooden woowkooden wooykooden
yaazhkooden yaawkooden yaaykooden
zhaazhkoodsooen zhaawkoodsooen zhaaykoodsooen
woozhkoodsooen woowkoodsooen wooykoodsooen
yaazhkoodsooen yaawkoodsooen yaaykoodsooen
zhaazhkoodaaen zhaawkoodaaen zhaaykoodaaen
woozhkoodaaen woowkoodaaen wooykoodaaen
yaazhkoodaaen yaawkoodaaen yaaykoodaaen
```

(You can also tick the option ‘Each word on its own line’, if you dislike placing multiple words on a single line.)

Note that in the paradigm described above, all affixes on each line are assigned to the same slot.
This is common in paradigms, so the paradigm builder has a shortcut syntax for this situation,
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright Brad Neimann (c) 2020-2023
Copyright Brad Neimann (c) 2020-2024

All rights reserved.

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
Brassica is a new sound change applier.
Its features include:

- Can be used interactively both [online](http://bradrn.com/brassica/index.html) and as a desktop application, or non-interactively in batch mode on the command-line or as a [Haskell library](https://hackage.haskell.org/package/brassica)
- Can be used interactively both [online](https://bradrn.com/brassica/index.html) and as a desktop application, or non-interactively in batch mode on the command-line or as a [Haskell library](https://hackage.haskell.org/package/brassica)
- Natively supports the MDF dictionary format, also used by tools including [SIL Toolbox](https://software.sil.org/toolbox/) and [Lexique Pro](https://software.sil.org/lexiquepro/)
- First-class support for multigraphs
- Easy control over rule application: apply sound changes sporadically, right-to-left, between words, and in many more ways
- Live preview and control over output highlighting let you try out sound changes quickly and easily
- Highlight and visualise results in numerous ways
- Category operations allow phonetic rules to be written in both featural and character-based ways
- Support for ‘features’ lets rules easily manipulate stress, tone and other suprasegmentals
- Comes with a paradigm builder for quickly investigating inflectional and other patterns
- Comes with a [paradigm builder](https://bradrn.com/brassica/builder.html) for quickly investigating inflectional and other patterns
- Rich syntax for specifying phonetic rules, including wildcards, optional elements and more

And many more!
Expand Down
28 changes: 17 additions & 11 deletions bench/Changes.hs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}

module Main where

import Criterion.Main (defaultMain, bench, nf, bgroup)
import Criterion.Main (defaultMain, bench, nf, bgroup, Benchmark)
import Data.FileEmbed (embedFile)
import Data.Text (unpack)
import Data.Text.Encoding (decodeUtf8)

import Brassica.SoundChange
import Brassica.SoundChange.Frontend.Internal

main :: IO ()
main = defaultMain
Expand All @@ -33,40 +35,44 @@ main = defaultMain
[ bench "parse" $ nf parseSoundChanges manyChanges
, bench "parseRun" $ case parseSoundChanges manyChanges of
Left _ -> error "invalid changes file"
Right cs -> case withFirstCategoriesDecl tokeniseWords cs manyWords of
Left _ -> error "invalid words file"
Right ws -> nf (fmap $ applyChanges cs) $ getWords ws
Right cs -> nf (parseTokeniseAndApplyRules
cs
manyWords
Raw
(ApplyRules NoHighlight WordsOnlyOutput "/"))
Nothing
]
]
where
basic = Rule
{ target = [Grapheme "a"]
, replacement = [Grapheme "b"]
, environment = ([], [])
, environment = [([], [])]
, exception = Nothing
, flags = defFlags
, plaintext = "a/b"
}

complex = Rule
{ target =
[ Category [GraphemeEl "t", GraphemeEl "d", GraphemeEl "n"]
[ Category $ FromElements $ Left <$> ["t", "d", "n"]
, Optional [Grapheme "y"]
, Category [GraphemeEl "i", GraphemeEl "e"]
, Category $ FromElements $ Left <$> ["i", "e"]
]
, replacement =
[ Category [GraphemeEl "c", GraphemeEl "j", GraphemeEl "nh"]
[ Category $ FromElements $ Left <$> ["c", "j", "nh"]
, Optional [Geminate]
]
, environment =
( [Category [BoundaryEl, GraphemeEl "a", GraphemeEl "e", GraphemeEl "i"]]
, [Category [GraphemeEl "a", GraphemeEl "e", GraphemeEl "i", GraphemeEl "o", GraphemeEl "u"]]
, environment = pure
( [Category $ FromElements $ Left <$> [GBoundary, "a", "e", "i"]]
, [Category $ FromElements $ Left <$> ["a", "e", "i", "o", "u"]]
)
, exception = Nothing
, flags = defFlags
, plaintext = "[t d n] (y) [i e] / [č j ñ] (>) / [# a e i] _ [a e i o u]"
}

benchChanges :: Rule Expanded -> PWord -> [Benchmark]
benchChanges cs l =
-- [ bench "log" $ nf (applyStatementWithLogs (RuleS cs)) l
-- given the implementation of logging, the above benchmark doesn't help very much at all
Expand Down
23 changes: 12 additions & 11 deletions brassica.cabal
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cabal-version: 2.0
name: brassica
version: 0.1.1
version: 0.2.0
synopsis: Featureful sound change applier
description:
The Brassica library for the simulation of sound changes in historical linguistics and language construction.
Expand Down Expand Up @@ -43,12 +43,13 @@ library
build-depends:
base >=4.7 && <5
, containers >=0.6 && <0.7
, deepseq >=1.4 && <1.5
, megaparsec >=8.0 && <9.3
, mtl >=2.2 && <2.3
, deepseq >=1.4 && <1.6
, megaparsec >=8.0 && <9.7
, mtl >=2.2 && <2.4
, parser-combinators >=1.2 && <1.3
, split >=0.2 && <0.3
, transformers >=0.5 && <0.6
, transformers >=0.5 && <0.7
, vector >=0.13 && <0.14

default-language: Haskell2010

Expand All @@ -62,12 +63,12 @@ executable brassica
, brassica
, aeson ^>=2.2
, attoparsec-aeson ^>=2.2
, bytestring >=0.10 && <0.12
, bytestring >=0.10 && <0.13
, conduit ^>=1.3
, conduit-extra ^>=1.3
, deepseq >=1.4 && <1.5
, optparse-applicative ^>=0.17
, text >=1.2 && <2.1
, deepseq >=1.4 && <1.6
, optparse-applicative ^>=0.17 || ^>=0.18
, text >=1.2 && <2.2

default-language: Haskell2010

Expand All @@ -79,7 +80,7 @@ benchmark changes-bench
build-depends:
base >=4.7 && <5
, brassica
, criterion >=1.5 && <1.6
, criterion >=1.5 && <1.7
, file-embed >=0.0.15 && <0.0.16
, text >=1.2 && <1.3

Expand All @@ -93,7 +94,7 @@ benchmark paradigm-bench
build-depends:
base >=4.7 && <5
, brassica
, criterion >=1.5 && <1.6
, criterion >=1.5 && <1.7

default-language: Haskell2010

Expand Down
4 changes: 4 additions & 0 deletions cabal-wasm.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
packages: ./brassica.cabal
./gui/brassica-interop-wasm/brassica-interop-wasm.cabal
with-compiler: wasm32-wasi-ghc
with-hc-pkg: wasm32-wasi-ghc-pkg
6 changes: 1 addition & 5 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
if(os(wasi))
packages: ./brassica.cabal
./gui/brassica-interop-wasm/brassica-interop-wasm.cabal
else
packages: ./brassica.cabal
packages: ./brassica.cabal
Loading

0 comments on commit 3322fda

Please sign in to comment.