Skip to content

Commit 2dff909

Browse files
committed
ENH v4.2.0
1 parent 9475d53 commit 2dff909

125 files changed

Lines changed: 28148 additions & 138 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,5 @@
11
version: 2
22
updates:
3-
- package-ecosystem: "cargo"
4-
directory: "/"
5-
schedule:
6-
interval: "weekly"
7-
- package-ecosystem: "pip"
8-
directory: "/"
9-
schedule:
10-
interval: "weekly"
113
- package-ecosystem: "github-actions"
124
directory: "/"
135
schedule:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ docs/generated/
1515

1616
# Benchmarks
1717
benchmarks/_baseline/
18+
19+
# From maturin develop
20+
src/pycantonese/lib_pycantonese.dylib.dSYM/

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
1313
### Fixed
1414
### Security
1515

16+
## [4.2.0] - 2026-03-27
17+
18+
### Added
19+
- Added the CantoMap corpus.
20+
- Added `from_git` and `from_url` to `CHAT` to support fetching datasets from remote sources.
21+
22+
### Changed
23+
- Bumped rustling to >= 0.8.0.
24+
1625
## [4.1.0] - 2026-03-14
1726

1827
### Added

Cargo.lock

Lines changed: 14 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pycantonese"
3-
version = "4.1.0"
3+
version = "4.2.0"
44
edition = "2024"
55

66
[lib]
@@ -10,7 +10,7 @@ path = "src/rust/lib.rs"
1010

1111
[dependencies]
1212
pyo3 = { version = "0.28", features = ["abi3-py310"] }
13-
rustling = { version = "0.7.0", default-features = false, features = ["pyo3"] }
13+
rustling = { version = "0.8.0", default-features = false, features = ["pyo3"] }
1414
regex = "1"
1515

1616
[features]

README.rst

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,11 @@ Using conda::
5151

5252
conda install -c conda-forge pycantonese
5353

54-
For Pyodide, install the WASM wheels (the ``.whl`` files with ``emscripten`` in the filename)
55-
from the GitHub releases of
56-
`Rustling <https://github.com/jacksonllee/rustling/releases>`_ and
57-
`PyCantonese <https://github.com/jacksonllee/pycantonese/releases>`_.
54+
PyCantonese also works
55+
`in JavaScript <https://docs.pycantonese.org/stable/quickstart.html#javascript>`_.
5856

5957
Ready for more?
60-
Check out the `Quickstart <https://pycantonese.org/quickstart.html>`_ page.
58+
Check out `Quickstart <https://docs.pycantonese.org/stable/quickstart.html>`_.
6159

6260
Links
6361
-----
@@ -98,6 +96,7 @@ Please note that PyCantonese includes data from the following sources,
9896
all of which are permissively licensed:
9997

10098
- Hong Kong Cantonese Corpus (CC BY)
99+
- CantoMap (GPL-3.0)
101100
- rime-cantonese (CC BY 4.0)
102101
- Common Voice Cantonese (Mozilla Public License 2.0)
103102
- Cantonese-Traditional Chinese Parallel Corpus (CC0 1.0 Universal)

docs/api.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Corpus Data
1414

1515
read_chat
1616
hkcancor
17+
cantomap
1718
CHAT
1819
CHAT.search
1920

@@ -58,6 +59,12 @@ Natural Language Processing
5859
.. autoclass:: pycantonese.corpus.Token
5960

6061

62+
:class:`~pycantonese.corpus.Utterance`
63+
--------------------------------------
64+
65+
.. autoclass:: pycantonese.corpus.Utterance
66+
67+
6168
:class:`~pycantonese.jyutping.Jyutping`
6269
---------------------------------------
6370

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,5 @@
9191
# Example configuration for intersphinx: refer to the Python standard library.
9292
intersphinx_mapping = {
9393
"python": ('https://docs.python.org/3/', None),
94-
"rustling": ("https://rustling.readthedocs.io/stable/", None),
94+
"rustling": ("https://docs.rustling.io/stable/", None),
9595
}

docs/data.rst

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,21 @@ For these reasons, PyCantonese adopts the `CHAT <https://talkbank.org/0info/manu
1717
corpus format from CHILDES and TalkBank.
1818
CHAT is widely used, well-documented, and rich for linguistic annotations.
1919
PyCantonese uses the library
20-
`Rustling <https://rustling.readthedocs.io/stable/chat.html>`_ to parse CHAT data files.
20+
`Rustling <https://docs.rustling.io/stable/chat.html>`_ to parse CHAT data files.
2121
For a primer on the CHAT data format, please see
22-
`here <https://docs.pylangacq.org/stable/transcriptions.html#chat-format>`_.
22+
`here <https://docs.rustling.io/stable/chat/transcriptions.html#chat-format>`_.
2323

2424

2525
Built-in Data
2626
-------------
2727

28-
Currently, PyCantonese comes with one built-in corpus, the
29-
`Hong Kong Cantonese Corpus <https://github.com/fcbond/hkcancor>`_
30-
(HKCanCor; license: CC BY), via the function :func:`~pycantonese.hkcancor`:
28+
PyCantonese ships with two built-in corpora: HKCanCor and CantoMap.
29+
30+
HKCanCor
31+
^^^^^^^^
32+
33+
The `Hong Kong Cantonese Corpus <https://github.com/fcbond/hkcancor>`_
34+
(HKCanCor; license: CC BY) is available via the function :func:`~pycantonese.hkcancor`:
3135

3236
.. code-block:: python
3337
@@ -46,11 +50,39 @@ They have been converted to CHAT for incorporation into PyCantonese.
4650
On the format conversion, please consult this
4751
`readme <https://github.com/jacksonllee/pycantonese/blob/main/src/pycantonese/data/hkcancor/README.md>`_.
4852

53+
CantoMap
54+
^^^^^^^^
55+
56+
The `CantoMap <https://github.com/gwinterstein/CantoMap>`_ corpus
57+
(license: GPL-3.0) is a collection of contemporary Hong Kong Cantonese
58+
conversation recordings from MapTask exercises.
59+
It is available via the function :func:`~pycantonese.cantomap`:
60+
61+
.. code-block:: python
62+
63+
import pycantonese
64+
cantomap = pycantonese.cantomap()
65+
cantomap.n_files # number of data files
66+
# 99
67+
len(cantomap.words()) # number of words as segmented from all the utterances
68+
# 118572
69+
70+
CantoMap is word-segmented and annotated for Jyutping romanization.
71+
Part-of-speech tags (HKCanCor tagset) are added by PyCantonese's POS tagger
72+
during the conversion from ELAN to CHAT format.
73+
74+
The original CantoMap source files are in the ELAN annotation format (``.eaf``).
75+
Because the CHAT format inherently requires word-segmented data,
76+
it is a natural fit for the word-segmented, Jyutping-annotated CantoMap data.
77+
The ELAN files have been converted to CHAT for incorporation into PyCantonese.
78+
On the format conversion, please consult this
79+
`readme <https://github.com/jacksonllee/pycantonese/blob/main/src/pycantonese/data/cantomap/README.md>`_.
80+
4981

5082
CHILDES and TalkBank Data
5183
-------------------------
5284

53-
For corpora other than HKCanCor, PyCantonese provides the function :func:`~pycantonese.read_chat`
85+
For corpora beyond the built-in ones, PyCantonese provides the function :func:`~pycantonese.read_chat`
5486
to read in Cantonese data in the CHAT format.
5587

5688
As of 2026, CHAT datasets are publicly available from `TalkBank <https://talkbank.org/>`_.
@@ -63,35 +95,43 @@ before you can download the full transcripts as a ZIP archive to your local driv
6395

6496
Here are the Cantonese-related TalkBank datasets (in alphabetical order):
6597

66-
* `Child Heritage Chinese Corpus <https://childes.talkbank.org/access/Biling/CHCC.html>`_
98+
* `Child Heritage Chinese Corpus <https://talkbank.org/childes/access/Biling/CHCC.html>`_
6799

68-
* `Guthrie Bilingual Corpus <https://childes.talkbank.org/access/Biling/Guthrie.html>`_
100+
* `Guthrie Bilingual Corpus <https://talkbank.org/childes/access/Biling/Guthrie.html>`_
69101

70-
* `HKU-70 Corpus <https://childes.talkbank.org/access/Chinese/Cantonese/HKU.html>`_
102+
* `HKU-70 Corpus <https://talkbank.org/childes/access/Chinese/Cantonese/HKU.html>`_
71103

72-
* `Lee-Wong-Leung Corpus <https://childes.talkbank.org/access/Chinese/Cantonese/LeeWongLeung.html>`_
104+
* `Lee-Wong-Leung Corpus <https://talkbank.org/childes/access/Chinese/Cantonese/LeeWongLeung.html>`_
73105

74106
* `Mandarin-Cantonese-English EACMC Corpus <https://talkbank.org/childes/access/Biling/EACMC.html>`_
75107

76-
* `Yip-Matthews Bilingual Corpus <https://childes.talkbank.org/access/Biling/YipMatthews.html>`_
108+
* `Yip-Matthews Bilingual Corpus <https://talkbank.org/childes/access/Biling/YipMatthews.html>`_
77109

78110

79111
Custom Data
80112
-----------
81113

82-
If you have your own CHAT data locally and would
83-
like PyCantonese to handle it, :func:`~pycantonese.read_chat`
84-
takes a path that can be a ZIP archive, a local directory, or a single CHAT file.
85-
86-
If more fine-grained control is needed when reading data, please check out
87-
:class:`~pycantonese.CHAT`, particularly the following methods:
88-
89-
* :py:meth:`~pycantonese.CHAT.from_zip`
90-
* :py:meth:`~pycantonese.CHAT.from_dir`
91-
* :py:meth:`~pycantonese.CHAT.from_files`
92-
* :py:meth:`~pycantonese.CHAT.from_strs`
93-
94-
The CHAT parser comes from `Rustling <https://rustling.readthedocs.io/stable/chat.html>`_,
95-
which both PyCantonese and PyLangAcq use.
96-
For more on reading CHAT data in general, please see
97-
`PyLangAcq's documentation <https://docs.pylangacq.org/stable/read.html>`_.
114+
If you have your own CHAT data,
115+
:func:`~pycantonese.read_chat` accepts a local ZIP archive,
116+
a local directory, or a single ``.cha`` file path.
117+
118+
For more control over how data is read, the :class:`~pycantonese.CHAT` class
119+
provides the following class methods:
120+
121+
* :py:meth:`~pycantonese.CHAT.from_zip` -- local ZIP archive
122+
* :py:meth:`~pycantonese.CHAT.from_dir` -- local directory
123+
* :py:meth:`~pycantonese.CHAT.from_files` -- one or more local file paths
124+
* :py:meth:`~pycantonese.CHAT.from_strs` -- in-memory strings
125+
* :py:meth:`~pycantonese.CHAT.from_git` -- Git repository (cloned and cached)
126+
* :py:meth:`~pycantonese.CHAT.from_url` -- URL to a ZIP archive (downloaded and cached)
127+
128+
The CHAT parser is powered by `Rustling <https://docs.rustling.io/stable/chat.html>`_,
129+
with Cantonese-specific additions for Jyutping romanization, Chinese characters,
130+
and a general corpus search function.
131+
132+
If your data is in one of the
133+
`formats supported by Rustling <https://docs.rustling.io/stable/>`_,
134+
you can use Rustling to parse it, apply any processing you need,
135+
and create a :class:`~pycantonese.CHAT` object via :py:meth:`~pycantonese.CHAT.from_strs`.
136+
For an example of this workflow, see how the CantoMap ELAN data is
137+
`converted for use in PyCantonese <https://github.com/jacksonllee/pycantonese/blob/main/src/pycantonese/data/cantomap/README.md>`_.

docs/parsing.rst

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Note:
4242
:func:`~pycantonese.CHAT.utterances`, :func:`~pycantonese.CHAT.search`, etc).
4343
* Since CHAT is designed for conversational data and your input data is a string,
4444
:func:`~pycantonese.parse_text` attempts simple utterance segmentation
45-
(by the Chinese full-width punctuation marks ``{"", "!", ""}``
45+
(by the Chinese full-width punctuation marks ``{"", "!", ""}``
4646
as well as the end-of-line character ``"\n"``).
4747
* By default, a dummy participant ``"X"`` is assigned to each utterance.
4848
To provide your own participant, pass it to the ``participant`` keyword argument of
@@ -143,20 +143,15 @@ This way, you can more easily share the processed data with your colleagues,
143143
reload the data (see :ref:`data`) for further processing and analysis in your workflow,
144144
and so forth.
145145

146-
With a :class:`~pycantonese.CHAT` object, simply call the :func:`~pycantonese.CHAT.to_chat`
147-
method with a local file path.
146+
With a :class:`~pycantonese.CHAT` object, simply call the :func:`~pycantonese.CHAT.to_files`
147+
method with a local directory path.
148148

149149
.. skip: start
150150
151151
.. code-block:: python
152152
153-
file_path = "result.cha"
154-
corpus.to_chat(file_path)
155-
156-
# If you're running code on Google Colab,
157-
# you can download the file like this:
158-
from google.colab import files
159-
files.download(file_path)
153+
dir_path = "output"
154+
corpus.to_files(dir_path)
160155
161156
.. skip: end
162157

0 commit comments

Comments
 (0)