Compare commits

...

10 Commits

Author SHA1 Message Date
Greg Shuflin
1257b79520 More documentation improvements 2023-07-04 01:15:00 -07:00
Greg Shuflin
ea57c70300 Update README 2023-07-04 00:49:00 -07:00
Greg Shuflin
a52c889925 More documentation improvements 2023-07-04 00:45:47 -07:00
Greg Shuflin
1cc3bd5d4b Use ltr stack technique to display gloss
This lets the numbering appear on the same line as the gloss.
2023-07-03 16:35:01 -07:00
Greg Shuflin
738afcfdaf Add missing example 2023-07-03 03:06:04 -07:00
Greg Shuflin
5fcc9e64b4 Start adding explicit documentation 2023-07-03 02:45:41 -07:00
Greg Shuflin
4e286319af Add Contributors section of README 2023-07-03 02:41:27 -07:00
Greg Shuflin
c88181acef Use codeblock fn 2023-07-03 02:34:20 -07:00
Greg Shuflin
d0592515b1 Some more verbiage changes 2023-07-03 02:18:36 -07:00
Greg Shuflin
94d8164bcf Add introductary text
Adapted from https://github.com/neunenak/typst-leipzig-glossing/pull/1
2023-07-03 01:49:48 -07:00
4 changed files with 158 additions and 31 deletions

View File

@ -1,11 +1,19 @@
# Leipzig Gloss # Leipzig Glossing in Typst
[Typst](https://github.com/typst/typst) library for creating interlinear morpheme-by-morpheme glosses according to the `leipzig-glossing` is a [Typst](https://github.com/typst/typst) library for
[Leipzig glossing rules](https://www.eva.mpg.de/lingua/pdf/Glossing-Rules.pdf). creating interlinear morpheme-by-morpheme glosses according to the [Leipzig
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 the example pdf by running: `just build-example`. generate a pdf file with examples and documentation. This command is also
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.

View File

@ -1,63 +1,166 @@
#import "leipzig-gloss.typ": gloss, numbered_gloss #import "leipzig-gloss.typ": gloss, numbered_gloss, gloss_count
#import "linguistic-abbreviations.typ": * #import "linguistic-abbreviations.typ": *
= Leipzig Glossing Examples #show link: x => underline[*#x*]
//#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(
source_text: ([გვ-ფრცქვნ-ი],), header_text: [from "Georgian and the Unaccusative Hypothesis", Alice Harris, 1982],
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", Harris, 1982], header_text: [from "Georgian and the Unaccusative Hypothesis", Alice 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 how about an example in English: And an example for English which exhibits some additional styling, and uses imports from another file
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!],
) )
```typst #codeblock(
[```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
See https://www.eva.mpg.de/lingua/pdf/Glossing-Rules.pdf The `#gloss` function has three pre-defined parameters for glossing levels:
`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)],

View File

@ -1,6 +1,6 @@
#let gloss_count = counter("gloss_count") #let gloss_count = counter("gloss_count")
#let gloss_lines(spacing_between_items, formatters, gloss_line_lists) = { #let build_gloss(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,7 +44,10 @@
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?")
@ -80,7 +83,7 @@
} }
gloss_lines(spacing_between_items, formatters, gloss_line_lists) build_gloss(spacing_between_items, formatters, gloss_line_lists)
if translation != none { if translation != none {
linebreak() linebreak()
@ -98,7 +101,20 @@
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)