Phoner is a CLI tool and library to validate phonotactic patterns for constructed languages. It is compatible with either romanization and phonetic transcription. Words can be randomly generated (see Argument Syntax).
Syntax Highlighting Extension for VSCode
This project can be used as a rust library, or as a binary.
``` $ phoner --help
Usage: phoner.exe [OPTIONS] [TESTS]
Options:
-t, --tests
-f, --file
Eg. `phoner -f ./myfile.phoner`
[default: phoner]
-d, --display-level
Options can be single letter
Eg. `phoner -d just-fails` or `phoner -df`
[default: show-all]
Possible values:
- show-all: Show everything (passes, notes, fails)
- notes-and-fails: Show most (notes, fails), but not passes
- just-fails: Show only fails, not passes or notes
- hide-all: Show nothing: not passes, notes, or fails
-m, --minify [
Possible values:
- tests: Include tests
-g, --generate [
Default count 1, specify with number
--gmin <GENERATE_MIN_LEN>
Set minimum length for generated words
Use with the `--generate` or `-g` flag
Note: This increases generation time exponentially
--gmax <GENERATE_MAX_LEN>
Set maximum length for generated words
Use with the `--generate` or `-g` flag
-n, --no-color Display output in default color
Use for piping standard output to a file
-h, --help
Print help information (use -h
for a summary)
```
```bash
phoner
phoner -t some,words
phoner -f myfile.phoner
phoner -df
phoner -d just-fails phoner -d fails
phoner -m
phoner -f myfile.phoner -dh -mt
phoner -g
phoner -g10 -g myfile.phoner
phoner -n > phoner.txt
phoner -f myfile.phoner -nd h -g 3 --gmin 6 --gmax 8 > ./phoner.txt ```
Replace <path_to_file>
with the directory of the downloaded binary.
Add alias in .bashrc
in user directory
```bash
alias phoner="
Add to $env:PATH
ps1
$env:Path = "$env:Path;<path_to_file>\phoner.exe"
Add phoner = "0.7.0"
to your Crates.toml
file
Short example:
```rust use phoner::Phoner;
fn main() { let file = std::fs::readtostring("phoner").unwrap();
// Parse file Phoner::parse(&file).unwrap() // Run tests .run(scheme) // Display results .display(Default::default()); } ```
Long example:
```rust use phoner::{Phoner, DisplayLevel};
fn main() { let file = std::fs::readtostring("phoner").unwrap();
// Parse file let scheme = Phoner::parse(&file).unwrap();
// Run tests let results = scheme.run(scheme);
// Display results - This could be manually implemented results.display(DisplayLevel::ShowAll, false);
// Generate random words let words = scheme.generate(10, 3..14).unwrap(); println!("{words:?}"); } ```
A Phoner file is used to define the rules, classes, and tests for the program.
The file should either be called phoner
, or end in .phoner
Syntax Highlighting Extension for VSCode
The syntax is a statements, each separated by a semicolon ;
or a linebreak.
Comments will only end with a linebreak.
All whitespace is ignored, except to separate words in tests.
Note! This will replace spaces in Regex as well!
Each statement must begin with an operator:
#
Hashtag: A whole line comment. A linebreak (not a semicolon) ends the comment$
Dollar: Define a class+
Plus or !
Bang: Define a rule@
Commat: Define a reason if a test fails?
Question: Create a test*
Star: Create a test note (also with @*
)~
Tilde: Define the mode of the fileClasses are used as shorthand Regular Expressions, substituted into rules at runtime.
Note: Angle brackets will not parse as class names directly after:
- An opening round bracket and a question mark:
(?
- An opening round bracket, question mark, and letter 'P':
(?P
- A backslash and letter 'k':
\k
This is the syntax used for look-behinds and named groups
Syntax:
$
Dollar=
Equals<>
(as with rules)The any
class, defined with $_ = ...
, is used for random word generation.
Example:
```phoner
$C = [ptksmn]
$V = [iueoa]
$C_s = [sz] ```
Rules are Regular Expressions used to test if a word is valid.
Rules are defined with an intent, either +
for positive, or !
for negative.
To use a class, use the class name, surrounded by angle brackets <>
.
Syntax:
+
Plus or !
Bang - Plus for positive rule, Bang for negative rule<>
Example (with predefined *classes*):
```phoner
!
Tests are checked against all rules, and the result is displayed in the output.
Tests are ran in the order of definition.
Like rules, tests must have a defined intent, either +
for positive, or !
for negative.
Syntax:
?
Question mark+
Plus or !
Bang - Plus for positive test, Bang for negative testExample (with predefined *rules*):
```phoner
?+ taso
?! tax
?+ taso sato tasa ```
Reasons are used before rules as an explanation if a test fails.
Syntax:
@
Commat*
Star - Use as a note as well (a noted reason)Example:
```phoner
@ Syllable structure
+ ^ (
?+ tasto
@* Must not have two vowels in a row
!
?+ taso ```
Notes are printed to the terminal output, alongside tests.
They can be used to separate tests into sections, however this is only cosmetic.
Syntax:
*
StarExample (with predefined rules):
```phoner * Should match ?+ taso
The mode of a Phoner file can be one of these:
<>
//
[]
This can optionally be specified in a file, although it does not add any functionality.
Syntax:
~
Tilde<.>
, /./
, or [.]
- Mode identifier, with .
being any string, or blankExamples:
```phoner
~<> ```
```phoner
~ / this is the mode / ```
See the examples folder for Phoner file examples.
These formatting tips are not required, but recommended to make the file easier to read.
any
class first, for word generationExample (this is from example.phoner):
```phoner ~<> ;# Mode (optional) - This file uses romanized letters
$_ = [ptkmnswjlaeiou] ;# Any / all letters (required for generating words) $C = [ptkmnswjl] ;# Consonants $V = [aeiou] ;# Vowels
@* Invalid letters ;# Noted reason - Prints like a note to standard output + ^ <_>+ $ ;# Check that every letter is in the 'any' group ?+ taso ?! tyxo
@* Syllable structure
+ ^ (
@* No repeated letters
! (.)\1 ;# This is an unnamed back-reference
! (?
.len()
calls on strings, check for non-ascii problems (use .chars().count()
)Error
variantsRemove unnecessary clone
s where possible
Move gen.rs
functionality to gen
feature