Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions src/lib/assets/play-template.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/css" href="../css/tei.css"?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:lang="ger">
<teiHeader>
<fileDesc>
<titleStmt>
<title type="main">
<!-- generated title -->
</title>
<title type="sub">
<!-- generated subtitle -->
</title>
<author>
<persName type="pseudo">Simplicius</persName>
Expand All @@ -22,13 +19,14 @@
<idno type="pnd">107968169</idno>
</author>
<author>
<persName type="pseudo">Du</persName>
<persName>Du</persName>
</author>
<respStmt>
<resp>Edited by</resp>
<name ref="https://orcid.org/0000-0003-2419-6629" type="person">Frank Fischer</name>
<name ref="https://orcid.org/0000-0002-7334-781X" type="person">Viktor J. Illmer</name>
<name ref="https://orcid.org/0009-0005-9680-3995" type="person">Nele Heindorf</name>
<name ref="https://orcid.org/0000-0002-4337-2467" type="person">Mark Schwindt</name>
</respStmt>
</titleStmt>
<publicationStmt>
Expand All @@ -43,9 +41,8 @@
</publicationStmt>
<sourceDesc>
<bibl type="digitalSource">
<!-- Name of the app -->
<name> »999 und noch etliche [mehr]«: Web app for Georg Nikolaus Bärmann’s Würfelalmanach
from 1829 </name>
<name>»999 und noch etliche [mehr]«: Web app for Georg Nikolaus Bärmann’s Würfelalmanach
from 1829</name>
<idno type="URL"> </idno>
<availability status="free">
<p>In the public domain.</p>
Expand All @@ -60,7 +57,6 @@
</bibl>
<bibl type="edition">
<edition>
<!-- dice sequence goes here -->
<idno type="sequence"/>
</edition>
</bibl>
Expand All @@ -77,10 +73,8 @@
<titlePage>
<docTitle>
<titlePart type="main">
<!-- generated title -->
</titlePart>
<titlePart type="sub">
<!-- generated subtitle -->
</titlePart>
</docTitle>
<epigraph>
Expand All @@ -92,9 +86,7 @@
</epigraph>
</titlePage>
</front>
<pb/>
<body>
<div type="main"/>
</body>
</text>
</TEI>
12 changes: 11 additions & 1 deletion src/lib/components/ShareButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import shareIcon from "$lib/assets/share-icon.svg"
import { locale } from "$lib/stores/locale"
import { fade } from "svelte/transition"
import { downloadTEIDoc } from "$lib/tei"

let { sequence } = $props<{ sequence: number[] }>()

Expand Down Expand Up @@ -57,7 +58,7 @@
>
<input type="text" class="rounded border bg-gray-100 p-1" value={sharingUrl} readonly />
<button
class="w-32 rounded bg-sky-800 p-1 text-white transition hover:bg-sky-700 focus:ring-2 focus:ring-sky-500 focus:ring-offset-2"
class="w-32 cursor-pointer rounded bg-sky-800 p-1 text-white transition hover:bg-sky-700 focus:ring-2 focus:ring-sky-500 focus:ring-offset-2"
onclick={copyUrlToClipboard}
>
{urlCopied
Expand All @@ -69,6 +70,15 @@
: "Copy link"}
</button>
</div>
<!-- Download TEI file button -->
<div class="mt-3 flex justify-center">
<button
class="w-full cursor-pointer rounded bg-sky-800 p-1 text-white transition hover:bg-sky-700 focus:ring-2 focus:ring-sky-500 focus:ring-offset-2"
onclick={() => downloadTEIDoc([...sequence])}
>
{$locale === "de" ? "TEI-Dokument herunterladen" : "Download TEI document"}
</button>
</div>
</div>
{/if}

Expand Down
73 changes: 62 additions & 11 deletions src/lib/tei.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import { page } from "$app/state"
import xmlTemplate from "$lib/assets/play-template.xml?raw"
import { Almanac } from "./almanac"

function removeEmptyNewlinesBeforeFirstScene(segments: DocumentFragment, n: number) {
for (let i = 0; i < n; i++) {
if (segments.firstChild) {
segments.removeChild(segments.firstChild)
}
}
}

function removePBsFromDiv(div: Element) {
Array.from(div.getElementsByTagName("pb")).forEach((pb) => pb.parentNode?.removeChild(pb))
}

function getSegment(almanacDoc: Document, roll: number, pips: number): Element | null {
const segmentId = Almanac.getSegmentId(roll, pips).toString()
const segment = almanacDoc.querySelector(`div[type="segment"][n="${segmentId}"]`)
Expand All @@ -22,15 +35,34 @@ function collectSegments(sequence: number[], almanacDoc: Document): DocumentFrag
if (segment) {
if (sceneNumber != null) {
if (currentSceneDiv) segments.appendChild(currentSceneDiv) // finish previous scene

// newline before new scene
segments.appendChild(document.createTextNode("\n" + " ".repeat(3))) // add line breaks and indentation

currentSceneDiv = document.createElementNS("http://www.tei-c.org/ns/1.0", "div") // start new scene
currentSceneDiv.setAttribute("type", "scene")
currentSceneDiv.setAttribute("n", sceneNumber.toString())
}
// append only the children of the div, not the outer <div type=segment> tag
Array.from(segment.childNodes).forEach((child) => {
removePBsFromDiv(segment) // remove page breaks from segments

if (currentSceneDiv) {
currentSceneDiv.appendChild(document.createTextNode("\n" + " ".repeat(4)))
currentSceneDiv.appendChild(
document.createComment(`<div type="segment" n="${Almanac.getSegmentId(roll, pips)}">`)
)
} else {
segments.appendChild(document.createTextNode("\n"))
segments.appendChild(
document.createComment(`<div type="segment" n="${Almanac.getSegmentId(roll, pips)}">`)
)
}
// // append only the children of the div, not the outer <div type=segment> tag
Array.from(segment.children).forEach((child) => {
if (currentSceneDiv) {
currentSceneDiv.appendChild(document.createTextNode("\n" + " ".repeat(4)))
currentSceneDiv.appendChild(child.cloneNode(true))
} else {
segments.appendChild(document.createTextNode("\n" + " ".repeat(4)))
// if no current scene yet, append directly
segments.appendChild(child.cloneNode(true))
}
Expand Down Expand Up @@ -59,9 +91,32 @@ export async function createTEIDoc(
templateDoc.querySelector('teiHeader titleStmt > title[type="sub"]')!.textContent = subTitle
templateDoc.querySelector('front > titlePage > docTitle > titlePart[type="main"]')!.textContent =
mainTitle

// add segment number comment before titles
const mainTitleEl = templateDoc.querySelector(
'front > titlePage > docTitle > titlePart[type="main"]'
)!
const commentNode = segments.children[0].previousSibling!.previousSibling!
const lineBreakNode = document.createTextNode("\n" + " ".repeat(5))
templateDoc.querySelector("front > titlePage > docTitle")!.insertBefore(commentNode, mainTitleEl)
templateDoc
.querySelector("front > titlePage > docTitle")!
.insertBefore(lineBreakNode, mainTitleEl)

templateDoc.querySelector('front > titlePage > docTitle > titlePart[type="sub"]')!.textContent =
subTitle

segments.removeChild(segments.children[0]) // remove main title
segments.removeChild(segments.children[0]) // remove subtitle

// add cast list and set description to front page (removed automatically)
const front = templateDoc.querySelector("front")
front?.appendChild(document.createTextNode(" ".repeat(3)))
front?.appendChild(segments.children[0].previousSibling!.previousSibling!)
front?.appendChild(document.createTextNode("\n" + " ".repeat(5)))
front?.appendChild(segments.children[0]) // cast list
front?.appendChild(segments.children[0]) // set description

// add url to generated play
templateDoc.querySelector(
'teiHeader sourceDesc > bibl[type="edition"] > edition > idno'
Expand All @@ -70,7 +125,7 @@ export async function createTEIDoc(
// set sequence as edition in source description
templateDoc.querySelector(
'teiHeader sourceDesc > bibl[type="digitalSource"] > idno'
)!.textContent = "https://temporal-communities.github.io/999/" + sequence.join("").toString()
)!.textContent = page.url.href + "#" + sequence.join("")

// add timestamp
const date = new Date()
Expand All @@ -79,16 +134,12 @@ export async function createTEIDoc(
.querySelector("teiHeader revisionDesc > listChange > change")!
.setAttribute("when", timestamp)

// add titles, cast list and set description to front page and remove from segments
const front = templateDoc.querySelector("front")
for (let i = 0; i < 4 && segments.children[i]; i++) {
front?.appendChild(segments.children[i])
segments.removeChild(segments.children[i])
}
removeEmptyNewlinesBeforeFirstScene(segments, 7)

// append segments wrapped in scene divs to template's main section
const mainDiv = templateDoc.querySelector('body > div[type="main"]')
mainDiv?.appendChild(segments)
const body = templateDoc.querySelector("body")
body?.appendChild(document.createTextNode(" ".repeat(1)))
body?.appendChild(segments)

// convert DOM to XML string
const serializer = new XMLSerializer()
Expand Down