Add sub-examples functionality (#7)
* Add sub-examples (resolves #4) * Separate `gloss()` and `example()` `gloss()` typesets are interlinear glosses, while `example()` treats everything extra that has to do with linguistic examples.
This commit is contained in:
parent
c7eded63d5
commit
ae3784f4ec
Binary file not shown.
@ -1,5 +1,7 @@
|
|||||||
#set document(title: "typst leipzig-glossing documentation")
|
#set document(title: "typst leipzig-glossing documentation")
|
||||||
#import "leipzig-gloss.typ": abbreviations, gloss, numbered-gloss, gloss-count
|
#import "leipzig-gloss.typ": abbreviations, example, example-count, gloss, numbered-example
|
||||||
|
|
||||||
|
#set heading(numbering: "1.")
|
||||||
|
|
||||||
#show link: x => underline[*#x*]
|
#show link: x => underline[*#x*]
|
||||||
|
|
||||||
@ -11,14 +13,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
block(stroke: 0.5pt + black, inset: 4pt, width: 100%, breakable: false)[
|
block(stroke: 0.5pt + black, inset: 4pt, width: 100%, breakable: false)[
|
||||||
#eval(contents, mode: "markup", scope: (gloss: gloss, numbered-gloss: numbered-gloss) + addl-bindings)
|
#eval(contents, mode: "markup", scope: (gloss: gloss, example: example, numbered-example: numbered-example) + addl-bindings)
|
||||||
#block(fill: luma(230), inset: 8pt, radius: 4pt, breakable: false, width: 100%, raw(full-contents, lang: "typst"))
|
#block(fill: luma(230), inset: 8pt, radius: 4pt, breakable: false, width: 100%, raw(full-contents, lang: "typst"))
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Abbreviations used in this document
|
// Abbreviations used in this document
|
||||||
|
|
||||||
#import abbreviations: poss, prog, sg, pl, sbj, obj, fut, neg, obl, gen, com, ins, all, pst, inf
|
#import abbreviations: poss, prog, sg, pl, sbj, obj, fut, neg, obl, gen, com, ins, all, pst, inf, indf, def, dem, pred
|
||||||
#import abbreviations: art, dat, du, A, P, prf
|
#import abbreviations: art, dat, du, A, P, prf
|
||||||
|
|
||||||
#let fmnt = abbreviations.emit-abbreviation("FMNT")
|
#let fmnt = abbreviations.emit-abbreviation("FMNT")
|
||||||
@ -55,10 +57,8 @@ visit the module's Github repository
|
|||||||
|
|
||||||
= Basic glossing functionality
|
= 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:
|
As a first example, here is a gloss of a text in Georgian, along with the Typst code used to generate it:
|
||||||
|
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#gloss(
|
"#gloss(
|
||||||
header: [from \"Georgian and the Unaccusative Hypothesis\", Alice Harris, 1982],
|
header: [from \"Georgian and the Unaccusative Hypothesis\", Alice Harris, 1982],
|
||||||
@ -68,138 +68,20 @@ As a first example, here is a gloss of a text in Georgian, along with the Typst
|
|||||||
translation: [The child burst out crying],
|
translation: [The child burst out crying],
|
||||||
)", unevaled-first-line: "#import \"leipzig-gloss.typ\": gloss")
|
)", unevaled-first-line: "#import \"leipzig-gloss.typ\": gloss")
|
||||||
|
|
||||||
|
The function `gloss()` typesets _bare_ interlinear glosses (including styling, see @styling and @additional-lines). Normally when adding linguistic examples use the `example()` function, which calls `gloss()` internally and includes functionality that has to do with linguistic examples: numbering, labelling/referencing and sub-examples. `gloss()` is to be used when only the basic function of typesetting interlinear glosses is needed. Unlike `gloss()`, the function `example()` does not take the different parameters directly, but takes a list of dictionaries whose keys and values correspond to `gloss()`’s parameters (with added options such as `label` and `numbering`). It also indents the text even when numbering is not enabled:
|
||||||
And an example for English which exhibits some additional styling, and uses imports from another file
|
|
||||||
for common glossing abbreviations:
|
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#gloss(
|
"#example(
|
||||||
source: ([I'm], [eat-ing], [your], [head]),
|
(
|
||||||
source-style: (item) => text(fill: red)[#item],
|
header: [from \"Georgian and the Unaccusative Hypothesis\", Alice Harris, 1982],
|
||||||
morphemes: ([1#sg.#sbj\=to.be], [eat-#prog], [2#sg.#poss], [head]),
|
source: ([ბავშვ-ი], [ატირდა]),
|
||||||
morphemes-style: text.with(size: 10pt, fill: blue),
|
transliteration: ([bavšv-i], [aṭirda]),
|
||||||
translation: text(weight: \"semibold\")[I'm eating your head!],
|
morphemes: ([child-#smallcaps[nom]], [3S/cry/#smallcaps[incho]/II]),
|
||||||
translation-style: (item) => [\"#item\"],
|
translation: [The child burst out crying],
|
||||||
)
|
)
|
||||||
", addl-bindings: (poss: poss, prog: prog, sg: sg, sbj: sbj))
|
)")
|
||||||
|
|
||||||
|
== Styling <styling>
|
||||||
The `#gloss` function has three pre-defined parameters for glossing levels:
|
|
||||||
`source`, `transliteration`, and `morphemes`. It also has two parameters
|
|
||||||
for unaligned text: `header` for text that precedes the gloss, and
|
|
||||||
`translation` for text that follows the gloss.
|
|
||||||
|
|
||||||
|
|
||||||
The `morphemes` param can be skipped, if you just want to provide a source
|
|
||||||
text and translation, without a gloss:
|
|
||||||
|
|
||||||
#codeblock(
|
|
||||||
"#gloss(
|
|
||||||
source: ([Trato de entender, debo comprender, qué es lo que ha hecho conmigo],),
|
|
||||||
source-style: emph,
|
|
||||||
translation: [I try to understand, I must comprehend, what she has done with me],
|
|
||||||
)
|
|
||||||
")
|
|
||||||
|
|
||||||
|
|
||||||
Note that it is still necessary to wrap the `source` argument in an array of length one.
|
|
||||||
|
|
||||||
Here is an example of a lengthy gloss that forces a line break:
|
|
||||||
|
|
||||||
// adapted from https://brill.com/fileasset/downloads_static/static_publishingbooks_formatting_glosses_linguistic_examples.pdf
|
|
||||||
#codeblock(
|
|
||||||
"#gloss(
|
|
||||||
source: ([Ich],[arbeite],[ein],[Jahr],[um],[das],[Geld], [zu],[verdienen,],[das], [dein],[Bruder], [an],[einem],[Wochenende],[ausgibt.]),
|
|
||||||
source-style: text.with(weight: \"bold\"),
|
|
||||||
morphemes: ([I], [work],[ one], [year],[to],[the],[money],[to],[earn,], [that],[your],[brother],[on],[one], [weekend], [spends.]),
|
|
||||||
translation: [\"I work one year to earn the money that your brother spends in one weekend\"]
|
|
||||||
)", addl-bindings: (poss: poss, prog: prog, sg: sg, sbj: sbj))
|
|
||||||
|
|
||||||
|
|
||||||
To add more than three glossing lines, there is an additional parameter
|
|
||||||
`additional-lines` that can take a list of arbitrarily many more glossing
|
|
||||||
lines, which will appear below those specified in the aforementioned
|
|
||||||
parameters:
|
|
||||||
|
|
||||||
#codeblock(
|
|
||||||
"#gloss(
|
|
||||||
header: [Hunzib (van den Berg 1995:46)],
|
|
||||||
source: ([ождиг],[хо#super[н]хе],[мукъер]),
|
|
||||||
transliteration: ([oʒdig],[χõχe],[muqʼer]),
|
|
||||||
morphemes: ([ož-di-g],[xõxe],[m-uq'e-r]),
|
|
||||||
additional-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.\"]
|
|
||||||
)
|
|
||||||
")
|
|
||||||
|
|
||||||
//TODO add a custom numbering system that can handle example 18a-c of Kartvelian Morphosyntax and Number Agreement
|
|
||||||
== Numbering Glosses
|
|
||||||
|
|
||||||
The `gloss` function takes a boolean parameter `numbering` which will add an incrementing
|
|
||||||
count to each gloss. A function `numbered-gloss` is exported for convenience; this is
|
|
||||||
defined as simply `#let numbered-gloss = gloss.with(numbering: true)`, and is called with the
|
|
||||||
same arguments as `gloss`:
|
|
||||||
|
|
||||||
|
|
||||||
#codeblock(
|
|
||||||
"#gloss(
|
|
||||||
source: ([გვ-ფრცქვნ-ი],),
|
|
||||||
transliteration: ([gv-prtskvn-i],),
|
|
||||||
morphemes: ([1#pl.#obj\-peel-#fmnt],),
|
|
||||||
translation: \"You peeled us\",
|
|
||||||
numbering: true,
|
|
||||||
)
|
|
||||||
|
|
||||||
#numbered-gloss(
|
|
||||||
source: ([მ-ფრცქვნ-ი],),
|
|
||||||
transliteration: ([m-prtskvn-i],),
|
|
||||||
morphemes: ([1#sg.#obj\-peel-#fmnt],),
|
|
||||||
translation: \"You peeled me\",
|
|
||||||
)
|
|
||||||
|
|
||||||
", addl-bindings: (pl: pl, obj: obj, sg: sg, fmnt: fmnt))
|
|
||||||
|
|
||||||
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 manipulated using the
|
|
||||||
standard Typst counter functions to control gloss numbering:
|
|
||||||
|
|
||||||
#codeblock(
|
|
||||||
"#gloss-count.update(20)
|
|
||||||
|
|
||||||
#numbered-gloss(
|
|
||||||
header: [from _Standard Basque: A Progressive Grammar_ by Rudolf de Rijk, quoting P. Charriton],
|
|
||||||
source: ([Bada beti guregan zorion handi baten nahia.],),
|
|
||||||
translation: [There always is in us a will for a great happiness.],
|
|
||||||
)", addl-bindings: (gloss-count: gloss-count))
|
|
||||||
|
|
||||||
References to individual examples can be achieved using the `label` argument and the referencing mechanism of Typst:
|
|
||||||
|
|
||||||
#codeblock(
|
|
||||||
"See @sorcerers:
|
|
||||||
|
|
||||||
#numbered-gloss(
|
|
||||||
header: [Middle Welsh; modified from _Grammatical number in Welsh_ (1999) by Silva Nurmio (§~2.1.1)],
|
|
||||||
source: ([ac], [ny], [allvs], [y], [dewinyon], [atteb], [idav]),
|
|
||||||
morphemes: ([and], [#neg], [be_able.#smallcaps[pret].3#sg], [#smallcaps[def]], [sorcerer.#pl], [answer.#smallcaps[inf]], [to.3#sg.#smallcaps[m]]),
|
|
||||||
translation: [and the sorcerers could not answer him],
|
|
||||||
label: \"sorcerers\",
|
|
||||||
label-supplement: [Example]
|
|
||||||
)
|
|
||||||
|
|
||||||
As we have seen in @sorcerers, […].", addl-bindings: (neg: neg, sg: sg, pl: pl))
|
|
||||||
|
|
||||||
Labeling uses the Typst #link("https://typst.app/docs/reference/model/figure/")[figure] document element. The `label-supplement`
|
|
||||||
parameter fills in the `suppliment` parameter of a `figure`, which is `[example]` by default.
|
|
||||||
|
|
||||||
|
|
||||||
== Styling lines of a gloss
|
|
||||||
|
|
||||||
Each of the aforementioned text parameters has a corresponding style parameter,
|
Each of the aforementioned text parameters has a corresponding style parameter,
|
||||||
formed by adding `-style` to its name: `header-style`, `source-style`,
|
formed by adding `-style` to its name: `header-style`, `source-style`,
|
||||||
@ -213,7 +95,8 @@ to or within any given content block in the gloss. Formatting applied in this
|
|||||||
way will override any contradictory line-level formatting.
|
way will override any contradictory line-level formatting.
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#gloss(
|
"#example(
|
||||||
|
(
|
||||||
header: [This text is about eating your head.],
|
header: [This text is about eating your head.],
|
||||||
header-style: text.with(weight: \"bold\", fill: green),
|
header-style: text.with(weight: \"bold\", fill: green),
|
||||||
source: (text(fill:black)[I'm], [eat-ing], [your], [head]),
|
source: (text(fill:black)[I'm], [eat-ing], [your], [head]),
|
||||||
@ -221,9 +104,211 @@ way will override any contradictory line-level formatting.
|
|||||||
morphemes: ([1#sg.#sbj\=to.be], text(fill:black)[eat-#prog], [2#sg.#poss], [head]),
|
morphemes: ([1#sg.#sbj\=to.be], text(fill:black)[eat-#prog], [2#sg.#poss], [head]),
|
||||||
morphemes-style: text.with(fill: blue),
|
morphemes-style: text.with(fill: blue),
|
||||||
translation: text(weight: \"bold\")[I'm eating your head!],
|
translation: text(weight: \"bold\")[I'm eating your head!],
|
||||||
|
)
|
||||||
)", addl-bindings: (prog: prog, sbj: sbj, poss: poss, sg: sg))
|
)", addl-bindings: (prog: prog, sbj: sbj, poss: poss, sg: sg))
|
||||||
|
|
||||||
//TODO add `line_styles` param
|
//TODO add `line-styles` param
|
||||||
|
|
||||||
|
An example for English which exhibits some additional styling, and uses imports from another file
|
||||||
|
for common glossing abbreviations:
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"#example(
|
||||||
|
(
|
||||||
|
source: ([I'm], [eat-ing], [your], [head]),
|
||||||
|
source-style: (item) => text(fill: red)[#item],
|
||||||
|
morphemes: ([1#sg.#sbj\=to.be], [eat-#prog], [2#sg.#poss], [head]),
|
||||||
|
morphemes-style: text.with(size: 10pt, fill: blue),
|
||||||
|
translation: text(weight: \"semibold\")[I'm eating your head!],
|
||||||
|
translation-style: (item) => [\"#item\"],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
", addl-bindings: (poss: poss, prog: prog, sg: sg, sbj: sbj))
|
||||||
|
|
||||||
|
|
||||||
|
The `gloss()` function has three pre-defined parameters for glossing levels:
|
||||||
|
`source`, `transliteration`, and `morphemes`. It also has two parameters
|
||||||
|
for unaligned text: `header` for text that precedes the gloss, and
|
||||||
|
`translation` for text that follows the gloss.
|
||||||
|
|
||||||
|
|
||||||
|
The `morphemes` param can be skipped, if you just want to provide a source
|
||||||
|
text and translation, without a gloss:
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"#example(
|
||||||
|
(
|
||||||
|
source: ([Trato de entender, debo comprender, qué es lo que ha hecho conmigo],),
|
||||||
|
source-style: emph,
|
||||||
|
translation: [I try to understand, I must comprehend, what she has done with me],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
")
|
||||||
|
|
||||||
|
|
||||||
|
Note that it is still necessary to wrap the `source` argument in an array of length one.
|
||||||
|
|
||||||
|
Here is an example of a lengthy gloss that forces a line break:
|
||||||
|
|
||||||
|
// adapted from https://brill.com/fileasset/downloads_static/static_publishingbooks_formatting_glosses_linguistic_examples.pdf
|
||||||
|
#codeblock(
|
||||||
|
"#example(
|
||||||
|
(
|
||||||
|
source: ([Ich],[arbeite],[ein],[Jahr],[um],[das],[Geld], [zu],[verdienen,],[das], [dein],[Bruder], [an],[einem],[Wochenende],[ausgibt.]),
|
||||||
|
source-style: text.with(weight: \"bold\"),
|
||||||
|
morphemes: ([I], [work],[ one], [year],[to],[the],[money],[to],[earn,], [that],[your],[brother],[on],[one], [weekend], [spends.]),
|
||||||
|
translation: [\"I work one year to earn the money that your brother spends in one weekend\"]
|
||||||
|
)
|
||||||
|
)", addl-bindings: (poss: poss, prog: prog, sg: sg, sbj: sbj))
|
||||||
|
|
||||||
|
== Additional lines <additional-lines>
|
||||||
|
|
||||||
|
To add more than three glossing lines, there is an additional parameter
|
||||||
|
`additional-lines` that can take a list of arbitrarily many more glossing
|
||||||
|
lines, which will appear below those specified in the aforementioned
|
||||||
|
parameters:
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"#example(
|
||||||
|
(
|
||||||
|
header: [Hunzib (van den Berg 1995:46)],
|
||||||
|
source: ([ождиг],[хо#super[н]хе],[мукъер]),
|
||||||
|
transliteration: ([oʒdig],[χõχe],[muqʼer]),
|
||||||
|
morphemes: ([ož-di-g],[xõxe],[m-uq'e-r]),
|
||||||
|
additional-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.\"]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
")
|
||||||
|
|
||||||
|
== Sub-examples
|
||||||
|
|
||||||
|
Sub-examples can be achieved by adding more dictionaries of glossing fields, separated by commas.
|
||||||
|
A global `header` field for the set can be added.
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"#example(
|
||||||
|
header: [Coptic; transliterated and glossed based on _Coptic in 20 lessons_ (2007) by Layton Bently (§~28)],
|
||||||
|
(
|
||||||
|
header: [Indefinite articles],
|
||||||
|
source: ([hen-maein], [mn-hen-špêre]),
|
||||||
|
morphemes: ([#indf.#pl\-sign], [with-#indf.#pl\-wonder]),
|
||||||
|
translation: [signs and wonders]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
header: [Definite articles],
|
||||||
|
source: ([m-maein], [mn-ne-špêre]),
|
||||||
|
morphemes: ([#def.#pl\-sign], [with-#def.#pl\-wonder]),
|
||||||
|
translation: [the signs and the wonders]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
header: [Definite pronouns],
|
||||||
|
source: ([nei-maein], [mn-nei-špêre]),
|
||||||
|
morphemes: ([#dem.#pl\-sign], [with-#dem.#pl\-wonder]),
|
||||||
|
translation: [these signs and these wonders]
|
||||||
|
),
|
||||||
|
)
|
||||||
|
", addl-bindings: (indf: indf, pl: pl, sg: sg, def: def, dem: dem))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO add a custom numbering system that can handle example 18a-c of Kartvelian Morphosyntax and Number Agreement
|
||||||
|
== Numbering Glosses
|
||||||
|
|
||||||
|
The `example()` function takes a boolean parameter `numbering` which will add an incrementing
|
||||||
|
count to each gloss. A function `numbered-example` is exported for convenience; this is
|
||||||
|
defined as simply `#let numbered-example = example.with(numbering: true)`, and is called with the
|
||||||
|
same arguments as `example()`:
|
||||||
|
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"#example(
|
||||||
|
(
|
||||||
|
source: ([გვ-ფრცქვნ-ი],),
|
||||||
|
transliteration: ([gv-prtskvn-i],),
|
||||||
|
morphemes: ([1#pl.#obj\-peel-#fmnt],),
|
||||||
|
translation: \"You peeled us\",
|
||||||
|
),
|
||||||
|
numbering: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
#numbered-example(
|
||||||
|
(
|
||||||
|
source: ([მ-ფრცქვნ-ი],),
|
||||||
|
transliteration: ([m-prtskvn-i],),
|
||||||
|
morphemes: ([1#sg.#obj\-peel-#fmnt],),
|
||||||
|
translation: \"You peeled me\",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
", addl-bindings: (pl: pl, obj: obj, sg: sg, fmnt: fmnt))
|
||||||
|
|
||||||
|
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 `example-count`. This
|
||||||
|
variable can be imported from the `leipzig-gloss` package and manipulated using the
|
||||||
|
standard Typst counter functions to control gloss numbering:
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"#example-count.update(20)
|
||||||
|
|
||||||
|
#numbered-example(
|
||||||
|
(
|
||||||
|
header: [from _Standard Basque: A Progressive Grammar_ by Rudolf de Rijk, quoting P. Charriton],
|
||||||
|
source: ([Bada beti guregan zorion handi baten nahia.],),
|
||||||
|
translation: [There always is in us a will for a great happiness.],
|
||||||
|
)
|
||||||
|
)", addl-bindings: (example-count: example-count))
|
||||||
|
|
||||||
|
References to individual examples can be achieved using the `label` argument and the referencing mechanism of Typst:
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"See @sorcerers:
|
||||||
|
|
||||||
|
#numbered-example(
|
||||||
|
(
|
||||||
|
header: [Middle Welsh; modified from _Grammatical number in Welsh_ (1999) by Silva Nurmio (§~2.1.1)],
|
||||||
|
source: ([ac], [ny], [allvs], [y], [dewinyon], [atteb], [idav]),
|
||||||
|
morphemes: ([and], [#neg], [be_able.#smallcaps[pret].3#sg], [#smallcaps[def]], [sorcerer.#pl], [answer.#smallcaps[inf]], [to.3#sg.#smallcaps[m]]),
|
||||||
|
translation: [and the sorcerers could not answer him],
|
||||||
|
),
|
||||||
|
label: \"sorcerers\",
|
||||||
|
label-supplement: [Example]
|
||||||
|
)
|
||||||
|
|
||||||
|
As we have seen in @sorcerers, […].", addl-bindings: (neg: neg, sg: sg, pl: pl))
|
||||||
|
|
||||||
|
Labelling uses the Typst #link("https://typst.app/docs/reference/model/figure/")[figure] document element. The `label-supplement`
|
||||||
|
parameter fills in the `suppliment` parameter of a `figure`, which is `[example]` by default.
|
||||||
|
Note that `label` and `label-supplement` are top-level arguments of `example()` and `numbered-example()`, not of the interlinear glosses surrounded by `(` and `)`.
|
||||||
|
|
||||||
|
Labelling of sub-examples is possible as well, using the same `label` and `label-supplement` fields but within the parentheses surrounding the sub-example in question.
|
||||||
|
|
||||||
|
#codeblock(
|
||||||
|
"#numbered-example(
|
||||||
|
header: [Hausa; from _Toward a functional typology of adpositions_ (2022) by Zygmunt Frajzyngier (§~3.2)],
|
||||||
|
label: \"hausa\",
|
||||||
|
(
|
||||||
|
source: ([àkwai], [mutā̀nè], [dà], [yawā̀], [a], [kanṑ]),
|
||||||
|
morphemes: ([exist], [People], [#smallcaps[assc]], [many], [#pred], [Kano]),
|
||||||
|
translation: [There are a lot of people in Kano.],
|
||||||
|
label: \"people\"
|
||||||
|
),
|
||||||
|
(
|
||||||
|
source: ([àkwai], [makar̃antā], [a], [nan], [gàrin]),
|
||||||
|
morphemes: ([exist], [school], [#pred], [#dem], [town]),
|
||||||
|
translation: [There is a school in this town.],
|
||||||
|
label: \"school\",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
In @hausa there are two sub-examples: @people deals with people and @school with a school.
|
||||||
|
", addl-bindings: (pred: pred, dem: dem))
|
||||||
|
|
||||||
= Standard Abbreviations
|
= Standard Abbreviations
|
||||||
|
|
||||||
@ -242,11 +327,13 @@ accessed either with Typst field access notation or by importing them from
|
|||||||
#codeblock(
|
#codeblock(
|
||||||
"#import abbreviations: obl, sg, prf
|
"#import abbreviations: obl, sg, prf
|
||||||
|
|
||||||
#gloss(
|
#example(
|
||||||
|
(
|
||||||
header: [(from _Why Caucasian Languages?_, by Bernard Comrie, in _Endangered Languages of the Caucasus and Beyond_)],
|
header: [(from _Why Caucasian Languages?_, by Bernard Comrie, in _Endangered Languages of the Caucasus and Beyond_)],
|
||||||
source: ([\[qálɐ-m], [∅-kw’-á\]], [ɬ’ə́-r]),
|
source: ([\[qálɐ-m], [∅-kw’-á\]], [ɬ’ə́-r]),
|
||||||
morphemes: ([city-#obl], [3#sg\-go-#prf], [man-#abbreviations.abs]),
|
morphemes: ([city-#obl], [3#sg\-go-#prf], [man-#abbreviations.abs]),
|
||||||
translation: \"The man who went to the city.\"
|
translation: \"The man who went to the city.\"
|
||||||
|
)
|
||||||
)", addl-bindings: (abbreviations: abbreviations), unevaled-first-line: "#import \"leipzig-gloss.typ\": abbreviations")
|
)", addl-bindings: (abbreviations: abbreviations), unevaled-first-line: "#import \"leipzig-gloss.typ\": abbreviations")
|
||||||
|
|
||||||
|
|
||||||
@ -270,11 +357,13 @@ Custom abbreviations may be defined using the `abbreviations.emit-abbreviation`
|
|||||||
|
|
||||||
#let ts = emit-abbreviation(\"TS\")
|
#let ts = emit-abbreviation(\"TS\")
|
||||||
|
|
||||||
#gloss(
|
#example(
|
||||||
|
(
|
||||||
header: [(from _Georgian: A Structural Reference Grammar_, by George Hewitt)],
|
header: [(from _Georgian: A Structural Reference Grammar_, by George Hewitt)],
|
||||||
source: ([g-nax-av-en],),
|
source: ([g-nax-av-en],),
|
||||||
morphemes: ([you#sub[2]-see(#fut)#sub[4]-#ts#sub[7]-they#sub[11]],),
|
morphemes: ([you#sub[2]-see(#fut)#sub[4]-#ts#sub[7]-they#sub[11]],),
|
||||||
translation: \"they will see you\",
|
translation: \"they will see you\",
|
||||||
|
)
|
||||||
)", addl-bindings: (abbreviations: abbreviations), unevaled-first-line: "#import \"leipzig-gloss.typ\": abbreviations")
|
)", addl-bindings: (abbreviations: abbreviations), unevaled-first-line: "#import \"leipzig-gloss.typ\": abbreviations")
|
||||||
|
|
||||||
== Building used-abbreviations pages
|
== Building used-abbreviations pages
|
||||||
@ -290,103 +379,127 @@ These are the first twelve example glosses given in #link("https://www.eva.mpg.d
|
|||||||
along with the Typst markup needed to generate them:
|
along with the Typst markup needed to generate them:
|
||||||
|
|
||||||
#{
|
#{
|
||||||
gloss-count.update(0)
|
example-count.update(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Indonesian (Sneddon 1996:237)],
|
header: [Indonesian (Sneddon 1996:237)],
|
||||||
source: ([Mereka], [di], [Jakarta], [sekarang.]),
|
source: ([Mereka], [di], [Jakarta], [sekarang.]),
|
||||||
morphemes: ([they], [in], [Jakarta], [now]),
|
morphemes: ([they], [in], [Jakarta], [now]),
|
||||||
translation: \"They are in Jakarta now\",
|
translation: \"They are in Jakarta now\",
|
||||||
|
)
|
||||||
)")
|
)")
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Lezgian (Haspelmath 1993:207)],
|
header: [Lezgian (Haspelmath 1993:207)],
|
||||||
source: ([Gila], [abur-u-n], [ferma], [hamišaluǧ], [güǧüna], [amuq’-da-č.]),
|
source: ([Gila], [abur-u-n], [ferma], [hamišaluǧ], [güǧüna], [amuq’-da-č.]),
|
||||||
morphemes: ([now], [they-#obl\-#gen], [farm], [forever], [behind], [stay-#fut\-#neg]),
|
morphemes: ([now], [they-#obl\-#gen], [farm], [forever], [behind], [stay-#fut\-#neg]),
|
||||||
translation: \"Now their farm will not stay behind forever.\",
|
translation: \"Now their farm will not stay behind forever.\",
|
||||||
|
)
|
||||||
)", addl-bindings: (fut: fut, neg: neg, obl: obl, gen:gen))
|
)", addl-bindings: (fut: fut, neg: neg, obl: obl, gen:gen))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [West Greenlandic (Fortescue 1984:127)],
|
header: [West Greenlandic (Fortescue 1984:127)],
|
||||||
source: ([palasi=lu], [niuirtur=lu]),
|
source: ([palasi=lu], [niuirtur=lu]),
|
||||||
morphemes: ([priest=and], [shopkeeper=and]),
|
morphemes: ([priest=and], [shopkeeper=and]),
|
||||||
translation: \"both the priest and the shopkeeper\",
|
translation: \"both the priest and the shopkeeper\",
|
||||||
|
)
|
||||||
)")
|
)")
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Hakha Lai],
|
header: [Hakha Lai],
|
||||||
source: ([a-nii -láay],),
|
source: ([a-nii -láay],),
|
||||||
morphemes: ([3#sg\-laugh-#fut],),
|
morphemes: ([3#sg\-laugh-#fut],),
|
||||||
translation: [s/he will laugh],
|
translation: [s/he will laugh],
|
||||||
|
)
|
||||||
)", addl-bindings: (sg: sg, fut: fut))
|
)", addl-bindings: (sg: sg, fut: fut))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Russian],
|
header: [Russian],
|
||||||
source: ([My], [s], [Marko], [poexa-l-i], [avtobus-om], [v], [Peredelkino]),
|
source: ([My], [s], [Marko], [poexa-l-i], [avtobus-om], [v], [Peredelkino]),
|
||||||
morphemes: ([1#pl], [#com], [Marko], [go-#pst\-#pl], [bus-#ins], [#all], [Peredelkino]),
|
morphemes: ([1#pl], [#com], [Marko], [go-#pst\-#pl], [bus-#ins], [#all], [Peredelkino]),
|
||||||
additional-lines: (([we], [with], [Marko], [go-#pst\-#pl], [bus-by], [to], [Peredelkino]),),
|
additional-lines: (([we], [with], [Marko], [go-#pst\-#pl], [bus-by], [to], [Peredelkino]),),
|
||||||
translation: \"Marko and I went to Perdelkino by bus\",
|
translation: \"Marko and I went to Perdelkino by bus\",
|
||||||
|
)
|
||||||
)", addl-bindings: (com: com, pl: pl, ins: ins, all: all, pst:pst))
|
)", addl-bindings: (com: com, pl: pl, ins: ins, all: all, pst:pst))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Turkish],
|
header: [Turkish],
|
||||||
source: ([çık-mak],),
|
source: ([çık-mak],),
|
||||||
morphemes: ([come.out-#inf],),
|
morphemes: ([come.out-#inf],),
|
||||||
translation: \"to come out\",
|
translation: \"to come out\",
|
||||||
|
)
|
||||||
)", addl-bindings: (inf: inf))
|
)", addl-bindings: (inf: inf))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Latin],
|
header: [Latin],
|
||||||
source: ([insul-arum],),
|
source: ([insul-arum],),
|
||||||
morphemes: ([island-#gen\-#pl],),
|
morphemes: ([island-#gen\-#pl],),
|
||||||
translation: \"of the islands\",
|
translation: \"of the islands\",
|
||||||
|
)
|
||||||
)", addl-bindings: (gen:gen, pl: pl))
|
)", addl-bindings: (gen:gen, pl: pl))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [French],
|
header: [French],
|
||||||
source: ([aux], [chevaux]),
|
source: ([aux], [chevaux]),
|
||||||
morphemes: ([to-#art\-#pl],[horse.#pl]),
|
morphemes: ([to-#art\-#pl],[horse.#pl]),
|
||||||
translation: \"to the horses\",
|
translation: \"to the horses\",
|
||||||
|
)
|
||||||
)",addl-bindings: (art:art, pl:pl))
|
)",addl-bindings: (art:art, pl:pl))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [German],
|
header: [German],
|
||||||
source: ([unser-n], [Väter-n]),
|
source: ([unser-n], [Väter-n]),
|
||||||
morphemes: ([our-#dat\-#pl],[father.#pl\-#dat.#pl]),
|
morphemes: ([our-#dat\-#pl],[father.#pl\-#dat.#pl]),
|
||||||
translation: \"to our fathers\",
|
translation: \"to our fathers\",
|
||||||
|
)
|
||||||
)", addl-bindings: (dat:dat, pl:pl))
|
)", addl-bindings: (dat:dat, pl:pl))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Hittite (Lehmann 1982:211)],
|
header: [Hittite (Lehmann 1982:211)],
|
||||||
source: ([n=an], [apedani], [mehuni],[essandu.]),
|
source: ([n=an], [apedani], [mehuni],[essandu.]),
|
||||||
morphemes: ([#smallcaps[conn]=him], [that.#dat.#sg], [time.#dat.#sg], [eat.they.shall]),
|
morphemes: ([#smallcaps[conn]=him], [that.#dat.#sg], [time.#dat.#sg], [eat.they.shall]),
|
||||||
translation: \"They shall celebrate him on that date\",
|
translation: \"They shall celebrate him on that date\",
|
||||||
|
)
|
||||||
)", addl-bindings: (pl:pl, sg:sg, dat:dat))
|
)", addl-bindings: (pl:pl, sg:sg, dat:dat))
|
||||||
|
|
||||||
#codeblock(
|
#codeblock(
|
||||||
"#numbered-gloss(
|
"#numbered-example(
|
||||||
|
(
|
||||||
header: [Jaminjung (Schultze-Berndt 2000:92)],
|
header: [Jaminjung (Schultze-Berndt 2000:92)],
|
||||||
source: ([nanggayan], [guny-bi-yarluga?]),
|
source: ([nanggayan], [guny-bi-yarluga?]),
|
||||||
morphemes: ([who], [2#du.#A.3#sg.#P\-#fut\-poke]),
|
morphemes: ([who], [2#du.#A.3#sg.#P\-#fut\-poke]),
|
||||||
translation: \"Who do you two want to spear?\",
|
translation: \"Who do you two want to spear?\",
|
||||||
|
)
|
||||||
)", addl-bindings: (du:du, sg:sg, fut:fut, A:A, P:P))
|
)", addl-bindings: (du:du, sg:sg, fut:fut, A:A, P:P))
|
||||||
|
|
||||||
|
|
||||||
#codeblock("
|
#codeblock("
|
||||||
#numbered-gloss(
|
#numbered-example(
|
||||||
|
(
|
||||||
header: [Turkish (cf. 6)],
|
header: [Turkish (cf. 6)],
|
||||||
source: ([çık-mak],),
|
source: ([çık-mak],),
|
||||||
morphemes: ([come_out-#inf],),
|
morphemes: ([come_out-#inf],),
|
||||||
translation: ['to come out'],
|
translation: ['to come out'],
|
||||||
|
)
|
||||||
)", addl-bindings: (inf: inf))
|
)", addl-bindings: (inf: inf))
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#import "abbreviations.typ"
|
#import "abbreviations.typ"
|
||||||
|
|
||||||
#let gloss-count = counter("gloss_count")
|
// ╭─────────────────────╮
|
||||||
|
// │ Interlinear glosses │
|
||||||
|
// ╰─────────────────────╯
|
||||||
|
|
||||||
#let build-gloss(item-spacing, formatters, gloss-line-lists) = {
|
#let build-gloss(item-spacing, 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")
|
||||||
@ -13,23 +15,23 @@
|
|||||||
|
|
||||||
assert(formatters.len() == gloss-line-lists.len(), message: "The number of formatters and the number of gloss line lists should be equal")
|
assert(formatters.len() == gloss-line-lists.len(), message: "The number of formatters and the number of gloss line lists should be equal")
|
||||||
|
|
||||||
let make_item_box(..args) = {
|
let make-item-box(..args) = {
|
||||||
box(stack(dir: ttb, spacing: 0.5em, ..args))
|
box(stack(dir: ttb, spacing: 0.5em, ..args))
|
||||||
}
|
}
|
||||||
|
|
||||||
for item_index in range(0, len) {
|
for item-index in range(0, len) {
|
||||||
let args = ()
|
let args = ()
|
||||||
for (line_idx, formatter) in formatters.enumerate() {
|
for (line-idx, formatter) in formatters.enumerate() {
|
||||||
let formatter_fn = if formatter == none {
|
let formatter-fn = if formatter == none {
|
||||||
(x) => x
|
(x) => x
|
||||||
} else {
|
} else {
|
||||||
formatter
|
formatter
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = gloss-line-lists.at(line_idx).at(item_index)
|
let item = gloss-line-lists.at(line-idx).at(item-index)
|
||||||
args.push(formatter_fn(item))
|
args.push(formatter-fn(item))
|
||||||
}
|
}
|
||||||
make_item_box(..args)
|
make-item-box(..args)
|
||||||
h(item-spacing)
|
h(item-spacing)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -39,6 +41,7 @@
|
|||||||
// to replace this workaround with `std.label`
|
// to replace this workaround with `std.label`
|
||||||
#let cmdlabel = label
|
#let cmdlabel = label
|
||||||
|
|
||||||
|
// Typesets the internal part of the interlinear glosses. This function does not deal with the external matters of numbering and labelling; which are handled by `example()`.
|
||||||
#let gloss(
|
#let gloss(
|
||||||
header: none,
|
header: none,
|
||||||
header-style: none,
|
header-style: none,
|
||||||
@ -51,16 +54,8 @@
|
|||||||
additional-lines: (), //List of list of content
|
additional-lines: (), //List of list of content
|
||||||
translation: none,
|
translation: none,
|
||||||
translation-style: none,
|
translation-style: none,
|
||||||
label: none,
|
|
||||||
label-supplement: [example],
|
|
||||||
|
|
||||||
item-spacing: 1em,
|
item-spacing: 1em,
|
||||||
gloss-padding: 2.0em, //TODO document these
|
|
||||||
left-padding: 0.5em,
|
|
||||||
numbering: false,
|
|
||||||
breakable: false,
|
|
||||||
) = {
|
) = {
|
||||||
|
|
||||||
assert(type(source) == "array", message: "source needs to be an array; perhaps you forgot to type `(` and `)`, or a trailing comma?")
|
assert(type(source) == "array", message: "source needs to be an array; perhaps you forgot to type `(` and `)`, or a trailing comma?")
|
||||||
|
|
||||||
if morphemes != none {
|
if morphemes != none {
|
||||||
@ -72,8 +67,7 @@
|
|||||||
assert(transliteration.len() == source.len(), message: "source and transliteration have different lengths")
|
assert(transliteration.len() == source.len(), message: "source and transliteration have different lengths")
|
||||||
}
|
}
|
||||||
|
|
||||||
let gloss_items = {
|
let gloss-items = {
|
||||||
|
|
||||||
if header != none {
|
if header != none {
|
||||||
if header-style != none {
|
if header-style != none {
|
||||||
header-style(header)
|
header-style(header)
|
||||||
@ -101,7 +95,6 @@
|
|||||||
gloss-line-lists.push(additional)
|
gloss-line-lists.push(additional)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
build-gloss(item-spacing, formatters, gloss-line-lists)
|
build-gloss(item-spacing, formatters, gloss-line-lists)
|
||||||
|
|
||||||
if translation != none {
|
if translation != none {
|
||||||
@ -115,12 +108,60 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if numbering {
|
align(left)[#gloss-items]
|
||||||
gloss-count.step()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let gloss_number = if numbering {
|
|
||||||
[(#context gloss-count.display())]
|
|
||||||
|
// ╭─────────────────────╮
|
||||||
|
// │ Linguistic examples │
|
||||||
|
// ╰─────────────────────╯
|
||||||
|
|
||||||
|
#let example-count = counter("example-count")
|
||||||
|
|
||||||
|
#let example(
|
||||||
|
label: none,
|
||||||
|
label-supplement: [example],
|
||||||
|
gloss-padding: 2.5em, //TODO document these
|
||||||
|
left-padding: 0.5em,
|
||||||
|
numbering: false,
|
||||||
|
breakable: false,
|
||||||
|
..args
|
||||||
|
) = {
|
||||||
|
let add-subexample(subexample, count) = {
|
||||||
|
// Remove parameters which are not used in the `gloss`.
|
||||||
|
// TODO Make this functional, if (or when) it’s possible in Typst: filter out `label` and `label-supplement` when they are passed below.
|
||||||
|
let subexample-internal = subexample
|
||||||
|
if "label" in subexample-internal {
|
||||||
|
let _ = subexample-internal.remove("label")
|
||||||
|
}
|
||||||
|
if "label-supplement" in subexample-internal {
|
||||||
|
let _ = subexample-internal.remove("label-supplement")
|
||||||
|
}
|
||||||
|
par()[
|
||||||
|
#box()[
|
||||||
|
#figure(
|
||||||
|
kind: "subexample",
|
||||||
|
numbering: it => [#example-count.display()#count.display("a")],
|
||||||
|
outlined: false,
|
||||||
|
supplement: it => {if "label-supplement" in subexample {return subexample.label-supplement} else {return "example"}},
|
||||||
|
stack(
|
||||||
|
dir: ltr, //TODO this needs to be more flexible
|
||||||
|
[(#context count.display("a"))],
|
||||||
|
left-padding,
|
||||||
|
gloss(..subexample-internal)
|
||||||
|
)
|
||||||
|
) #if "label" in subexample {cmdlabel(subexample.label)}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
if numbering {
|
||||||
|
example-count.step()
|
||||||
|
}
|
||||||
|
|
||||||
|
let example-number = if numbering {
|
||||||
|
[(#context example-count.display())]
|
||||||
} else {
|
} else {
|
||||||
none
|
none
|
||||||
}
|
}
|
||||||
@ -128,15 +169,32 @@
|
|||||||
style(styles => {
|
style(styles => {
|
||||||
block(breakable: breakable)[
|
block(breakable: breakable)[
|
||||||
#figure(
|
#figure(
|
||||||
kind: "ling-example",
|
kind: "example",
|
||||||
|
numbering: it => [#example-count.display()],
|
||||||
|
outlined: false,
|
||||||
supplement: label-supplement,
|
supplement: label-supplement,
|
||||||
numbering: it => [#gloss-count.display()],
|
|
||||||
stack(
|
stack(
|
||||||
dir: ltr, //TODO this needs to be more flexible
|
dir: ltr, //TODO this needs to be more flexible
|
||||||
left-padding,
|
left-padding,
|
||||||
[#gloss_number],
|
[#example-number],
|
||||||
gloss-padding - left-padding - measure([#gloss_number],styles).width,
|
gloss-padding - left-padding - measure([#example-number],styles).width,
|
||||||
align(left)[#gloss_items],
|
{
|
||||||
|
if args.pos().len() == 1 { // a simple example with no sub-examples
|
||||||
|
gloss(..arguments(..args.pos().at(0)))
|
||||||
|
}
|
||||||
|
else { // containing sub-examples
|
||||||
|
let subexample-count = counter("subexample-count")
|
||||||
|
subexample-count.update(0)
|
||||||
|
set align(left)
|
||||||
|
if "header" in args.named() {
|
||||||
|
par[#args.named().header]
|
||||||
|
}
|
||||||
|
for subexample in args.pos() {
|
||||||
|
subexample-count.step()
|
||||||
|
add-subexample(subexample, subexample-count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
),
|
),
|
||||||
) #if label != none {cmdlabel(label)}
|
) #if label != none {cmdlabel(label)}
|
||||||
]
|
]
|
||||||
@ -144,4 +202,4 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#let numbered-gloss = gloss.with(numbering: true)
|
#let numbered-example = example.with(numbering: true)
|
||||||
|
Loading…
Reference in New Issue
Block a user