Compare commits
No commits in common. "1257b79520d9082b317288fc875b63a35e51827d" and "158d6a73394c79ef895aa8dbe775c2fb21bf48b2" have entirely different histories.
1257b79520
...
158d6a7339
18
README.md
18
README.md
@ -1,19 +1,11 @@
|
|||||||
# Leipzig Glossing in Typst
|
# Leipzig Gloss
|
||||||
|
|
||||||
`leipzig-glossing` is a [Typst](https://github.com/typst/typst) library for
|
[Typst](https://github.com/typst/typst) library for creating interlinear morpheme-by-morpheme glosses according to the
|
||||||
creating interlinear morpheme-by-morpheme glosses according to the [Leipzig
|
[Leipzig glossing rules](https://www.eva.mpg.de/lingua/pdf/Glossing-Rules.pdf).
|
||||||
glossing rules](https://www.eva.mpg.de/lingua/pdf/Glossing-Rules.pdf).
|
|
||||||
|
|
||||||
Run `typst compile leipzig-gloss-examples.typ` in the root of the repository to
|
|
||||||
generate a pdf file with examples and documentation. This command is also
|
Generate the example pdf by running: `just build-example`.
|
||||||
codified in the accompanying [justfile](https://github.com/casey/just) as `just
|
|
||||||
build-example`.
|
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
This library uses the MIT license; see `LICENSE.txt`.
|
This library uses the MIT license; see `LICENSE.txt`.
|
||||||
|
|
||||||
# Contributors
|
|
||||||
|
|
||||||
Thanks to [Bethany E. Toma](https://github.com/betoma) for a number of
|
|
||||||
suggestions and improvements.
|
|
||||||
|
Binary file not shown.
@ -1,166 +1,63 @@
|
|||||||
#import "leipzig-gloss.typ": gloss, numbered_gloss, gloss_count
|
#import "leipzig-gloss.typ": gloss, numbered_gloss
|
||||||
#import "linguistic-abbreviations.typ": *
|
#import "linguistic-abbreviations.typ": *
|
||||||
|
|
||||||
#show link: x => underline[*#x*]
|
= Leipzig Glossing Examples
|
||||||
//#show raw: x => text(fill: rgb("#43464b"))[#x]
|
|
||||||
|
|
||||||
#let codeblock(contents) = block(fill: luma(230), inset: 8pt, radius: 4pt, breakable: false, contents)
|
|
||||||
|
|
||||||
|
|
||||||
= Introduction
|
|
||||||
|
|
||||||
Interlinear morpheme-by-morpheme glosses are common in linguistic texts to give
|
|
||||||
information about the meanings of individual words and morphemes in the
|
|
||||||
language being studied. A set of conventions called the *Leipzig Glossing Rules*
|
|
||||||
was developed to give linguists a general set of standards and principles for
|
|
||||||
how to format these glosses. The most recent version of these rules can be
|
|
||||||
found in PDF form at
|
|
||||||
#link("https://www.eva.mpg.de/lingua/pdf/Glossing-Rules.pdf")[this link],
|
|
||||||
provided by the Department of Linguistics at the Max Planck Institute for
|
|
||||||
Evolutionary Anthropology.
|
|
||||||
|
|
||||||
There is a staggering variety of LaTex packages designed to properly align and
|
|
||||||
format glosses (including `gb4e`, `ling-macros`, `linguex`, `expex`, and
|
|
||||||
probably even more). These modules vary in the complexity of their syntax and
|
|
||||||
the amount of control they give to the user of various aspects of formatting.
|
|
||||||
The `typst-leipzig-glossing` module is designed to provide utilities for
|
|
||||||
creating aligned Leipzig-style glosses in Typst, while keeping the syntax as
|
|
||||||
intuitive as possible and allowing users as much control over how their glosses
|
|
||||||
look as is feasible.
|
|
||||||
|
|
||||||
This PDF will show examples of the module's functionality and detail relevant
|
|
||||||
parameters. For more information or to inform devs of a bug or other issue,
|
|
||||||
visit the module's Github repository
|
|
||||||
#link("https://github.com/neunenak/typst-leipzig-glossing")[neunenak/typst-leipzig-glossing].
|
|
||||||
|
|
||||||
= Basic glossing functionality
|
|
||||||
|
|
||||||
|
|
||||||
As a first example, here is a gloss of a text in Georgian, along with the Typst code used to generate it:
|
|
||||||
|
|
||||||
|
This is the classic example of the inflected Georgian verb with an 8-segment consonant cluster:
|
||||||
|
|
||||||
#gloss(
|
#gloss(
|
||||||
header_text: [from "Georgian and the Unaccusative Hypothesis", Alice Harris, 1982],
|
source_text: ([გვ-ფრცქვნ-ი],),
|
||||||
|
source_text_style: none,
|
||||||
|
transliteration: ([gv-prtskvn-i],),
|
||||||
|
morphemes: ([1pl.#obj\-peel-#fmnt],),
|
||||||
|
translation: "You peeled us",
|
||||||
|
)
|
||||||
|
|
||||||
|
Some more Georgian:
|
||||||
|
|
||||||
|
#gloss(
|
||||||
|
header_text: [from "Georgian and the Unaccusative Hypothesis", Harris, 1982],
|
||||||
source_text: ([ბავშვ-ი], [ატირდა]),
|
source_text: ([ბავშვ-ი], [ატირდა]),
|
||||||
|
source_text_style: (item) => text(fill: red)[#item],
|
||||||
transliteration: ([bavšv-i], [aṭirda]),
|
transliteration: ([bavšv-i], [aṭirda]),
|
||||||
morphemes: ([child-#smallcaps[nom]], [3S/cry/#smallcaps[incho]/II]),
|
morphemes: ([child-#smallcaps[nom]], [3S/cry/#smallcaps[incho]/II]),
|
||||||
translation: [The child burst out crying],
|
translation: [The child burst out crying],
|
||||||
)
|
)
|
||||||
|
|
||||||
#codeblock[
|
|
||||||
```typst
|
```typst
|
||||||
|
|
||||||
#gloss(
|
#gloss(
|
||||||
header_text: [from "Georgian and the Unaccusative Hypothesis", Alice Harris, 1982],
|
header_text: [from "Georgian and the Unaccusative Hypothesis", Harris, 1982],
|
||||||
source_text: ([ბავშვ-ი], [ატირდა]),
|
source_text: ([ბავშვ-ი], [ატირდა]),
|
||||||
|
source_text_style: (item) => text(fill: red)[#item],
|
||||||
transliteration: ([bavšv-i], [aṭirda]),
|
transliteration: ([bavšv-i], [aṭirda]),
|
||||||
morphemes: ([child-#smallcaps[nom]], [3S/cry/#smallcaps[incho]/II]),
|
morphemes: ([child-#smallcaps[nom]], [3S/cry/#smallcaps[incho]/II]),
|
||||||
translation: [The child burst out crying],
|
translation: [The child burst out crying],
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
]
|
|
||||||
|
|
||||||
And an example for English which exhibits some additional styling, and uses imports from another file
|
And how about an example in English:
|
||||||
for common glossing abbreviations:
|
|
||||||
|
|
||||||
#gloss(
|
#gloss(
|
||||||
source_text: ([I'm], [eat-ing], [your], [head]),
|
source_text: ([I'm], [eat-ing], [your], [head]),
|
||||||
source_text_style: (item) => text(fill: red)[#item],
|
|
||||||
morphemes: ([1#sg.#sbj\=to.be], [eat-#prog], [2#sg.#pos], [head]),
|
morphemes: ([1#sg.#sbj\=to.be], [eat-#prog], [2#sg.#pos], [head]),
|
||||||
morphemes_style: text.with(fill: blue),
|
morphemes_style: text.with(fill: blue),
|
||||||
translation: text(weight: "semibold")[I'm eating your head!],
|
translation: text(weight: "semibold")[I'm eating your head!],
|
||||||
)
|
)
|
||||||
|
|
||||||
#codeblock(
|
```typst
|
||||||
[```typst
|
|
||||||
#import "linguistic-abbreviations.typ": *
|
|
||||||
|
|
||||||
#gloss(
|
#gloss(
|
||||||
source_text: ([I'm], [eat-ing], [your], [head]),
|
source_text: ([I'm], [eat-ing], [your], [head]),
|
||||||
source_text_style: (item) => text(fill: red)[#item],
|
|
||||||
morphemes: ([1#sg.#subj\=to.be], [eat-#prog], [2#sg.#pos], [head]),
|
morphemes: ([1#sg.#subj\=to.be], [eat-#prog], [2#sg.#pos], [head]),
|
||||||
morphemes_style: text.with(fill: blue),
|
morphemes_style: text.with(fill: blue),
|
||||||
translation: text(weight: "semibold")[I'm eating your head!],
|
translation: text(weight: "semibold")[I'm eating your head!],
|
||||||
)
|
)
|
||||||
```])
|
```
|
||||||
|
|
||||||
|
== Leipzig Glossing Rules PDF examples
|
||||||
|
|
||||||
The `#gloss` function has three pre-defined parameters for glossing levels:
|
See https://www.eva.mpg.de/lingua/pdf/Glossing-Rules.pdf
|
||||||
`source_text`, `transliteration`, and `morphemes`. It also has two parameters
|
|
||||||
for unaligned text: `header_text` for text that precedes the gloss, and
|
|
||||||
`translation` for text that follows the gloss.
|
|
||||||
|
|
||||||
If one wishes to add more than three glossing lines, there is an additional
|
|
||||||
parameter `additional_gloss_lines` that can take a list of arbitrarily many more glossing
|
|
||||||
lines, which will appear below those specified in the aforementioned
|
|
||||||
parameters:
|
|
||||||
|
|
||||||
#gloss(
|
|
||||||
header_text: [Hunzib (van den Berg 1995:46)],
|
|
||||||
source_text: ([ождиг],[хо#super[н]хе],[мукъер]),
|
|
||||||
transliteration: ([oʒdig],[χõχe],[muqʼer]),
|
|
||||||
morphemes: ([ož-di-g],[xõxe],[m-uq'e-r]),
|
|
||||||
additional_gloss_lines: (
|
|
||||||
([boy-#smallcaps[obl]-#smallcaps[ad]], [tree(#smallcaps[g4])], [#smallcaps[g4]-bend-#smallcaps[pret]]),
|
|
||||||
([at boy], [tree], [bent]),
|
|
||||||
),
|
|
||||||
translation: ["Because of the boy, the tree bent."]
|
|
||||||
)
|
|
||||||
|
|
||||||
#codeblock(
|
|
||||||
[```typst
|
|
||||||
#gloss(
|
|
||||||
header_text: [Hunzib (van den Berg 1995:46)],
|
|
||||||
source_text: ([ождиг],[хо#super[н]хе],[мукъер]),
|
|
||||||
transliteration: ([oʒdig],[χõχe],[muqʼer]),
|
|
||||||
morphemes: ([ož-di-g],[xõxe],[m-uq'e-r]),
|
|
||||||
additional_gloss_lines: (
|
|
||||||
([boy-#smallcaps[obl]-#smallcaps[ad]], [tree(#smallcaps[g4])], [#smallcaps[g4]-bend-#smallcaps[pret]]),
|
|
||||||
([at boy], [tree], [bent]),
|
|
||||||
),
|
|
||||||
translation: ["Because of the boy, the tree bent."]
|
|
||||||
)
|
|
||||||
```])
|
|
||||||
|
|
||||||
To number gloss examples, use `#numbered_gloss` in place of `gloss`. All other parameters remain the same.
|
|
||||||
|
|
||||||
#numbered_gloss(
|
|
||||||
source_text: ([გვ-ფრცქვნ-ი],),
|
|
||||||
source_text_style: none,
|
|
||||||
transliteration: ([gv-prtskvn-i],),
|
|
||||||
morphemes: ([1#pl.#obj\-peel-#fmnt],),
|
|
||||||
translation: "You peeled us",
|
|
||||||
)
|
|
||||||
|
|
||||||
#codeblock[
|
|
||||||
```typst
|
|
||||||
#import "linguistic-abbreviations.typ": *
|
|
||||||
|
|
||||||
#gloss(
|
|
||||||
source_text: ([გვ-ფრცქვნ-ი],),
|
|
||||||
source_text_style: none,
|
|
||||||
transliteration: ([gv-prtskvn-i],),
|
|
||||||
morphemes: ([1#pl.#obj\-peel-#fmnt],),
|
|
||||||
translation: "You peeled us",
|
|
||||||
```)]
|
|
||||||
|
|
||||||
The displayed number for numbered glosses is iterated for each numbered gloss
|
|
||||||
that appears throughout the document. Unnumbered glosses do not increment the
|
|
||||||
counter for the numbered glosses.
|
|
||||||
|
|
||||||
The gloss count is controlled by the Typst counter variable `gloss_count`. This
|
|
||||||
variable can be imported from the `leipzig-gloss` package and reset using the
|
|
||||||
standard Typst counter functions to control gloss numbering.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
== Further Example Glosses
|
|
||||||
|
|
||||||
These example glosses replicate the ones given in
|
|
||||||
#link("https://www.eva.mpg.de/lingua/pdf/Glossing-Rules.pdf").
|
|
||||||
|
|
||||||
#{
|
|
||||||
gloss_count.update(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#numbered_gloss(
|
#numbered_gloss(
|
||||||
header_text: [Indonesian (Sneddon 1996:237)],
|
header_text: [Indonesian (Sneddon 1996:237)],
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#let gloss_count = counter("gloss_count")
|
#let gloss_count = counter("gloss_count")
|
||||||
|
|
||||||
#let build_gloss(spacing_between_items, formatters, gloss_line_lists) = {
|
#let gloss_lines(spacing_between_items, formatters, gloss_line_lists) = {
|
||||||
assert(gloss_line_lists.len() > 0, message: "Gloss line lists cannot be empty")
|
assert(gloss_line_lists.len() > 0, message: "Gloss line lists cannot be empty")
|
||||||
|
|
||||||
let len = gloss_line_lists.at(0).len()
|
let len = gloss_line_lists.at(0).len()
|
||||||
@ -44,10 +44,7 @@
|
|||||||
additional_gloss_lines: (), //List of list of content
|
additional_gloss_lines: (), //List of list of content
|
||||||
translation: none,
|
translation: none,
|
||||||
spacing_between_items: 1em,
|
spacing_between_items: 1em,
|
||||||
gloss_padding: 2.0em, //TODO document these
|
|
||||||
left_padding: 0.5em,
|
|
||||||
numbering: false,
|
numbering: false,
|
||||||
breakable: false,
|
|
||||||
) = {
|
) = {
|
||||||
|
|
||||||
assert(type(source_text) == "array", message: "source_text needs to be an array; perhaps you forgot to type `(` and `)`, or a trailing comma?")
|
assert(type(source_text) == "array", message: "source_text needs to be an array; perhaps you forgot to type `(` and `)`, or a trailing comma?")
|
||||||
@ -83,7 +80,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
build_gloss(spacing_between_items, formatters, gloss_line_lists)
|
gloss_lines(spacing_between_items, formatters, gloss_line_lists)
|
||||||
|
|
||||||
if translation != none {
|
if translation != none {
|
||||||
linebreak()
|
linebreak()
|
||||||
@ -101,20 +98,7 @@
|
|||||||
none
|
none
|
||||||
}
|
}
|
||||||
|
|
||||||
//[#gloss_number #pad(left: 1em)[#gloss_items]]
|
[#gloss_number #pad(left: 1em)[#gloss_items]]
|
||||||
|
|
||||||
style(styles => {
|
|
||||||
block(breakable: breakable)[
|
|
||||||
#stack(
|
|
||||||
dir:ltr, //TODO this needs to be more flexible
|
|
||||||
left_padding,
|
|
||||||
[#gloss_number],
|
|
||||||
gloss_padding - left_padding - measure([#gloss_number],styles).width,
|
|
||||||
[#gloss_items]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#let numbered_gloss = gloss.with(numbering: true)
|
#let numbered_gloss = gloss.with(numbering: true)
|
||||||
|
Loading…
Reference in New Issue
Block a user