Skip to main content

sona toki

Test workflow for this library Version number for this library

What is sona toki?

This library, "Language Knowledge," helps you identify whether a message is in Toki Pona. It does so by determining whether a large enough number of words in a statement are "in Toki Pona". No grammar checking, yet.

I wrote this library with a variety of scraps and lessons learned from a prior project, ilo pi toki pona taso, "toki-pona-only tool". That tool now uses this library to great success!

If you've ever worked on a similar project, you know the question "is this message in [language]" is not a consistent one- the environment, topic, preferences of the speaker, and much more, can all alter whether a given message is "in" any specific language. This complexity applies to Toki Pona too.

So, this project "solves" that complex problem by offering an opinionated tokenizer and a configurable parser, allowing you to tune its output to your preferences and goals. Even silly ones.

Quick Start

Install with your preferred Python package manager. Example:

pdm init  # if your pyproject.toml doesn't exist yet
pdm add sonatoki

Then get started with a script along these lines:

from sonatoki.ilo import Ilo
from sonatoki.Configs import PrefConfig

def main():
    ilo = Ilo(**PrefConfig)
    ilo.is_toki_pona("imagine how is touch the sky")  # False
    ilo.is_toki_pona("o pilin insa e ni: sina pilin e sewi")  # True
    ilo.is_toki_pona("I Think I Can Evade Detection")  # False

if __name__ == "__main__":
    main()

Or if you'd prefer to configure on your own:

from copy import deepcopy
from sonatoki.ilo import Ilo
from sonatoki.Configs import BaseConfig
from sonatoki.Filters import NimiLinkuCore, NimiLinkuCommon, Phonotactic, ProperName, Or
from sonatoki.Scorers import SoftPassFail

def main():
    config = deepcopy(BaseConfig)
    config["scoring_filters"].extend([Or(NimiLinkuCore, NimiLinkuCommon), Phonotactic, ProperName])
    config["scorer"] = SoftPassFail

    ilo = Ilo(**config)
    ilo.is_toki_pona("mu mu!")  # True
    ilo.is_toki_pona("mi namako e moku mi")  # True
    ilo.is_toki_pona("ma wulin")  # False

if __name__ == "__main__":
    main()

Ilo is highly configurable by necessity, so I recommend looking through the premade configs in Configs as well as the individual Preprocessors, Filters, and Scorers. In Cleaners, all you need is ConsecutiveDuplicates. In Tokenizers, the preferred tokenizers WordTokenizer and SentTokenizer are already the default in Ilo.

Development

  1. Install pdm
  2. pdm install --dev
  3. Open any file you like!

FAQ

Why isn't this README/library written in Toki Pona?

The intent is to show our methodology to the Unicode Consortium, particularly to the Script Encoding Working Group (previously the Script Ad Hoc Group). As far as we're aware, zero members of the committee know Toki Pona, which unfortunately means we fall back on English.

I originally intended to translate this file and library into Toki Pona once Unicode had reviewed our proposal, but this library has picked up some interest outside of the Toki Pona community, so this library and README will remain accessible to them.

What's the deal with the tokenizers?

The Toki Pona tokenizer sonatoki.Tokenizers.WordTokenizer attempts to tokenize statements such that every token either represents a word candidate ("toki", "mumumu") or a complete non-candidate ("..!", "123"). This design is highly undesirable for NLTK's English tokenizer because words in languages other than Toki Pona can have punctuation characters in or around them which are part of the word. Toki Pona doesn't have any mid-word symbols when rendered in the Latin alphabet or in Private Use Area Unicode characters, so a more aggressive tokenizer is highly desirable. However, this tokenizer doesn't ignore intra-word punctuation entirely. Instead, exactly one of -, ', or . is allowed at a time, so long as both of its neighbors are writing characters. This increases the accuracy of the tokenizer significantly, which increases the scoring accuracy of the library, ultimately making it easier to correctly identify Toki Pona sentences among arbitrary ones. The reason for this is that, while Toki Pona itself does not have intra-word punctuation, Toki Pona may be written in mixed language environments; a more accurate tokenizer is less likely to produce sentence fragments, and accurately captured sentences are more likely to be identified as the actual language they are written in.

Another note: The intent of splitting into word candidates and non-candidates is important, because any encoding of Toki Pona's logographic script will require each character be split into its own token, where the default behavior would be to leave consecutive non-punctuation together.

Aren't there a lot of false positives?

For any individual filter, yes. Here are some examples:

  • ProperName will errantly match text in languages without a capital/lowercase distinction
  • Alphabetic matches words so long as they are only made of letters in Toki Pona's alphabet, which is 14 letters of the Latin alphabet.
  • Syllabic and Phonetic, despite imposing more structure than Alphabetic, will match a surprising amount of English words. For example, every word in "an awesome joke!" matches.
  • NimiPu and NimiLinkuCore will match a, mute, open regardless of the surrounding language.

This is point of Ilo and the Scorers: None of these filters would individually be able to correctly identify a Toki Pona statement, but all of them working together with some tuning are able to achieve a surprisingly high accuracy.

Don't some of the cleaners/filters conflict?

Yes, though not terribly much.

  • ConsecutiveDuplicates may errantly change a word's validity. For example, "manna" is phonotactically invalid in Toki Pona, but would become "mana" which is valid.
  • ConsecutiveDuplicates will not work correctly with syllabaries, though this should not change the validity of the analyzed word unless you attempt to dictionary match these words.
  • If you build your own MemberFilter with words that have capital letters or consecutive duplicates, they will never match unless you use prep_dictionary.

You'll notice these are mostly casued by applying latin alphabet filters to non-latin text. Working on it!

Metadata

Release files for sonatoki 0.13.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sonatoki 0.13.0
File Size Uploaded Provenance Actions
sonatoki-0.13.0.tar.gz 156.1 kB Without provenance Details for sonatoki-0.13.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sonatoki 0.13.0
File Interpreter ABI Platform Actions
sonatoki-0.13.0-py3-none-any.whl Python 3 none any Details for sonatoki-0.13.0-py3-none-any.whl

Total release size: 303.0 kB

Release files / sonatoki-0.13.0.tar.gz

Download URL sonatoki-0.13.0.tar.gz
Size 156.1 kB
Tags Source
SHA-256 checksum
How to use checksums
66d59cddf67abef9523318caaf596739947e2801a480925f2ad4689746e3ef06
BLAKE2b-256 checksum
How to use checksums
d8f57586daba2713c7497bee38657e8afb74edc1ef6140fc5e26f4db231d1895
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via pdm/2.28.0 CPython/3.11.15 Linux/6.17.0-1018-azure

Release files / sonatoki-0.13.0-py3-none-any.whl

Download URL sonatoki-0.13.0-py3-none-any.whl
Size 147.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b634ba32b2a9062a65f99e66be8be277996dd3ea6c79a217fb2032484af9fbb
BLAKE2b-256 checksum
How to use checksums
07dc66dd4bcefa5810a25850d0a9a5964561bb2b8cb698f681ab5b1372f668b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via pdm/2.28.0 CPython/3.11.15 Linux/6.17.0-1018-azure

Security for sonatoki 0.13.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.13.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page