typst rewrite part 1
This commit is contained in:
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# dependencies for build.ts and other related nonsense
|
||||
node_modules
|
||||
bun.lock
|
||||
|
||||
|
||||
# VSCode configuration
|
||||
.vscode
|
||||
|
||||
# Generated output
|
||||
public_html
|
||||
9
assets/scripts/fuse.min.js
vendored
Normal file
9
assets/scripts/fuse.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
47
assets/scripts/search.js
Normal file
47
assets/scripts/search.js
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
window.onload = async function (ev) {
|
||||
let data_req = await fetch("/index.json")
|
||||
let data = await data_req.json()
|
||||
let fuse = new Fuse(data, {keys: [
|
||||
"tags",
|
||||
"id",
|
||||
"title",
|
||||
"body"
|
||||
]
|
||||
})
|
||||
async function search(args) {
|
||||
try {
|
||||
let x = fuse.search(args)
|
||||
return x
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
document.getElementById('searchbox').addEventListener("input",
|
||||
async function(e) {
|
||||
let results = document.getElementById('results') // .innerHTML = idx.search(e.target.value))
|
||||
if (e.target.value == "") {
|
||||
results.innerHTML = ""
|
||||
} else {
|
||||
Promise.race([
|
||||
search(e.target.value),
|
||||
new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
resolve(-1)
|
||||
}, 3000);
|
||||
})
|
||||
]).then((r) => {
|
||||
if (r == null) {
|
||||
results.innerHTML = "<ul class='sresult'><li class='sresult'><strong>Search results</strong></li><li class='sresult'>An error occured</li></ul>"
|
||||
} else if (r == -1) {
|
||||
results.innerHTML = "<ul class='sresult'><li class='sresult'><strong>Search results</strong></li><li class='sresult'>Query timed out</li></ul>"
|
||||
} else if (r.length == 0) {
|
||||
results.innerHTML = "<ul class='sresult'><li class='sresult'><strong>Search results</strong></li><li class='sresult'>No result</li></ul>"
|
||||
} else {
|
||||
results.innerHTML = "<ul class='sresult'>" + r.map((it) => "<li class='sresult'>" + "<a href=\"/" + it.item.id + ".html\">" + it.item.title + "</a></li>").reduce((a, b) => a + b) + "</ul>"
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
147
assets/style/common.css
Normal file
147
assets/style/common.css
Normal file
@ -0,0 +1,147 @@
|
||||
@import url(/assets/style/fonts.css);
|
||||
:root {
|
||||
--bg: #282828;
|
||||
--bg-accent: #504945;
|
||||
--fg: #ebdbb2;
|
||||
--fg-disabled: #bdae93;
|
||||
--accent: #fe8019;
|
||||
--note: #b8bb26;
|
||||
--info: #83a598;
|
||||
--warn: #fabd2f;
|
||||
--error: #fb4934;
|
||||
--font-main: Andika, sans-serif;
|
||||
--font-mono: Iosevka, monospace;
|
||||
}
|
||||
* {
|
||||
font-family: var(--font-main);
|
||||
font-feature-settings: "ss13" on;
|
||||
padding: 0pt;
|
||||
margin: 0pt;
|
||||
}
|
||||
body {
|
||||
background-color: var(--bg);
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
background-color: var(--bg-accent);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header h1 a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
header nav {
|
||||
width: 100%;
|
||||
padding: 0pt, 10pt;
|
||||
background-color: var(--bg-accent);
|
||||
justify-items: stretch;
|
||||
justify-content: space-evenly;
|
||||
align-items: stretch;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
nav input {
|
||||
width: 25vw;
|
||||
background-color: var(--bg);
|
||||
margin: 10pt;
|
||||
color: var(--fg);
|
||||
}
|
||||
|
||||
aside, aside * {
|
||||
background-color: var(--bg-accent);
|
||||
}
|
||||
a {
|
||||
display: inline;
|
||||
color: var(--accent)
|
||||
}
|
||||
ul.sresult {
|
||||
width: 50vw;
|
||||
height: 50vw;
|
||||
overflow: scroll;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 25%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0%);
|
||||
background-color: var(--bg-accent);
|
||||
padding: 10pt
|
||||
}
|
||||
li.sresult {
|
||||
list-style: none;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
aside {
|
||||
padding: 10pt;
|
||||
height: min-content;
|
||||
}
|
||||
main {
|
||||
padding: 25pt 10pt;
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
#main-body {display: flex;}
|
||||
main {
|
||||
width: calc(100% - 10em);
|
||||
}
|
||||
aside {
|
||||
margin: 10pt 10pt 10pt 0pt;
|
||||
width: 10em;
|
||||
}
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
main {
|
||||
width: 100% - 20pt
|
||||
}
|
||||
aside { width: 100% - 20pt }
|
||||
}
|
||||
/****** Main body styling ******/
|
||||
main h1 {
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
main li {
|
||||
list-style-position: inside;
|
||||
padding: 0 0 0 10pt;
|
||||
}
|
||||
main table {
|
||||
margin: 1em;
|
||||
}
|
||||
main table, main td, main tr {
|
||||
text-align: center;
|
||||
border-collapse: collapse;
|
||||
border: 2px solid var(--fg);
|
||||
}
|
||||
main td {
|
||||
padding: 0em 1em;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
main .low {
|
||||
color: var(--fg-disabled);
|
||||
font-style: italic;
|
||||
}
|
||||
main .high {
|
||||
color: var(--accent);
|
||||
font-family: inherit;
|
||||
}
|
||||
main em {
|
||||
color: var(--accent)
|
||||
}
|
||||
|
||||
/****** GLOSSES ******/
|
||||
.gloss, .gloss tr, .gloss td {
|
||||
stroke: none;
|
||||
border: none;
|
||||
text-align: left;
|
||||
padding: 0 .25em;
|
||||
}
|
||||
|
||||
/****** SCRIPTS ******/
|
||||
.scr-nahan {
|
||||
font-family: AndikaAmbNaran;
|
||||
}
|
||||
55
assets/style/fonts.css
Normal file
55
assets/style/fonts.css
Normal file
@ -0,0 +1,55 @@
|
||||
/* Andika with the nahan script */
|
||||
@font-face {
|
||||
font-family: AndikaAmbNaran;
|
||||
src: url("../fonts/AndikaAmbNaran.ttf") format("truetype");
|
||||
}
|
||||
|
||||
/* Andika for the rest */
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-Bold.ttf") format("truetype");
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-BoldItalic.ttf") format("truetype");
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-Italic.ttf") format("truetype");
|
||||
font-weight: 400;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-Medium.ttf") format("truetype");
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-MediumItalic.ttf") format("truetype");
|
||||
font-weight: 500;
|
||||
font-style: italic;
|
||||
}
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-Regular.ttf") format("truetype");
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-SemiBold.ttf") format("truetype");
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: Andika;
|
||||
src: url("../fonts/Andika-SemiBoldItalic.ttf") format("truetype");
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
}
|
||||
96
build.ts
Executable file
96
build.ts
Executable file
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env -S bun run
|
||||
import { $ } from "bun";
|
||||
import { readdir } from "node:fs/promises"
|
||||
import { parseArgs } from "util";
|
||||
import { JSDOM } from "jsdom";
|
||||
import { Dirent } from "node:fs";
|
||||
import { mkdir, stat } from "node:fs/promises";
|
||||
|
||||
function out_path(path: string) {
|
||||
}
|
||||
|
||||
type LogLevel = "INFO"|"WARN"|"ERROR"|"FATAL"
|
||||
function log(level: LogLevel, message: any) {
|
||||
const p = Bun.argv[1]?.split("/").slice(-1)[0] ?? "build script";
|
||||
switch (level) {
|
||||
case "INFO": console.log(`\x1b[90m${p}: \x1b[1;42;97m [INFO] \x1b[0m ${message}`); break;
|
||||
case "WARN": console.log(`\x1b[90m${p}: \x1b[1;48;5;208;97m [WARN] \x1b[0m ${message}`); break;
|
||||
case "ERROR": console.log(`\x1b[90m${p}: \x1b[1;41;97m [ERROR] \x1b[0m ${message}`); break;
|
||||
case "FATAL": console.log(`\x1b[90m${p}: \x1b[1;41;97m [FATAL] ${message} \x1b[0m`); process.exit(); break;
|
||||
}
|
||||
}
|
||||
|
||||
async function build_typst_file(file: Dirent) {
|
||||
let path = file.parentPath + "/" + file.name
|
||||
let dir = "public_html" + file.parentPath.slice(3)
|
||||
let slug = path.slice(4, -4)
|
||||
let outfile = `public_html/${slug}.html`
|
||||
log("INFO", `Building ${path}`)
|
||||
await mkdir(dir, {recursive: true})
|
||||
await $`typst c --features html --format html --root . ${path} ${outfile}`
|
||||
log("INFO", `Built ${path}`)
|
||||
}
|
||||
|
||||
|
||||
async function build_all_typst() {
|
||||
let files = await readdir("src", {withFileTypes: true, recursive: true});
|
||||
let promises: Promise<void>[] = [];
|
||||
for (let f of files) {
|
||||
if (f.isFile() && f.name.endsWith(".typ"))
|
||||
promises.push(build_typst_file(f))
|
||||
}
|
||||
await Promise.all(promises)
|
||||
}
|
||||
|
||||
async function copy_assets() {
|
||||
log("INFO", "Updating assets")
|
||||
await $`rm -rf public_html/assets/`
|
||||
await $`cp -r assets/ public_html/`
|
||||
}
|
||||
|
||||
type IndexEntry = { id: string; title: string; body: string; tags: string;}
|
||||
async function collect_data(f:string) : Promise<IndexEntry> {
|
||||
let id = f.slice(12, -5)
|
||||
log("INFO", `collecting metadata for ${id}`)
|
||||
let dom = await JSDOM.fromFile(f)
|
||||
let body = ""
|
||||
let things = dom.window.document.getElementsByTagName("main")
|
||||
for (let thing of things) body += thing.textContent;
|
||||
let title = dom.window.document.getElementById("search-title")?.getAttribute("content") ?? ""
|
||||
let tags = dom.window.document.getElementById("search-tags")?.getAttribute("content") ?? ""
|
||||
return {id, title, body, tags}
|
||||
}
|
||||
async function gen_index() {
|
||||
let files = await readdir("public_html", {withFileTypes: true, recursive: true})
|
||||
|
||||
let promises : Promise<IndexEntry>[] = [];
|
||||
for (let f of files) {
|
||||
if (f.isFile() && f.name.endsWith(".html")) {
|
||||
promises.push(collect_data(f.parentPath + "/" + f.name));
|
||||
}
|
||||
}
|
||||
let data : IndexEntry[] = await Promise.all(promises)
|
||||
await Bun.write("public_html/index.json", JSON.stringify(data), {mode: 0o644, createPath: true})
|
||||
}
|
||||
|
||||
|
||||
const args = parseArgs({
|
||||
args: Bun.argv,
|
||||
options: {
|
||||
"build": {type: "boolean", short: "b"},
|
||||
"assets": {type: "boolean", short: "a"},
|
||||
"index": {
|
||||
short: "i", type: "boolean"
|
||||
}
|
||||
},
|
||||
allowPositionals: true
|
||||
}).values
|
||||
|
||||
if (!args.build && !args.assets && !args.index) {
|
||||
await build_all_typst()
|
||||
await copy_assets()
|
||||
await gen_index()
|
||||
}
|
||||
if (args.build) await build_all_typst();
|
||||
if (args.assets) await copy_assets();
|
||||
if (args.index) await gen_index();
|
||||
14
package.json
Normal file
14
package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "wiki-build-tools",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/jsdom": "^27.0.0",
|
||||
"jsdom": "^27.4.0",
|
||||
"@types/bun": "latest"
|
||||
}
|
||||
}
|
||||
14
src/dict/-ala.typ
Normal file
14
src/dict/-ala.typ
Normal file
@ -0,0 +1,14 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "-ala")
|
||||
%dict %word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/ala", mos-cit(""),"cln")
|
||||
=== Pronunciation <mos-1-pro>
|
||||
#mos-pro[\*aʟa]
|
||||
=== Affix <mos-1-affix>
|
||||
%mos/affix
|
||||
#mos-cit("")
|
||||
1. Noun #low[x] arrow Verb "causing the existence of #low[x]"
|
||||
20
src/dict/ain.typ
Normal file
20
src/dict/ain.typ
Normal file
@ -0,0 +1,20 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ain")
|
||||
%dict %word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/ainy", [#sn[]], "cln") #low[ainy]
|
||||
=== Pronunciation <mos-1-pro>
|
||||
#mos-pro[ɛ̃]
|
||||
=== Pronoun <mos-1-pronoun>
|
||||
%mos/pronoun
|
||||
#mos-cit("")
|
||||
1. Third person inannimate pronoun
|
||||
#mos-pron("")
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. Thing, object
|
||||
#mos-n("")
|
||||
15
src/dict/ainilapil.typ
Normal file
15
src/dict/ainilapil.typ
Normal file
@ -0,0 +1,15 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ainilapil")
|
||||
%dict %word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From #wl("/dict/ain", mos-cit(""), "mos-1-noun") + #wl("/dict/ilapil", mos-cit(""), "mos")
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[ɛ̃neʎapeẅ]
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("") (plural #wl("/dict/ainilapiltee", mos-cit(""), "mos"))
|
||||
1. Noun, substantive
|
||||
#mos-n("", pl: "")
|
||||
13
src/dict/ainilapiltee.typ
Normal file
13
src/dict/ainilapiltee.typ
Normal file
@ -0,0 +1,13 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ainilapiltee")
|
||||
%dict
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[ɛ̃neʎapeẅdi]
|
||||
=== Moun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. plural form of #wl("/dict/ainilapil", mos-cit(""), "mos"))
|
||||
13
src/dict/ainy.typ
Normal file
13
src/dict/ainy.typ
Normal file
@ -0,0 +1,13 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ainy")
|
||||
%dict %word
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
=== Pronounciation <cln-1-p>
|
||||
- /a.inə/
|
||||
=== Noun <cln-1-noun>
|
||||
%cln/noun
|
||||
#sn[] #low[ainy]
|
||||
1. Thing, object
|
||||
8
src/dict/ala.typ
Normal file
8
src/dict/ala.typ
Normal file
@ -0,0 +1,8 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ala")
|
||||
%dict %word
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[ala] [aɫa]
|
||||
13
src/dict/an·oreaiác ila.typ
Normal file
13
src/dict/an·oreaiác ila.typ
Normal file
@ -0,0 +1,13 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "an·oreaiác ila")
|
||||
%word %dict
|
||||
= Mosici <mos>
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/oheaiā", sn[], "cln") #low[oheaiā] and the regular formation for language names
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[ãdoʀeç eʎa]
|
||||
=== Proper noun <mos-1-proper>
|
||||
#mos-cit(" ")
|
||||
1. #reg[Out of Universe] #link("https://www.laghariportals.com/78h")[O’eaiā]
|
||||
#mos-n(" ", pl: false)
|
||||
8
src/dict/cihyty.typ
Normal file
8
src/dict/cihyty.typ
Normal file
@ -0,0 +1,8 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "cihyty")
|
||||
%dict %word
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[cihyty] [kixətə]
|
||||
16
src/dict/cirts.typ
Normal file
16
src/dict/cirts.typ
Normal file
@ -0,0 +1,16 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "cirts")
|
||||
%word %dict
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/cihyty", sn[], "cln") #low[cihyty]
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[ceɐ̯ts]
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. Writing, text
|
||||
2. Document, book
|
||||
#mos-n("")
|
||||
16
src/dict/contse.typ
Normal file
16
src/dict/contse.typ
Normal file
@ -0,0 +1,16 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "contse")
|
||||
%word %dict
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/contysse", sn[], "cln") #low[contysse]
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[qõtsɛ]
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. Novelty, innovation
|
||||
#mos-n("")
|
||||
|
||||
15
src/dict/contseila.typ
Normal file
15
src/dict/contseila.typ
Normal file
@ -0,0 +1,15 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "contseila")
|
||||
%word %dict
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From #wl("/dict/contse", sn[], "mos-1-noun") #low[contse] + #wl("/dict/ila", sn[], "mos-1-verb") #low[ila]
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[qõtsiʎa]
|
||||
=== Verb <mos-1-verb>
|
||||
%mos/verb
|
||||
#mos-cit("")
|
||||
1. To present, to announce
|
||||
#mos-v("")
|
||||
8
src/dict/contysse.typ
Normal file
8
src/dict/contysse.typ
Normal file
@ -0,0 +1,8 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "contysse")
|
||||
%word %dict
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[contysse] [kontəsːə]
|
||||
8
src/dict/effyha.typ
Normal file
8
src/dict/effyha.typ
Normal file
@ -0,0 +1,8 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "effyha")
|
||||
%word %dict
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[effyha] [efːəxa]
|
||||
15
src/dict/entec r. tziets.typ
Normal file
15
src/dict/entec r. tziets.typ
Normal file
@ -0,0 +1,15 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "Entec R. Tzietz")
|
||||
%dict %word
|
||||
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[ɛ̃dɛx aɐ̯ dʑɛdz]
|
||||
=== Proper Noun <mos-1-proper>
|
||||
%mos/proper
|
||||
#mos-cit(" ")
|
||||
1. Enderjed, the man, the myth, the legend
|
||||
#mos-n(" ", pl: false)
|
||||
21
src/dict/i.typ
Normal file
21
src/dict/i.typ
Normal file
@ -0,0 +1,21 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "i")
|
||||
%dict
|
||||
%word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/i", sn[], "cln") #low[i]
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[e]
|
||||
=== Particle <mos-1-part>
|
||||
%mos/particle
|
||||
#mos-cit("")
|
||||
1. and
|
||||
2. also
|
||||
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#mos-cit("") [i]
|
||||
|
||||
28
src/dict/ila.typ
Normal file
28
src/dict/ila.typ
Normal file
@ -0,0 +1,28 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ila")
|
||||
%dict
|
||||
%word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/ila", mos-cit(""), "cln")
|
||||
=== Prononciation <mos-1-pro>
|
||||
#mos-pro[eʎa]
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. Language, especially spoken
|
||||
2. Speech, announcement
|
||||
3. #poet word
|
||||
#mos-n("")
|
||||
=== Verb <mos-1-verb>
|
||||
%mos/verb
|
||||
#mos-cit("")
|
||||
1. #arch to speak, to tell
|
||||
#mos-v("")
|
||||
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#mos-cit("") [iɫa]
|
||||
17
src/dict/ilaala.typ
Normal file
17
src/dict/ilaala.typ
Normal file
@ -0,0 +1,17 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ilaala")
|
||||
%dict
|
||||
%word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From #wl("/dict/ila", sn[], "mos") #low[ila] + #wl("/dict/-ala", sn[], "mos") #low[-ala]
|
||||
=== Pronunciation <mos-1-pro>
|
||||
#mos-pro[eʎɔʟa]
|
||||
=== Verb <mos-1-verb>
|
||||
%mos/verb
|
||||
#mos-cit("")
|
||||
1. To speak
|
||||
#mos-v("")
|
||||
|
||||
16
src/dict/ilamócirts.typ
Normal file
16
src/dict/ilamócirts.typ
Normal file
@ -0,0 +1,16 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ilamócirts")
|
||||
%dict
|
||||
%word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From #wl("/dict/ilamós", sn[], "mos") #low[ilamós] + #wl("/dict/cirts", sn[], "mos") #low[cirts]
|
||||
=== Pronunciation <mos-1-pro>
|
||||
#mos-pro[eʎamuceɐ̯ts]
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. Grammar (book)
|
||||
#mos-n("")
|
||||
16
src/dict/ilamós.typ
Normal file
16
src/dict/ilamós.typ
Normal file
@ -0,0 +1,16 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ilamós")
|
||||
%dict
|
||||
%word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From #wl("/dict/ila", sn[], "mos") #low[ila] + [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/mōssy", sn[], "cln") #low[mōssy] (see also #wl("/dict/mósnier", sn[], "mos") #low[mósnier])
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[eʎamus]
|
||||
=== Noun
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. Grammar, language rules
|
||||
#mos-n("")
|
||||
16
src/dict/ilapil.typ
Normal file
16
src/dict/ilapil.typ
Normal file
@ -0,0 +1,16 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ilapil")
|
||||
%dict
|
||||
%word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/ila", sn[], "cln") #low[ila] #wl("/dict/pilyteny", sn[], "cln") #low[pily(teny)]
|
||||
=== Pronunciation <mos-1-pro>
|
||||
#mos-pro[eʎapeẅ]
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("") (plural #wl("/dict/ilapiltee", sn[], "mos") #low[ilapiltee])
|
||||
1. Word
|
||||
#mos-n("", pl: "")
|
||||
13
src/dict/ilapiltee.typ
Normal file
13
src/dict/ilapiltee.typ
Normal file
@ -0,0 +1,13 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ilapiltee")
|
||||
%dict
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[eʎapeẅdi]
|
||||
=== Moun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("")
|
||||
1. plural form of #wl("/dict/ilapil", mos-cit(""), "mos"))
|
||||
18
src/dict/ipianlei.typ
Normal file
18
src/dict/ipianlei.typ
Normal file
@ -0,0 +1,18 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ipianlei")
|
||||
%dict
|
||||
|
||||
= Mosici <mos>
|
||||
%word %mos
|
||||
|
||||
From the [[/worlds/Asteron/Classical Nyelaf]] phrase #sn[]#wl("/dict/i", sn[], "cln") #low[i] #wl("/dict/piany", sn[], "cln") #low[piany] #wl("/dict/lei", sn[], "cln") #low[lei] #sn[] (and afterwards, two)
|
||||
=== Pronunciation <mos-1-pro>
|
||||
#mos-pro[epjãʎi]
|
||||
=== Noun <mos-1-noun>
|
||||
%mos/noun
|
||||
#mos-cit("") (plural #wl("/dict/ipianalei", mos-cit(""), "mos"))
|
||||
1. Sequence, ordering
|
||||
|
||||
#mos-n("", pl: "")
|
||||
18
src/dict/lei.typ
Normal file
18
src/dict/lei.typ
Normal file
@ -0,0 +1,18 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "lei")
|
||||
%dict
|
||||
%word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/lei", sn[], "cln") #low[lei]
|
||||
=== Pronunciation
|
||||
#mos-pro[ʎi]
|
||||
=== Numeral <mos-1-numeral>
|
||||
%mos/numeral
|
||||
#mos-cit("")
|
||||
1. two
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#mos-cit("") [ɫe.i]
|
||||
15
src/dict/mósnier.typ
Normal file
15
src/dict/mósnier.typ
Normal file
@ -0,0 +1,15 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "mósnier")
|
||||
%dict %word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/mōssy", sn[], "cln") #low[mōssy] + #wl("/dict/niehy", sn[], "cln") #low[niehy]
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[musɲiɐ̯]
|
||||
=== Noun <mos-1-noun>
|
||||
#mos-cit("")
|
||||
1. Convention, custom
|
||||
2. Rule (of a game)
|
||||
#mos-n("")
|
||||
9
src/dict/mōssy.typ
Normal file
9
src/dict/mōssy.typ
Normal file
@ -0,0 +1,9 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "mōssy")
|
||||
%dict
|
||||
%word
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[mōssy] [moːsːə]
|
||||
9
src/dict/niehy.typ
Normal file
9
src/dict/niehy.typ
Normal file
@ -0,0 +1,9 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "niehy")
|
||||
%dict
|
||||
%word
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[niehy] [ni.exə]
|
||||
15
src/dict/o.typ
Normal file
15
src/dict/o.typ
Normal file
@ -0,0 +1,15 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "o")
|
||||
%dict %word
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From onomatopeic origin
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[o]
|
||||
=== Particle <mos-1-particle>
|
||||
#mos-cit("")
|
||||
1. #reg[After nouns] Vocative marker
|
||||
2. #reg[After verbs] Imperative marker
|
||||
|
||||
8
src/dict/ohaioa.typ
Normal file
8
src/dict/ohaioa.typ
Normal file
@ -0,0 +1,8 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ohaioa")
|
||||
%word %dict
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[ohaioa] [oxajo.a]
|
||||
9
src/dict/oheaiā.typ
Normal file
9
src/dict/oheaiā.typ
Normal file
@ -0,0 +1,9 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "oheaiā")
|
||||
%word %dict
|
||||
= Classical Neyelaf
|
||||
%cln
|
||||
#sn[] #low[oheaiā] [oxe.a.i.aː]
|
||||
1. #reg[Out of Universe] #link("https://www.laghariportals.com/78h")[O’eaiā]
|
||||
9
src/dict/oiaō.typ
Normal file
9
src/dict/oiaō.typ
Normal file
@ -0,0 +1,9 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "oiaō")
|
||||
%word %dict
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[oiaō] [o.i.a.oː]
|
||||
|
||||
15
src/dict/óasonela.typ
Normal file
15
src/dict/óasonela.typ
Normal file
@ -0,0 +1,15 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "óasonela")
|
||||
%word %dict
|
||||
= Mosici <mos>
|
||||
%mos
|
||||
From [[/worlds/Asteron/Classical Nyelaf]] #wl("/dict/ōas", sn[], "cln") #low[ōas] + #wl("/dict/sonela", sn[], "cln") #low[sonela]
|
||||
=== Pronunciation <mos-1-p>
|
||||
#mos-pro[wasõnɛʟa]
|
||||
=== Verb <mos-1-verb>
|
||||
%mos/verb
|
||||
#mos-cit("")
|
||||
1. To discover
|
||||
#mos-v("")
|
||||
9
src/dict/īly.typ
Normal file
9
src/dict/īly.typ
Normal file
@ -0,0 +1,9 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "īly")
|
||||
%dict
|
||||
%word
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[īly] [iːɫə]
|
||||
9
src/dict/īny.typ
Normal file
9
src/dict/īny.typ
Normal file
@ -0,0 +1,9 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "īny")
|
||||
%dict
|
||||
%word
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[īny] [iːnə]
|
||||
8
src/dict/ōas.typ
Normal file
8
src/dict/ōas.typ
Normal file
@ -0,0 +1,8 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/dict.typ": *
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#show: conf.with(page-title: "ōas")
|
||||
%word %dict
|
||||
= Classical Nyelaf <cln>
|
||||
%cln
|
||||
#sn[] #low[ōas] [oːas]
|
||||
7
src/index.typ
Normal file
7
src/index.typ
Normal file
@ -0,0 +1,7 @@
|
||||
#import "../templates/base.typ": *
|
||||
#show: conf.with(page-title: sitename, title-override: "Index")
|
||||
|
||||
= Welcome <welcome>
|
||||
foo bar baz
|
||||
== H2
|
||||
=== H3
|
||||
4
src/worlds/Asteron/Classical Nyelaf.typ
Normal file
4
src/worlds/Asteron/Classical Nyelaf.typ
Normal file
@ -0,0 +1,4 @@
|
||||
#import "/templates/base.typ": *
|
||||
#show: conf.with(page-title: "Classical Nyelaf")
|
||||
#tag("lang") #tag("cln")
|
||||
#set heading(numbering: "1.")
|
||||
121
src/worlds/Asteron/Mosici.typ
Normal file
121
src/worlds/Asteron/Mosici.typ
Normal file
@ -0,0 +1,121 @@
|
||||
#import "/templates/base.typ": *
|
||||
#import "/templates/utils/gloss.typ": example, gloss
|
||||
#import "/templates/utils/lang-mos.typ": *
|
||||
#let high = html.span.with(class: "high")
|
||||
#show: conf.with(page-title: "Mosici")
|
||||
%lang %mos
|
||||
#set heading(numbering: "1.")
|
||||
#let gloss-opts = (
|
||||
txt-style: sn,
|
||||
translation-style: html.span.with(class: "low"),
|
||||
)
|
||||
#let g = gloss.with(..gloss-opts)
|
||||
#let ex = example.with(..gloss-opts)
|
||||
= Sound ⁊ Letters <sec-sound-letters>
|
||||
== Phonolgy <sec-phonology>
|
||||
Mosici has the following phonemes
|
||||
#table(
|
||||
columns: 5,
|
||||
[], [*Labial*], [*Coronal*], [*Palatal*], [*Dorsal*],
|
||||
[*Nasal*], [m], [n], [], [],
|
||||
[*Stop*], [p], [t], [], [k],
|
||||
[*Fricative*], [f v], [s z], [ɕ ʑ], [ʀ],
|
||||
[*Approximants*], [w], [], [j], [ʟ],
|
||||
)
|
||||
#table(
|
||||
columns: 3,
|
||||
[], [*Front*], [*Back*],
|
||||
[*Close*], [i y], [u],
|
||||
[*Close-Mid*], [e ø], [o],
|
||||
[*Open-Mid*], [ɛ], [ɔ],
|
||||
[*Open*], table.cell(colspan: 2)[a],
|
||||
)
|
||||
|
||||
All vowels can also all be long,
|
||||
|
||||
There is also the following allophony rules:
|
||||
|
||||
- The dorsal approximant is realised as a [ẅ] off-glide in coda positions.
|
||||
- The dorsal fricative is realised as a [ɐ̯] off-glide in coda positions.
|
||||
- The dorsal fricative is realised as a true fricative [ʁ] in consonant clusters.
|
||||
- /n/ nasalises a preceding vowel.
|
||||
- /n/ itself is not pronounced in coda positions.#footnote[still applies nasalisation] <fn-nasal-even-coda>
|
||||
- Nasalised close vowels are realised as mid-centralised: /ĩ ĩː ỹ ỹː ũ ũː/ [ɪ̃ ɪ̃ː ʏ̃ ʏ̃ː ʊ̃ ʊ̃ː]
|
||||
- The dorsal plosive ⁊ approximant are realised as palatal before /i y e j/ #footnote[or their or their long and/or
|
||||
nasalised variants] <fn-dorsal-assimilation>,
|
||||
- The dorsal plosive ⁊ approximant are realised as uvular before ther /u o w/@fn-dorsal-assimilation
|
||||
- The dorsal plosive ⁊ approximant are realised as palatal after /e i j/@fn-dorsal-assimilation or in the coda of a
|
||||
syllable with /e i/@fn-dorsal-assimilation as the nucleus.
|
||||
- The dorsal plosive ⁊ approximant are realised as velar otherwise
|
||||
- Plosives are realised as voiced next to other phonemically voiced consonants.
|
||||
- Plosives are realised as non-sibilant fricatives of the same place of articulation word finally.
|
||||
|
||||
== Coalsecence <sec-coalescence>
|
||||
|
||||
Mosici doesn't allow consecutive vowels inside of words. To resolve would-be hiatuses, a coalescence process is used.
|
||||
This process is historic for all native words, but it still current to resolve diphthongs in loan words and is necessary
|
||||
to understand to read the written language, as the spelling was fixed before that sound change occurred.
|
||||
|
||||
The process goes thusly (before applying the allophony):
|
||||
|
||||
1. Group <enumitem-coalesce-start> all consecutive vowels by pairs, starting at near the start of the word
|
||||
2. Combine all pairs of vowels according to the table below (the first vowel indexes the row, and the second vowel
|
||||
indexes the column)
|
||||
3. If any vowel is long, the resulting vowel is long;
|
||||
4. Repeat from #context link(query(<enumitem-coalesce-start>).first().location())[step 1] until all hiatus has been
|
||||
resolved.
|
||||
#table(
|
||||
columns: 10,
|
||||
[ ], [*a*], [*ɛ*], [*ɔ*], [*e*], [*ø*], [*o*], [*i*], [*y*], [*u*],
|
||||
[*a*], [ɔ], [a], [ɔ], [ɛ], [ɛ], [ɔ], [e], [ø], [o],
|
||||
[*ɛ*], [ɛ], [i], [ø], [i], [e], [ø], [i], [ø], [ø],
|
||||
[*ɔ*], [ɔ], [ø], [ɔ], [ø], [ø], [o], [ø], [ø], [o],
|
||||
[*e*], [ɛ], [i], [ø], [i], [e], [ø], [i], [ø], [ø],
|
||||
[*ø*], [ø], [e], [ø], [e], [y], [ø], [y], [y], [y],
|
||||
[*o*], [ɔ], [ø], [o], [ø], [ø], [u], [ø], [ø], [u],
|
||||
[*i*], [ja], [jɛ], [jɔ], [je], [jø], [jo], [i], [jy], [ju],
|
||||
[*y*], [ø], [ø], [ø], [ø], [y], [ø], [i], [i], [y],
|
||||
[*u*], [wa], [wɛ], [wɔ], [we], [wø], [wo], [wi], [y], [u],
|
||||
)
|
||||
|
||||
== The Nahan Script <sec-nahan-script>
|
||||
Mosici is written in the [[/worlds/Asteron/Nahan Script]] (also named the Polia(h)r alphabet), which is am alphabet
|
||||
which in Mosici is considered to have the following letters, digraphs and diacritic’d letters. The sole diacritic is
|
||||
called the #sn[] 〈sitrapaóha〉.
|
||||
|
||||
#table(
|
||||
columns: 5,
|
||||
[Letter], [Transliteration], [Value (IPA)], [Name], [Name (IPA)],
|
||||
sn[], [p], [/p/], sn[], [[pe]],
|
||||
sn[], [o], [/o/], sn[], [[us]],
|
||||
sn[], [l], [/ʟ/], sn[], [[ʟɔ̃]],
|
||||
sn[], [i], [/e/], sn[], [[iɐ̯nɛ]],
|
||||
sn[], [a], [/a/], sn[], [[ɔ̃ɸ]],
|
||||
sn[], [h], [/∅/#footnote[Lengthens a preceeding vowel] <fn-script-h>], sn[], [[apfɛ]],
|
||||
sn[],
|
||||
[r],
|
||||
[/ʀ/],
|
||||
sn[ #footnote[Literally "sounded 〈base letter〉"] <fn-script-sounded>],
|
||||
[[fasteɕɛx apfɛ]],
|
||||
|
||||
sn[], [c], [/k/], sn[], [[kaẅ]],
|
||||
sn[], [n], [/n/], sn[], [[nɔẅ]],
|
||||
sn[], [e], [/e/], sn[], [[istaẅ]],
|
||||
sn[], [s], [/s/], sn[], [[ɕpaẅ]],
|
||||
sn[], [z], [/z/], sn[ @fn-script-sounded], [[fasteɕɛx ɕpaẅ]],
|
||||
sn[], [f], [/f/], sn[], [[fasoː]],
|
||||
sn[], [v], [/v/], sn[ @fn-script-sounded], [[fasteɕex fasoː]],
|
||||
sn[], [m], [/m/], sn[], [[miʎɔ]],
|
||||
sn[], [t], [/t/], sn[], [[tɛɟjo]],
|
||||
)
|
||||
|
||||
= Morphology <morphology>
|
||||
#ex(
|
||||
caption: [foo],
|
||||
txt: [ #high[ ] ],
|
||||
translit: ([il], high[vionreapt], high[anap], [cirtan]),
|
||||
phono: ([\[eẅ], high[vjõʀɛpθ], high[ãnaɸ], [ceɐ̯dã\]]),
|
||||
morphemes: (sc[1s.act], high[eat#sc[.gno.pcp.pat]], high(sc[loctmp.gno]), [write] + sc[.gno.2s]),
|
||||
translation: [#high[Whenever] I #high[eat], you write],
|
||||
lbl: "example"
|
||||
)
|
||||
66
templates/base.typ
Normal file
66
templates/base.typ
Normal file
@ -0,0 +1,66 @@
|
||||
#let tag = tagname => [ #metadata(tagname) <tag> ]
|
||||
#let wl(path, txt, frag) = {
|
||||
let fragtext = if frag == none {""} else {"#" + frag}
|
||||
let texttext = if txt == none {
|
||||
path.split("/").at(-1)
|
||||
} else {txt}
|
||||
link(path + ".html" + fragtext, texttext)
|
||||
}
|
||||
#let conf(
|
||||
page-title: "",
|
||||
title-override: none,
|
||||
subtitle: none,
|
||||
doc,
|
||||
) = {
|
||||
let sitename = [Annwan's Wiki]
|
||||
// matches [[path|text!fragments]] with opt texts and fragment
|
||||
let link-re = regex(
|
||||
"\\[\\[([^\\]\\|!]+)(?:\\|([^\\]\\|!]+))?(?:!([^\\]\\|!]+))?\\]\\]"
|
||||
)
|
||||
show figure.where(kind: "gloss"): set figure(supplement: [Example])
|
||||
show figure.where(kind: "gloss"): set figure.caption(position: top)
|
||||
show figure: it => {
|
||||
html.details({
|
||||
html.summary[*#it.caption.supplement #it.caption.counter.display(it.numbering)*: #it.caption.body]
|
||||
it.body
|
||||
})
|
||||
}
|
||||
show regex("%[a-z0-9/]+"): it => tag(it.text.slice(1))
|
||||
show link-re: it => wl(..it.text.match(link-re).captures)
|
||||
set table(stroke: none)
|
||||
html.head({
|
||||
html.link(rel: "stylesheet", href: "/assets/style/common.css")
|
||||
html.meta(charset: "utf-8")
|
||||
html.meta(name: "viewport", content: "width=device-width, initial-scale=1")
|
||||
html.meta(name: "search-title", content: if title-override != none {title-override} else {page-title}, id: "search-title")
|
||||
context html.meta(content: { let t = query(<tag>).map(it => it.value).join(" "); if type(t) != str {""} else {t}}, name: "search-tags", id: "search-tags")
|
||||
|
||||
if title-override != none {
|
||||
html.title(sitename + " — " + title-override)
|
||||
} else {
|
||||
html.title(sitename + " — " + page-title)
|
||||
}
|
||||
html.script(src:"/assets/scripts/fuse.min.js")
|
||||
html.script(src: "/assets/scripts/search.js")
|
||||
})
|
||||
|
||||
html.header({
|
||||
html.h1(html.a(href: "/", sitename))
|
||||
html.nav(html.input(id: "searchbox", type: "text", placeholder: "Search..."))
|
||||
})
|
||||
html.div(id: "results")[]
|
||||
html.div(id: "main-body", {
|
||||
html.main({
|
||||
html.h1(page-title)
|
||||
html.hr()
|
||||
doc
|
||||
|
||||
})
|
||||
html.aside(outline())
|
||||
})
|
||||
}
|
||||
#let sitename = [Annwan's Wiki]
|
||||
#let s(script, body) = {
|
||||
html.span(class: "scr-"+script, body)
|
||||
}
|
||||
#let sc = smallcaps
|
||||
6
templates/utils/dict.typ
Normal file
6
templates/utils/dict.typ
Normal file
@ -0,0 +1,6 @@
|
||||
#let reg = (it) => [(#html.span(style: "font-style: italic", it))]
|
||||
#let poet = reg[poetic]
|
||||
#let arch = reg[archaic]
|
||||
#let coll = reg[colloquial]
|
||||
#let slang = reg[slang]
|
||||
#let low = html.span.with(class: "low")
|
||||
39
templates/utils/gloss.typ
Normal file
39
templates/utils/gloss.typ
Normal file
@ -0,0 +1,39 @@
|
||||
#let gloss(
|
||||
txt: none,
|
||||
translit: none,
|
||||
phono: none,
|
||||
morphemes: none,
|
||||
translation: none,
|
||||
txt-style: it => it,
|
||||
translit-style: it => it,
|
||||
phono-style: it => it,
|
||||
morphemes-style: it => it,
|
||||
translation-style: it => it,
|
||||
|
||||
) = {
|
||||
assert(type(morphemes) == array)
|
||||
assert(translation == none or type(translation) == content)
|
||||
assert(txt == none or type(txt) == content or (type(txt) == array and txt.len() == morphemes.len()))
|
||||
assert(translit == none or (type(translit) == array and translit.len() == morphemes.len()))
|
||||
assert(translit == none or (type(phono) == array and phono.len() == morphemes.len()))
|
||||
html.table(class: "gloss",
|
||||
{
|
||||
if type(txt) == content {
|
||||
html.tr(html.td(colspan: morphemes.len(), txt-style(txt)))
|
||||
} else if type(txt) == array {
|
||||
html.tr(txt.map(txt-style).map(html.td).join())
|
||||
}
|
||||
if translit != none {
|
||||
html.tr(translit.map(translit-style).map(html.td).join())
|
||||
}
|
||||
if phono != none {
|
||||
html.tr(phono.map(phono-style).map(html.td).join())
|
||||
}
|
||||
html.tr(morphemes.map(morphemes-style).map(html.td).join())
|
||||
if translation != none { html.tr(html.td(colspan: morphemes.len(),translation-style(translation))) }
|
||||
}
|
||||
)
|
||||
}
|
||||
#let example(..g, lbl: none, caption: none) = [
|
||||
#figure(kind: "gloss", caption: caption, gloss(..g)) #if lbl != none {label(lbl)}
|
||||
]
|
||||
129
templates/utils/lang-mos.typ
Normal file
129
templates/utils/lang-mos.typ
Normal file
@ -0,0 +1,129 @@
|
||||
#import "/templates/base.typ"
|
||||
#let mos-sec = [
|
||||
= Mosici <mos>
|
||||
#base.tag("word") #base.tag("mos")
|
||||
]
|
||||
#let sn = base.s.with("nahan")
|
||||
#let mos-pro(ipa) = [
|
||||
- #base.wl("/worlds/Asteron/Mosici", [Standard], none) [#ipa]
|
||||
]
|
||||
#let mos-translit(s) = {
|
||||
s .replace("", "a")
|
||||
.replace("", "á")
|
||||
.replace("", "c")
|
||||
.replace("", "e")
|
||||
.replace("", "é")
|
||||
.replace("", "f")
|
||||
.replace("", "h")
|
||||
.replace("", "i")
|
||||
.replace("", "í")
|
||||
.replace("", "l")
|
||||
.replace("", "m")
|
||||
.replace("", "n")
|
||||
.replace("", "o")
|
||||
.replace("", "ó")
|
||||
.replace("", "p")
|
||||
.replace("", "r")
|
||||
.replace("", "s")
|
||||
.replace("", "t")
|
||||
.replace("", "u")
|
||||
.replace("", "v")
|
||||
.replace("", "z")
|
||||
.replace("", ",")
|
||||
.replace("", "·")
|
||||
.replace("", "’")
|
||||
}
|
||||
#let mos-cit(t) = [#sn(t) #html.span(class: "low", mos-translit(t))]
|
||||
#let mos-nstem(w) = {
|
||||
if w.ends-with("") {(w.clusters().slice(0, -2).join(), "")}
|
||||
else if w.ends-with("") {(w.clusters().slice(0, -2).join(), "")}
|
||||
else if w.ends-with("") {(w.clusters().slice(0, -2).join(), "")}
|
||||
else if w.ends-with("") {(w.clusters().slice(0, -2).join(), "")}
|
||||
else if w.ends-with("") {(w.clusters().slice(0, -1).join(), "")}
|
||||
else if w.ends-with("") {(w.clusters().slice(0, -1).join(), "")}
|
||||
else {(w, "")}
|
||||
}
|
||||
#let mos-vstem(w) = w.clusters().slice(0, -1).join()
|
||||
|
||||
#let mos-pluralise(w) = {
|
||||
// find index of last vowel
|
||||
let revw = w.rev()
|
||||
let pos = revw.position(regex("[]"))
|
||||
let v = revw.at(pos)
|
||||
if v == "" {v = ""}
|
||||
if v == "" {v = ""}
|
||||
if v == "" {v = ""}
|
||||
if v == "" {v = ""}
|
||||
revw = revw.slice(0, pos) + v + revw.slice(pos)
|
||||
revw.rev()
|
||||
}
|
||||
|
||||
|
||||
#let mos-n(sg, pl: none) = {
|
||||
let pr = if pl == false {""} else if pl != none {pl} else {mos-pluralise(sg)}
|
||||
let (ps, pv) = mos-nstem(pr)
|
||||
let (ss, sv) = mos-nstem(sg)
|
||||
|
||||
let c(it) = [#base.s("nahan", it) \ #html.span(class: "low", mos-translit(it))]
|
||||
html.details({
|
||||
html.summary[ *Declension for* _#mos-cit(sg)_ #if pl != none and pl != false [*Irr. pl. stem* _#mos-cit(pl)_] else if pl == false [*(Uncountable)*]]
|
||||
table(columns: if pl != false {3} else {2},
|
||||
..if pl != false { ([],
|
||||
base.sc[*sg*], base.sc[*pl*],)} else {()},
|
||||
base.sc[*age*], c(sg), ..if pl != false {(c(pr),)} else {()},
|
||||
base.sc[*pat*], c(ss + ""), ..if pl != false {(c(ps + ""),)} else {()},
|
||||
base.sc[*gen*], c(ss + ""), ..if pl != false {(c(ps + ""),)} else {()},
|
||||
base.sc[*dat*], c(ss + sv + ""), ..if pl != false {(c(ps + pv + ""),)} else {()},
|
||||
base.sc[*abl*], c(ss + ""), ..if pl != false {(c(ps + ""),)} else {()},
|
||||
)
|
||||
})
|
||||
}
|
||||
#let mos-v(w) = {
|
||||
let s = mos-vstem(w)
|
||||
let c(it) = [#base.s("nahan", it) \ #html.span(class: "low", mos-translit(it))]
|
||||
html.details({
|
||||
html.summary[*Conjugation for* _#mos-cit(w)_]
|
||||
table(columns: 5,
|
||||
[], base.sc[*prs*], base.sc[*pst*], base.sc[*fut*], base.sc[*gno*],
|
||||
base.sc[*1s*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*2s*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*3sa*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*3si*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*1pi*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*1pe*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*2p*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*3pa*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*3pi*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*inf*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*pcp.sg*], c(s+""), c(s+""), c(s+""), c(s+""),
|
||||
base.sc[*pcp.pl*], c(s+""), c(s+""), c(s+""), c(s+"")
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#let mos-pron(this) = {
|
||||
let c(k, h: false) = if h and k != this [
|
||||
#base.wl("dict/"+mos-translit(k), base.s("nahan", k), "mos") \ #html.span(class: "low", mos-translit(k))
|
||||
] else [
|
||||
#base.s("nahan", k) \ #html.span(class: "low", mos-translit(k))
|
||||
]
|
||||
|
||||
html.details({
|
||||
html.summary[Mosici Pronouns]
|
||||
table(columns: 6,
|
||||
[], base.sc[*agt*], base.sc[*pat*], base.sc[*gen*], base.sc[*dat*], base.sc[*abl*],
|
||||
base.sc[*1s*], c(h: true, ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*1p*], c( ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*2s*], c(h: true, ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*2p*], c( ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*3sa*], c(h: true, ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*3pa*], c( ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*3si*], c(h: true, ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*3pi*], c( ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*dem.sg*], c(h: true, ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*dem.pl*], c( ""), c(""), c(""), c(""), c(""),
|
||||
base.sc[*q*], c(h: true, ""), c(""), c(""), c(""), c(""),
|
||||
)
|
||||
})
|
||||
|
||||
}
|
||||
186
templates/utils/notes.typ
Normal file
186
templates/utils/notes.typ
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
Keep track of a running note counter, and associated notes.
|
||||
*/
|
||||
|
||||
#let note_state_prefix = "notes-"
|
||||
#let note_default_group = "default"
|
||||
|
||||
#let note_default_display_fn(note) = {
|
||||
h(0pt, weak: true)
|
||||
super([[#note.index]])
|
||||
}
|
||||
|
||||
#let add_note(
|
||||
// The location of the note. This is used to derive
|
||||
// what the note counter should be for this note.
|
||||
loc,
|
||||
// The note itself.
|
||||
text,
|
||||
// The offset which will be added to the 0-based counter index
|
||||
// when the index stored in the state.
|
||||
offset: 1,
|
||||
// the display function that creates the returned content from put.
|
||||
// Put can't return a pure index number because the counter
|
||||
// and state updates need to output content.
|
||||
display: note_default_display_fn,
|
||||
// The state group to track notes in.
|
||||
// A group acts independent (both counter and set of notes)
|
||||
// from other groups.
|
||||
group: note_default_group
|
||||
) = {
|
||||
let s = state(note_state_prefix + group, ())
|
||||
let c = counter(note_state_prefix + group)
|
||||
// find any existing note that hasn't been printed yet,
|
||||
// containing the exact same text:
|
||||
let existing = s.at(loc).filter((n) => n.text == text)
|
||||
// If we found an existing note use that,
|
||||
// otherwise the note is the current location's counter + offset
|
||||
// and the given text (the counter is 0-based, we want 1-based indices)
|
||||
let note = if existing.len() > 0 {
|
||||
existing.first()
|
||||
} else {
|
||||
(text: text, index: c.at(loc).first() + offset, page: loc.page())
|
||||
}
|
||||
|
||||
// If we didn't find an existing index, increment the counter
|
||||
// and add the note to the "notes" state.
|
||||
if existing.len() == 0 {
|
||||
c.step()
|
||||
s.update(notes => notes + (note,))
|
||||
}
|
||||
|
||||
// Output the note marker
|
||||
display(note)
|
||||
}
|
||||
|
||||
// get notes at specific location
|
||||
#let get_notes(loc, group: note_default_group) = {
|
||||
state(note_state_prefix + group, ()).at(loc)
|
||||
}
|
||||
|
||||
// Reset the note group to empty.
|
||||
// Note: The counter does not reset by default.
|
||||
#let reset_notes(group: note_default_group, reset_counter: false) = {
|
||||
if reset_counter {
|
||||
counter(note_state_prefix + group).update(0)
|
||||
}
|
||||
state(note_state_prefix + group, ()).update(())
|
||||
}
|
||||
|
||||
//
|
||||
// Helpers for nicer in-document ergonomics
|
||||
//
|
||||
|
||||
#let render_notes(fn, group: note_default_group, reset: true, reset_counter: false) = {
|
||||
locate(loc => fn(get_notes(loc, group: group)))
|
||||
if reset {
|
||||
reset_notes(group: group, reset_counter: reset_counter)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new note at the current location
|
||||
#let note(note, ..args) = {
|
||||
locate((loc) => add_note(loc, note, ..args))
|
||||
}
|
||||
|
||||
// The quick-start option that outputs something useful by default.
|
||||
// This is a sane-defaults call to `render_notes`.
|
||||
#let notes(
|
||||
size: 8pt,
|
||||
font: "Roboto",
|
||||
line: line(length: 100%, stroke: 1pt + gray),
|
||||
padding: (top: 3mm),
|
||||
alignment: bottom,
|
||||
numberings: "1",
|
||||
group: note_default_group,
|
||||
reset: true,
|
||||
reset_counter: false
|
||||
) = {
|
||||
let render(notes) = {
|
||||
if notes.len() > 0 {
|
||||
set align(alignment)
|
||||
block(breakable: false, pad(..padding, {
|
||||
if line != none { line }
|
||||
set text(size: size, font: font)
|
||||
for note in notes {
|
||||
[/ #text(font: "Roboto Mono")[[#numbering(numberings, note.index)]]: #note.text]
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
render_notes(group: group, reset: reset, reset_counter: reset_counter, render)
|
||||
}
|
||||
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
|
||||
#set page(height: 5cm, width: 15cm)
|
||||
|
||||
= Example
|
||||
|
||||
- Having a flexible note-keeping system is important #note[Citation needed]
|
||||
- It's pretty easy to implement with Typst #note[Fact]
|
||||
- Everyone really likes the name "Typst" #note[Citation needed]
|
||||
|
||||
|
||||
|
||||
// Print notes since last print:
|
||||
#notes()
|
||||
#pagebreak()
|
||||
|
||||
These notes won't be printed on this page, so they accumulate onto next page.
|
||||
|
||||
- Hello World #note[Your first program]
|
||||
- Foo Bar #note[Does not serve beverages]
|
||||
#pagebreak()
|
||||
|
||||
- Orange #note[A Color]
|
||||
- Blue #note[A Color]
|
||||
// Notice that the "Citation needed" gets a new index
|
||||
// because we've re-used it since we printed the initial "Citation needed"
|
||||
- All colors are great #note[Citation needed]
|
||||
#notes()
|
||||
#pagebreak()
|
||||
|
||||
#set page(
|
||||
height: 8cm,
|
||||
footer: notes(padding: (bottom: 5mm)),
|
||||
margin: (rest: 5mm, bottom: 3cm)
|
||||
)
|
||||
|
||||
= Footnotes
|
||||
|
||||
It is of course also possible to place the notes _in_ the page footer.
|
||||
This is the way to implement footnotes.
|
||||
|
||||
- Black#note[Debateably a color]
|
||||
- White#note[Debateably a color]
|
||||
#pagebreak()
|
||||
|
||||
- Orange#note[A Color]
|
||||
- Blue#note[A Color]
|
||||
- Purple#note[Also a color]
|
||||
|
||||
#pagebreak()
|
||||
|
||||
= Note groups
|
||||
|
||||
This page still has footnotes (using the default note group)
|
||||
but we can also name a new group for custom notes.
|
||||
|
||||
#let mynote = note.with(group: "custom")
|
||||
#let mynotes = notes.with(
|
||||
group: "custom",
|
||||
font: "Comic Neue",
|
||||
size: 12pt,
|
||||
numberings: "a.",
|
||||
line: none,
|
||||
alignment: right + top
|
||||
)
|
||||
|
||||
- This is in it's own group#mynote[Custom]
|
||||
- Regular footnote here#note[Regular footnote]
|
||||
- Same custom note#mynote[Custom]
|
||||
|
||||
#mynotes()
|
||||
Reference in New Issue
Block a user