diff --git a/package-lock.json b/package-lock.json index 7e47a37..b8e4ec4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,7 +26,7 @@ "prettier": "^3.3.2", "prettier-plugin-svelte": "^3.2.6", "prettier-plugin-tailwindcss": "^0.6.5", - "svelte": "^5.0.0", + "svelte": "^5.20.0", "svelte-check": "^4.0.0", "tailwindcss": "^3.4.9", "typescript": "^5.0.0", @@ -1120,25 +1120,23 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.8.4.tgz", - "integrity": "sha512-oDSBHPokbP2iaQlHiEWAkVLsIugsXve8YtABtlyHBUljA63Wgx0UtV8MSOQOGpRft1M+Cd5rzer+0SFlppQwOg==", + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.17.1.tgz", + "integrity": "sha512-CpoGSLqE2MCmcQwA2CWJvOsZ9vW+p/1H3itrFykdgajUNAEyQPbsaSn7fZb6PLHQwe+07njxje9ss0fjZoCAyw==", "dev": true, - "hasInstallScript": true, "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", "devalue": "^5.1.0", - "esm-env": "^1.0.0", + "esm-env": "^1.2.2", "import-meta-resolve": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", - "sirv": "^3.0.0", - "tiny-glob": "^0.2.9" + "sirv": "^3.0.0" }, "bin": { "svelte-kit": "svelte-kit.js" @@ -1147,9 +1145,9 @@ "node": ">=18.13" }, "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1", + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3" + "vite": "^5.0.3 || ^6.0.0" } }, "node_modules/@sveltejs/vite-plugin-svelte": { @@ -2287,6 +2285,16 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2668,9 +2676,9 @@ } }, "node_modules/esm-env": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.1.4.tgz", - "integrity": "sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.2.2.tgz", + "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", "dev": true, "license": "MIT" }, @@ -2706,14 +2714,13 @@ } }, "node_modules/esrap": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.2.2.tgz", - "integrity": "sha512-F2pSJklxx1BlQIQgooczXCPHmcWpn6EsP5oo73LQfonG9fIlIENQ8vMmfGXeojP9MrkzUNAfyU5vdFlR9shHAw==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.4.4.tgz", + "integrity": "sha512-tDN6xP/r/b3WmdpWm7LybrD252hY52IokcycPnO+WHfhFF0+n5AWtcLLK7VNV6m0uYgVRhGVs8OkZwRyfC7HzQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1" + "@jridgewell/sourcemap-codec": "^1.4.15" } }, "node_modules/esrecurse": { @@ -3017,20 +3024,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true, - "license": "MIT" - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3482,9 +3475,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "funding": [ { "type": "github", @@ -4432,9 +4425,9 @@ } }, "node_modules/svelte": { - "version": "5.2.8", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.2.8.tgz", - "integrity": "sha512-VU7a01XwnFi6wXVkH5QY3FYXRZWrhsWZhaE8AYU6UeYZdslE3TFgQq6+HLrbMjOLkVhdKt74NGHYbhFeErQQ6g==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.20.0.tgz", + "integrity": "sha512-04HJfFLaTwTyEKdPm3vYGdaD/8ZAHcd9SEBufq0FZNIrdzJWdM1usVdm4KIlzzDfM5+aMzio6BBhpXPoPGuMjg==", "dev": true, "license": "MIT", "dependencies": { @@ -4445,8 +4438,9 @@ "acorn-typescript": "^1.4.13", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", - "esm-env": "^1.0.0", - "esrap": "^1.2.2", + "clsx": "^2.1.1", + "esm-env": "^1.2.1", + "esrap": "^1.4.3", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -4753,17 +4747,6 @@ "node": ">=0.8" } }, - "node_modules/tiny-glob": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", - "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4943,9 +4926,9 @@ } }, "node_modules/vite": { - "version": "5.4.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz", - "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 07d715e..0f69199 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "prettier": "^3.3.2", "prettier-plugin-svelte": "^3.2.6", "prettier-plugin-tailwindcss": "^0.6.5", - "svelte": "^5.0.0", + "svelte": "^5.20.0", "svelte-check": "^4.0.0", "tailwindcss": "^3.4.9", "typescript": "^5.0.0", diff --git a/src/app.css b/src/app.css index a31e444..862b6ad 100644 --- a/src/app.css +++ b/src/app.css @@ -1,3 +1,15 @@ @import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities'; + +p { + padding-top: 15px; +} +/* :global(.nowrap p) { + white-space: nowrap; +} */ + +/* Prevent selecting
on copy-paste */ +.copyWithoutLinebreaks br { + user-select: none; +} diff --git a/src/lib/constants/constants.js b/src/lib/constants/constants.js new file mode 100644 index 0000000..58f4cb9 --- /dev/null +++ b/src/lib/constants/constants.js @@ -0,0 +1,11 @@ +export const api = `https://dhbern.github.io/aco-static-api/api`; +export const MARGIN_NOTEBOX = 10; // in px + +export const ID_CONTAINER_SETTINGS = 'containerSettings'; +export const ID_CONTAINER_MAIN = 'scrollContainer'; +export const ID_CONTAINER_DOCHEAD = 'containerDocHead'; +export const ID_CONTAINER_DOCTITLE = 'containerDocTitle'; +export const ID_CONTAINER_TEXT = 'containerText'; +export const ID_CONTAINER_PAGENUMS = 'containerPageNums'; +export const ID_CONTAINER_LINENUMS = 'containerLineNums'; +export const ID_CONTAINER_NOTES = 'containerNotes'; diff --git a/src/lib/data/aco-notes.json b/src/lib/data/aco-notes.json new file mode 100644 index 0000000..5e1f185 --- /dev/null +++ b/src/lib/data/aco-notes.json @@ -0,0 +1,98 @@ +{ + "notesData": { + "CV166": { + "libIII-6": { + "CV166-III-6-1-6-erinnert-wird": { + "document": "CV166", + "doc_unit": "libIII-6", + "line_start": 1, + "line_end": 6, + "text_start": "Erinnert", + "text_end": "wird", + "note_content": "

Vgl. Loofs, Nestoriana S. 354,12-18

" + }, + "CV166-III-6-14-14-ergibt-habe": { + "document": "CV166", + "doc_unit": "libIII-6", + "line_start": "14", + "line_end": "14", + "text_start": "ergibt", + "text_end": "habe", + "note_content": "

Eine solche Union wurde zwar in dieser Formulierung (εἷς ἐξ ἀμφοῖν) in der vorliegenden Schrift bisher nur einmal obenCV166,II,Praef.,68–69, der Sache nach jedoch in der Tat schon häufiger postuliert (z.B. noch kurz zuvor CV166,III,5,18–19). Insgesamt betrachtet greift Kyrill allerdings tatsächlich auch auf die hier genutzte Formulierung des Öfteren zurück (vgl. z.B. CV4,3,15–16, ACO 1,1,1 S. 27,2 [Dok. 23]; CV7,25,29–30, ACO 1,1,1 S. 58,10 [Dok. 39];CV169,51, ACO 1,1,1 S. 129,27).

" + }, + "CV166-III-6-24-24--hypostasen": { + "document": "CV166", + "doc_unit": "libIII-6", + "line_start": "14", + "line_end": "14", + "text_start": "", + "text_end": "Hypostasen", + "note_content": "

In der Handschrift stand hier eigentlich φύσεων. ὑποστάσεων wurde nachträglich darüber gesetzt.

" + }, + "CV166-III-6-33-36-dann-wird": { + "document": "CV166", + "doc_unit": "libIII-6", + "line_start": 33, + "line_end": 36, + "text_start": "Dann", + "text_end": "wird", + "note_content": "

Vgl. oben CV166,III,5,2–4.

" + }, + "CV166-III-6-34-34-fürchtest-recht": { + "document": "CV166", + "doc_unit": "libIII-24", + "line_start": 24, + "line_end": 24, + "text_start": "fürchtest", + "text_end": "Recht", + "note_content": "

Der Text scheint hier eine Lücke aufzuweisen. Zum einen fehlt das bei Kyrillregelmäßig auf die Junktur καὶ μάλα folgende Adverb, zum anderen vermisst man einen Ausdruck,von dem der Infinitiv παρατρέπεσθαι abhängen könnte. Agellio (1607)hat, um zumindest das zweiteDesiderat auszugleichen, ἀναγκαῖον vorgeschlagen. Schwartz schlägt, beide Mängel bedenkend,ὀρθῶς οὐ φάμεν vor. Die Übersetzung versucht, den unvollständigen Satz mit eigenen Ergänzungenin einen unmittelbaren Zusammenhang mit dem Nestoriuszitat, dessen Wortmaterial er enthält, zusetzen (vgl. oben CV166,III,5,2).

" + }, + "CV166-III-6-39-41-dass-gelten": { + "document": "CV166", + "doc_unit": "libIII-6", + "line_start": 39, + "line_end": 41, + "text_start": "dass", + "text_end": "gelten", + "note_content": "

Vgl. oben CV166,II,13,3u. CV166,II,14,6-7.

" + }, + "CV166-III-6-42-42-das-frömmigkeit": { + "document": "CV166", + "doc_unit": "libIII-6", + "line_start": 42, + "line_end": 42, + "text_start": "das", + "text_end": "Frömmigkeit", + "note_content": "

Vgl. 1 Tim 3,16.

" + }, + "CV166-III-latetest": { + "document": "CV166", + "doc_unit": "libIII-6", + "line_start": 0, + "line_end": 0, + "text_start": "foo", + "text_end": "bar", + "note_content": "

Hi there, this is just a test

" + }, + "CV166-IV-pre-start": { + "document": "CV166", + "doc_unit": "libIV-pre", + "line_start": 0, + "line_end": 0, + "text_start": "foo", + "text_end": "bar", + "note_content": "

Hi there,jawef jkaöwfe jkewaölf jkewalöf jkeawölf jkewaölf jakweflö jewakföl awjfkewlaöf jkewalöf jakewlfö jewakföl wajkfeölewaf test

" + }, + "CV166-III-6-deleteme": { + "document": "CV166", + "doc_unit": "libIV-pre", + "line_start": 0, + "line_end": 0, + "text_start": "foo", + "text_end": "bar", + "note_content": "

Hi there,jawef jkaöwfe jkewaölf jkewalöf jkeawölf jkewaölf jakweflö jewakföl awjfkewlaöf jkewalöf jakewlfö jewakföl wajkfeölewaf test

" + } + } + } + } +} diff --git a/src/lib/data/aco-text.json b/src/lib/data/aco-text.json new file mode 100644 index 0000000..b825ca4 --- /dev/null +++ b/src/lib/data/aco-text.json @@ -0,0 +1,127 @@ +{ + "textData": { + "CV166": { + "metaunits": ["head", "title"], + "usemelater": [ + "libI-pre", + "libI-1", + "libI-2", + "libI-3", + "libI-4", + "libI-5", + "libI-6", + "libI-7", + "libI-8", + "libI-9", + "libI-10", + "libII-pre", + "libII-1", + "libII-2", + "libII-3", + "libII-4", + "libII-5", + "libII-6", + "libII-7", + "libII-8", + "libII-9", + "libII-10", + "libII-11", + "libII-12", + "libII-13", + "libII-14", + "libIII-pre", + "libIII-1", + "libIII-2", + "libIII-3", + "libIII-4", + "libI-pre", + "libI-1", + "libI-2", + "libI-3", + "libI-4", + "libI-5", + "libI-6", + "libI-7", + "libI-8", + "libI-9", + "libI-10", + "libII-pre", + "libII-1", + "libII-2", + "libII-3", + "libII-4", + "libII-5", + "libII-6", + "libII-7", + "libII-8", + "libII-9", + "libII-10", + "libII-11", + "libII-12", + "libII-13", + "libII-14", + "libIII-pre", + "libIII-1", + "libIII-2", + "libIII-3", + "libIII-4", + "libIII-5", + "libIII-5" + ], + "units": [ + "libIII-6", + "libIV-pre", + "libIV-1", + "libIV-2", + "libIV-3", + "libIV-4", + "libIV-5", + "libIV-6", + "libIV-7" + ], + "dochead": "Edition: Collectio Vaticana 166, ACO I,1,6 S. 13,4–106,41; ältereEdd.: PG 76, Sp. 9–248; Pusey (1965 [=1868–1877]), Bd. 6 S. 54–239

Verzeichnisnummern: CPG 5217

Verfasser: Kyrill von Alexandria

Datierung: spätestens Mitte 430 Lat.

Übersetzungen:

Inhalt: Kyrill unterzieht die Christologie seines GegnersNestorius einer groß angelegten Kritik. Zu diesem Zweck zitiert er zahlreiche ihm anstößigerscheinende Aussagen, die jener im Vorfeld getätigt hatte, und stellt diesen dann seineeigenen Ansichten gegenüber.

Literatur: Pusey (1881), S. 1–184.

", + "doctitle": "

Kyrills, des überaus heiligen Erzbischofs von Alexandria,

‚Gegen die Schmähungen des Nestorius‘

Fünfbändige Widerlegung oder die fünf Bücher des heiligen Kyrill

", + "libI-pre": "

libI-pre Foo bar bal
Foooooo aweohjk j.

", + "libI-1": "

libI-1 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae


", + "libI-2": "

libI-2 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-3": "

libI-3 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-4": "

libI-4 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-5": "

libI-5 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-6": "

libI-6 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-7": "

libI-7 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-8": "

libI-8 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-9": "

libI-9 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libI-10": "

libI-10 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-pre": "

libII-pre Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-1": "

libII-1 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-2": "

libII-2 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-3": "

libII-3 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-4": "

libII-4 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-5": "

libII-5 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-6": "

libII-6 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-7": "

libII-7 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-8": "

libII-8 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-9": "

libII-9 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-10": "

libII-10 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-11": "

libII-11 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-12": "

libII-12 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-13": "

libII-13 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libII-14": "

libII-14 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIII-pre": "

libIII-pre Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIII-1": "

libIII-1 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIII-2": "

libIII-2 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIII-3": "

libIII-3 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIII-4": "

libIII-4 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIII-5": "

libIII-5 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIII-6": "

libIII-6 Erinnert euch in vollem Umfang auch an das, was immer wieder von mir gesagt
worden ist, der ich im Hinblick auf den Herrscher Christus die zweifachen Naturen
unterscheide – nämlich durch die zweifache Natur, aber die einheitlicheWürde. Die
Autorität der Naturen ist nämlich wegen der Verbindungeine, wobei die Naturen
gänzlich in ihrereigentümlichen Ordnung verbleiben, die Würde jedoch, wie ich zuvor
sagte, zu einer einheitlichen Autorität verbunden wird.
Du bist vermutlich in jeder inscht vn guter Auffassungsgabe, weil dudich dazu
entschlossen hast, der göttlich inspirierten Schrift zufolgen, die einen Herrn Jesus
Christus nennt und nicht separat den aus der Nachkommenschaft Abrahams [Stam-
menden] und den aus Gott, dem Vater,[gezeugten] Logos bestimmt. Daneben ist es
aber auch nötig, Folgendeszu bedenken. Eine Sache ist nämlich die Gottheit, eine
andere aber dieuns entsprechende Menschheit dem Prinzip nach, das den Naturen
innewohnt. Durch einen Zusammenschluss aber, der auf einer wahrhaftenEinung
basiert,[ergibt sich] aus beiden ein Christus, wie ich immer wieder gesagt habe.Wenn
allerdings die Hypostasen, wie du sagst, in zwei aufgeteilt sind undman sie als separat
und für sich existierend betrachtet, wie kommt es[dann] zum Zusammenschluss zu
einerPerson, wenn man nicht eben irgendwie sagt, dass ein Einzelnes einem Einzelnen
zu eigen sei, wie zum Beispiel der dazugehörige Leib wohl als etwasder menschlichen
Seele Eigenes betrachtet wird, obwohl er im Vergleichzu ihr von anderer Art ist? Seele
und Leib sind wohl schließlich nichtdasselbe.
Doch vielleicht wird jemand sagen: ‚Warum wird die heilige undverehrte Trinität in
drei Hypostasen unterschieden, bringt abereine Natur der Gottheit hervor?‘ Weil,
möchte ichsagen, die Identität im Hinblick auf das Wesen, die mit Notwendigkeit
dem Unterschied der Hypostasenfolgt, den Geist der Gläubigen zu einer Natur der
Gottheit hinaufführt. Weil aber im Falle des Immanuel die Gottheit imVergleich mit
der Menschheit etwas anderes ist, wenn wir nicht sagen,dass der Leib auf Grundlage
einer wahren Einung dem Logos zu eigengeworden ist, wie sollte [da] eine Person von
beidenhervorgebracht werden, wenn uns jede der beiden Hypostasen Eigenes mit sich
bringt unter der Annahme, dass sie separiert vorliege? Und wenn dasAngenommene
dem nicht zu eigen geworden ist, der angenommen hat, wirdeine Verbindung, die
einfach auf Grundlage eines Zusammenschlusseszustande kommt, der allein in Würde
und Autorität begründet ist, nicht ausreichen, den einen und alleinigen Christus
hervorzubringen, der in einer Person Gott und zugleich Mensch ist.Dann erst, erst in
diesem Moment<fürchtest> du auch völlig zu Recht>, dich ‚von dem Glauben an ihn
abzuwenden‘, auch wenn er dem Fleisch nach als ‚aus derNachkommenschaft Abra-
hams stammend‘ aufgefasst wird.Wenn du aber, indem du sagst, dass es einen und ei-
nen anderen gebe, und außerdem behauptest, dass man den Glauben demder Nach-
kommenschaft Abrahams entstammenden entgegenbringen müsse,sollst du wissen,
und zwar ganz gewiss,dass du den Vorwurf der Menschenverehrung auf dein eigenes
Hauptausgießt, obwohl du es von dir zurückweist, und das durchaus berechtigt, als
Menschenverehrer zu gelten.Da er aber überhaupt wenig von dem, was zu bedenken
angemessen wäre, bedacht hat, verunglimpft erdas große Geheimnis der Frömmigkeit
auch auf andere Weise und fügt unmittelbar an:
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error
Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque

", + "libIV-pre": "

libIV-pre Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIV-1": "

libIV-1 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIV-2": "

libIV-2 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIV-3": "

libIV-3 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIV-4": "

libIV-4 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIV-5": "

libIV-5 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIV-6": "

libIV-6 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

", + "libIV-7": "

libIV-6 Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque,
totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae

" + } + } +} diff --git a/src/lib/data/content.js b/src/lib/data/content.js new file mode 100644 index 0000000..ea93bfd --- /dev/null +++ b/src/lib/data/content.js @@ -0,0 +1,14 @@ +// Import local JSON files +export { textData } from './aco-text.json'; +export { notesData } from './aco-notes.json'; + +// Get JSON from Web-API +// import { api } from '$lib/constants/constants'; + +// export const { textData } = fetch(`${api}/json/aco-text.json`).then((r) => { +// return r.json(); +// }); + +// export const { notesData } = fetch(`${api}/json/aco-notes.json`).then((r) => { +// return r.json(); +// }); diff --git a/src/lib/functions/floatingApparatus/README.md b/src/lib/functions/floatingApparatus/README.md new file mode 100644 index 0000000..12095bc --- /dev/null +++ b/src/lib/functions/floatingApparatus/README.md @@ -0,0 +1,11 @@ +# Comments on Conventions + +### Measuring Offsets and Overlaps + +- .offsetTop and .style.top are measured relative to the next _positioned_ parent. So make sure that this is the parent column. +- .top is fixed at the reference height in the text while for the offset transform.translateY is used. +- .offsetTop and .transform.translateY return a snapshot of a potentially moving element. Hence, they are unreliable together with css-transitions. As a workaround the offset is also stored in an additional attribute "instantTranslateY" which can be read from at any time. + +# Comments on Maintainance + +- Make sure to sync constants with +page.svelte diff --git a/src/lib/functions/floatingApparatus/constants.js b/src/lib/functions/floatingApparatus/constants.js new file mode 100644 index 0000000..aa82c71 --- /dev/null +++ b/src/lib/functions/floatingApparatus/constants.js @@ -0,0 +1,2 @@ +export const ID_CONTAINER_TEXT = 'containerText'; +export const OFFSET_POPUP = -400; // in pixel diff --git a/src/lib/functions/floatingApparatus/getInstantOffsetTop.js b/src/lib/functions/floatingApparatus/getInstantOffsetTop.js new file mode 100644 index 0000000..fb6f6ad --- /dev/null +++ b/src/lib/functions/floatingApparatus/getInstantOffsetTop.js @@ -0,0 +1,20 @@ +import { getInstantTranslateY } from './getInstantTranslateY'; + +export function getInstantOffsetTop(el, edge) { + if (!el) return null; // safety guard + switch (edge) { + case 'attop': + return el.offsetTop + getInstantTranslateY(el) || 0; + case 'atbottom': + const computedStyles = window.getComputedStyle(el); + return ( + el.offsetTop + + getInstantTranslateY(el) + + el?.offsetHeight + + parseFloat(computedStyles.marginTop) + + parseFloat(computedStyles.marginBottom) || 0 + ); + default: + return null; + } +} diff --git a/src/lib/functions/floatingApparatus/getInstantTranslateY.js b/src/lib/functions/floatingApparatus/getInstantTranslateY.js new file mode 100644 index 0000000..cbe6818 --- /dev/null +++ b/src/lib/functions/floatingApparatus/getInstantTranslateY.js @@ -0,0 +1,3 @@ +export function getInstantTranslateY(el) { + return Number(el?.getAttribute('instantTranslateY')) || 0; +} diff --git a/src/lib/functions/floatingApparatus/getOffsetTop.js b/src/lib/functions/floatingApparatus/getOffsetTop.js new file mode 100644 index 0000000..a56ff3c --- /dev/null +++ b/src/lib/functions/floatingApparatus/getOffsetTop.js @@ -0,0 +1,15 @@ +export function getOffsetTop(el, edge) { + if (!el) return null; // safety guard + switch (edge) { + case 'attop': + return el.offsetTop || 0; + case 'atbottom': + const computedStyles = window.getComputedStyle(el); + return ( + el.offsetTop + + el?.offsetHeight + + parseFloat(computedStyles.marginTop) + + parseFloat(computedStyles.marginBottom) || 0 + ); + } +} diff --git a/src/lib/functions/floatingApparatus/handleMarkClick.js b/src/lib/functions/floatingApparatus/handleMarkClick.js new file mode 100644 index 0000000..d2ba071 --- /dev/null +++ b/src/lib/functions/floatingApparatus/handleMarkClick.js @@ -0,0 +1,34 @@ +import { selectMark } from './selectMark'; +import { unselectMarks } from './unselectMarks'; +import { moveNote } from './moveNote'; +import { showMultiMarkPopup } from './showMultiMarkPopup'; + +export function handleMarkClick(ev, selectedNote, multiMarkPopupIds) { + // no mark clicked + if (!ev.target.classList.contains('mark')) { + multiMarkPopupIds.ids = []; + selectedNote.id = ''; + unselectMarks(); + return; + } + + let ids = []; + try { + //!FIX + ids = JSON.parse(ev.target.dataset.ids); + } catch (error) { + ids = [ev.target.dataset.ids]; + } + + switch (ids.length) { + case 0: + return; + case 1: + selectMark(ids[0]); + moveNote(ids[0]); + selectedNote.id = ids[0]; + break; + default: + showMultiMarkPopup(ids, multiMarkPopupIds, ev.target); + } +} diff --git a/src/lib/functions/floatingApparatus/handleNoteClick.js b/src/lib/functions/floatingApparatus/handleNoteClick.js new file mode 100644 index 0000000..d043ffd --- /dev/null +++ b/src/lib/functions/floatingApparatus/handleNoteClick.js @@ -0,0 +1,7 @@ +import { selectMark } from './selectMark'; +import { moveNote } from './moveNote'; + +export function handleNoteClick(id) { + selectMark(id); + moveNote(id); +} diff --git a/src/lib/functions/floatingApparatus/handlePopupClick.js b/src/lib/functions/floatingApparatus/handlePopupClick.js new file mode 100644 index 0000000..1e9b6d1 --- /dev/null +++ b/src/lib/functions/floatingApparatus/handlePopupClick.js @@ -0,0 +1,9 @@ +import { selectMark } from './selectMark'; +import { moveNote } from './moveNote'; + +export function handlePopupClick(id, selectedNote, multiMarkPopupIds) { + selectMark(id); + moveNote(id); + multiMarkPopupIds.ids = []; + selectedNote.id = id; +} diff --git a/src/lib/functions/floatingApparatus/index.js b/src/lib/functions/floatingApparatus/index.js new file mode 100644 index 0000000..b3180b7 --- /dev/null +++ b/src/lib/functions/floatingApparatus/index.js @@ -0,0 +1,17 @@ +// Helpers for translating notes +export { setTranslateY } from './setTranslateY'; +export { getInstantTranslateY } from './getInstantTranslateY'; +export { getOffsetTop } from './getOffsetTop'; +export { getInstantOffsetTop } from './getInstantOffsetTop'; + +// Place, select, unselect and move notes +export { placeNotes } from './placeNotes'; // original placement (do this onMount) +export { selectMark } from './selectMark'; // +export { moveNote } from './moveNote'; +export { unselectMarks } from './unselectMarks'; + +// Handle interaction with notes, marks and popups +export { handleNoteClick } from './handleNoteClick'; +export { handleMarkClick } from './handleMarkClick'; +export { handlePopupClick } from './handlePopupClick'; +export { showMultiMarkPopup } from './showMultiMarkPopup'; diff --git a/src/lib/functions/floatingApparatus/moveNote.js b/src/lib/functions/floatingApparatus/moveNote.js new file mode 100644 index 0000000..9a582da --- /dev/null +++ b/src/lib/functions/floatingApparatus/moveNote.js @@ -0,0 +1,46 @@ +import { setTranslateY } from './setTranslateY'; +import { getInstantTranslateY } from './getInstantTranslateY'; +import { getInstantOffsetTop } from './getInstantOffsetTop'; +import { ID_CONTAINER_TEXT } from './constants'; + +export function moveNote(id) { + const elNoteRef = document.querySelector(`.note-start[data-id=${id}]`); + const elNoteBox = document.querySelector(`.notebox[data-id=${id}]`); + const elContainerText = document.querySelector(`#${ID_CONTAINER_TEXT}`); + const elContainer = document.querySelector('#scrollContainer'); + + // Move entire column (via marginTop) + // const elContainerNotes = document.querySelector('#containerNotes'); + // elContainerNotes.style.marginTop = `${offset}px`; + + // Move noteboxe to reference position (i.e. reset translateY) + setTranslateY(elNoteBox, 0); + + // Detect Overlap and move other boxes up or down until there is no overlap + let el = elNoteBox; + let elPrev = elNoteBox?.previousElementSibling; + let overlapTop = getInstantOffsetTop(elPrev, 'atbottom') - getInstantOffsetTop(el, 'attop'); + while (overlapTop > 0 && elPrev) { + setTranslateY(elPrev, getInstantTranslateY(elPrev) - overlapTop); // move up + el = elPrev; + elPrev = el.previousElementSibling; + overlapTop = getInstantOffsetTop(elPrev, 'atbottom') - getInstantOffsetTop(el, 'attop'); + } + + el = elNoteBox; + let elNext = elNoteBox?.nextElementSibling; + let overlapBottom = getInstantOffsetTop(el, 'atbottom') - getInstantOffsetTop(elNext, 'attop'); + while (overlapBottom > 0 && elNext) { + setTranslateY(elNext, getInstantTranslateY(elNext) + overlapBottom); // move down + el = elNext; + elNext = el.nextElementSibling; + overlapBottom = getInstantOffsetTop(el, 'atbottom') - getInstantOffsetTop(elNext, 'attop'); + } + + // Scroll to note + elContainer.scrollTo({ + // Important: offsetTop is measured relative to the next *positioned* parent! + top: elContainerText.offsetTop + elNoteRef.offsetTop - window.innerHeight * 0.3, + behavior: 'smooth' + }); +} diff --git a/src/lib/functions/floatingApparatus/placeNotes.js b/src/lib/functions/floatingApparatus/placeNotes.js new file mode 100644 index 0000000..6d5e90a --- /dev/null +++ b/src/lib/functions/floatingApparatus/placeNotes.js @@ -0,0 +1,24 @@ +import { getOffsetTop } from './getOffsetTop'; +import { setTranslateY } from './setTranslateY'; + +export function placeNotes(ids) { + let offsetSum = 0; + ids.forEach((id) => { + const elNoteBox = document.querySelector(`.notebox[data-id=${id}]`); + const elNoteRef = document.querySelector(`.note-start[data-id=${id}]`); + const offsetRef = elNoteRef?.offsetTop; + + // Move to reference height + elNoteBox.style.top = `${offsetRef}px`; + + // Adjust visual height if overlap with previous notebox + const elNoteBoxPrev = elNoteBox?.previousElementSibling; + if (elNoteBoxPrev) { + const overlapTop = getOffsetTop(elNoteBoxPrev, 'atbottom') - offsetRef; // overlap if positive + offsetSum += Math.max(0, overlapTop); + if (overlapTop > 0) { + setTranslateY(elNoteBox, offsetSum); + } + } + }); +} diff --git a/src/lib/functions/floatingApparatus/selectMark.js b/src/lib/functions/floatingApparatus/selectMark.js new file mode 100644 index 0000000..682b40f --- /dev/null +++ b/src/lib/functions/floatingApparatus/selectMark.js @@ -0,0 +1,10 @@ +import { unselectMarks } from './unselectMarks'; + +export function selectMark(id) { + // Remove old highlights + unselectMarks(); + const elSpan = document.querySelectorAll(`span.mark[data-ids*=${id}]`); + elSpan.forEach((el) => { + el.classList.add('highlighted'); + }); +} diff --git a/src/lib/functions/floatingApparatus/setTranslateY.js b/src/lib/functions/floatingApparatus/setTranslateY.js new file mode 100644 index 0000000..4fd5e3f --- /dev/null +++ b/src/lib/functions/floatingApparatus/setTranslateY.js @@ -0,0 +1,5 @@ +export function setTranslateY(el, value) { + if (!el) return; // safety guard + el.style.transform = `translateY(${value}px)`; + el.setAttribute('instantTranslateY', value); +} diff --git a/src/lib/functions/floatingApparatus/showMultiMarkPopup.js b/src/lib/functions/floatingApparatus/showMultiMarkPopup.js new file mode 100644 index 0000000..ae55cf0 --- /dev/null +++ b/src/lib/functions/floatingApparatus/showMultiMarkPopup.js @@ -0,0 +1,21 @@ +import { ID_CONTAINER_TEXT, OFFSET_POPUP } from './constants'; +import { tick } from 'svelte'; + +export function showMultiMarkPopup(ids, multiMarkPopupIds, elMark) { + // Feed ids to state, which will trigger popup-component + multiMarkPopupIds.ids = ids; + + // Make sure that popup exists + tick().then(() => { + const elPopup = document.querySelector('.multimark-popup'); + const elContainer = document.querySelector(`#${ID_CONTAINER_TEXT}`); + const rectMark = elMark.getBoundingClientRect(); + const rectContainer = elContainer.getBoundingClientRect(); + + //! Replace this with propper Skeleton Popover Component + elPopup.style.display = 'none'; + elPopup.style.top = `${rectMark.top - rectContainer.top + OFFSET_POPUP}px`; + elPopup.style.left = `${rectMark.left + window.scrollX}px`; + elPopup.style.display = 'block'; + }); +} diff --git a/src/lib/functions/floatingApparatus/unselectMarks.js b/src/lib/functions/floatingApparatus/unselectMarks.js new file mode 100644 index 0000000..48842cd --- /dev/null +++ b/src/lib/functions/floatingApparatus/unselectMarks.js @@ -0,0 +1,6 @@ +export function unselectMarks() { + const elSpan = document.querySelectorAll(`span.mark`); + elSpan.forEach((el) => { + el.classList.remove('highlighted'); + }); +} diff --git a/src/lib/functions/protoHTMLconversion/extractNoteIds.js b/src/lib/functions/protoHTMLconversion/extractNoteIds.js new file mode 100644 index 0000000..1e0bc78 --- /dev/null +++ b/src/lib/functions/protoHTMLconversion/extractNoteIds.js @@ -0,0 +1,14 @@ +export function extractNoteIds(text) { + let ids = []; + let match; + + const regex = /<\/span>/g; + while ((match = regex.exec(text)) !== null) { + // This is necessary to avoid infinite loops with zero-width matches + if (match.index === regex.lastIndex) { + regex.lastIndex++; + } + ids.push(match[1]); + } + return ids; +} diff --git a/src/lib/functions/protoHTMLconversion/generateLineNumbers.js b/src/lib/functions/protoHTMLconversion/generateLineNumbers.js new file mode 100644 index 0000000..1319810 --- /dev/null +++ b/src/lib/functions/protoHTMLconversion/generateLineNumbers.js @@ -0,0 +1,12 @@ +export function generateLineNumbers(text) { + // Match a-line, p and br tags + const matches = text.match(/(<\/a>)|(<\/?p>)|()/g); + const linesText = matches ? matches.join('') : ''; + + // Insert line-number as text at every 5th line + const numbersText = linesText.replace(/<\/a>/g, (match, lineNumber) => { + return `${!(lineNumber % 5) ? lineNumber : "00 "}`; + }); + + return numbersText; +} diff --git a/src/lib/functions/protoHTMLconversion/generateMainText.js b/src/lib/functions/protoHTMLconversion/generateMainText.js new file mode 100644 index 0000000..e6b7ef8 --- /dev/null +++ b/src/lib/functions/protoHTMLconversion/generateMainText.js @@ -0,0 +1,55 @@ +function insertNoteSpans(text) { + let openIds = []; + let result = ''; + let lastIndex = 0; + + text.replace( + /<\/span>|<\/span>/g, + (match, startId, endId, offset) => { + // Capture text before this match + let precedingText = text.slice(lastIndex, offset); + if (precedingText.trim()) { + let idsAttribute = JSON.stringify(openIds); + if (openIds.length > 0) { + let multiIdsClass = openIds.length > 1 ? 'multiple-ids' : ''; + let myclass = ['mark', multiIdsClass].filter(Boolean).join(' '); + result += `${precedingText}`; + } else { + result += precedingText; // Preserve text without wrapping + } + } + + if (startId) { + // Handle note-start tag + openIds.push(startId); + result += ``; + } else if (endId) { + // Handle note-end tag + result += ``; + openIds = openIds.filter((id) => id !== endId); // Remove closed ID + } + + lastIndex = offset + match.length; + } + ); + + // Append remaining text after last match + let remainingText = text.slice(lastIndex); + if (remainingText.trim()) { + result += remainingText; + } + + return result; +} + +export function generateMainText(text) { + // Remove line numbers + text = text.replace(/]*[line|page]="[^"]*"[^>]*><\/a>/g, ''); + // Insert spans + text = insertNoteSpans(text); + // Transform lib-number + text = text.replace(/<\/a>/g, (match, libNumber) => { + return `Buch ${libNumber}`; + }); + return text.trim(); +} diff --git a/src/lib/functions/protoHTMLconversion/generatePageNumbers.js b/src/lib/functions/protoHTMLconversion/generatePageNumbers.js new file mode 100644 index 0000000..5c01e47 --- /dev/null +++ b/src/lib/functions/protoHTMLconversion/generatePageNumbers.js @@ -0,0 +1,11 @@ +export function generatePageNumbers(text) { + // Match a-page, p and br tags + const matches = text.match(/(<\/a>)|()/g); + const pageText = matches ? matches.join('') : ''; + + // Insert page-number as text and add class + const numbersText = pageText.replace(/<\/a>/g, (match, pageNumber) => { + return `Seite ${pageNumber}`; + }); + return numbersText; +} diff --git a/src/lib/functions/protoHTMLconversion/index.js b/src/lib/functions/protoHTMLconversion/index.js new file mode 100644 index 0000000..c10ee19 --- /dev/null +++ b/src/lib/functions/protoHTMLconversion/index.js @@ -0,0 +1,10 @@ +// Generate html for mainText, lineNumbers and pageNumbers +export { generateMainText } from './generateMainText'; +export { generateLineNumbers } from './generateLineNumbers'; +export { generatePageNumbers } from './generatePageNumbers'; + +// Extract NoteIds +// This will extract all referenced data-ids for a text. +// This is useful if text.json and notes.json don't match or don't follow the same structure. +// However, this could be dropped completely, if the json files match. +export { extractNoteIds } from './extractNoteIds'; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index eb82088..df1b265 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -43,6 +43,6 @@ > -
+
{@render children()}
diff --git a/src/routes/404.html b/src/routes/404.html new file mode 100644 index 0000000..1666057 --- /dev/null +++ b/src/routes/404.html @@ -0,0 +1,14 @@ + + + + + + + %sveltekit.head% + + +

Game over

+

Code %sveltekit.status%

+

%sveltekit.error.message%

+ + diff --git a/src/routes/edition/+layout.svelte b/src/routes/edition/+layout.svelte index e69de29..f6db9eb 100644 --- a/src/routes/edition/+layout.svelte +++ b/src/routes/edition/+layout.svelte @@ -0,0 +1,8 @@ + + + +
+ {@render children()} +
diff --git a/src/routes/edition/[vol]/[doc]/+layout.js b/src/routes/edition/[vol]/[doc]/+layout.js new file mode 100644 index 0000000..8e99524 --- /dev/null +++ b/src/routes/edition/[vol]/[doc]/+layout.js @@ -0,0 +1,18 @@ +import { textData as data } from '$lib/data/content'; + +/** @type {import('./$types').PageLoad} */ +export async function load({ fetch, params }) { + const textData = await data; + + // URL Parameters + const doc = params.doc; + + // Get corresponding data + const dochead = textData?.[doc].dochead; + const doctitle = textData?.[doc].doctitle; + + return { + dochead, + doctitle + }; +} diff --git a/src/routes/edition/[vol]/[doc]/+layout.svelte b/src/routes/edition/[vol]/[doc]/+layout.svelte new file mode 100644 index 0000000..4004b28 --- /dev/null +++ b/src/routes/edition/[vol]/[doc]/+layout.svelte @@ -0,0 +1,50 @@ + + +
+
+ +

Ohne Zeilenumbrüche kopieren

+
+
+ +
+ +
+ {@html dochead} +
+ + +
+ {@html doctitle} +
+ + {@render children()} +
+ + diff --git a/src/routes/edition/[vol]/[doc]/+page.svelte b/src/routes/edition/[vol]/[doc]/+page.svelte deleted file mode 100644 index e69de29..0000000 diff --git a/src/routes/edition/[vol]/[doc]/[page]/+page.svelte b/src/routes/edition/[vol]/[doc]/[page]/+page.svelte deleted file mode 100644 index e69de29..0000000 diff --git a/src/routes/edition/[vol]/[doc]/[unit]/+page.js b/src/routes/edition/[vol]/[doc]/[unit]/+page.js new file mode 100644 index 0000000..6e83f72 --- /dev/null +++ b/src/routes/edition/[vol]/[doc]/[unit]/+page.js @@ -0,0 +1,38 @@ +// import { textData, notesData } from '$lib/data/content'; +import { textData } from '$lib/data/aco-text.json'; +import { notesData } from '$lib/data/aco-notes.json'; + +/** @type {import('./$types').PageLoad} */ +export function load({ fetch, params }) { + // For later + //!! Now this leads to: "Cannot use relative URL (/json/aco-text.json) with global fetch — use `event.fetch` instead: https://svelte.dev/docs/kit/web-standards#fetch-apis" + // const textData = await textData; + // const notesData = await notesData; + + // Alternative for localhost + // const { textData } = await fetch(`/json/aco-text.json`).then((r) => { + // return r.json(); + // }); + // const { notesData } = await fetch(`/json/aco-notes.json`).then((r) => { + // return r.json(); + // }); + + // URL Parameters + const doc = params.doc; + const unit = params.unit; + + // Get corresponding data + const textunit = textData?.[doc]?.[unit] || ''; + const notes = notesData?.[doc]?.[unit] || {}; + + // Workaround until dynamic unit-loading is in place (delete later) + const allunits = textData?.[doc].units.map((unit) => { + return textData?.[doc][unit]; + }); + + return { + textunit, + allunits, + notes + }; +} diff --git a/src/routes/edition/[vol]/[doc]/[unit]/+page.svelte b/src/routes/edition/[vol]/[doc]/[unit]/+page.svelte new file mode 100644 index 0000000..2f17b4b --- /dev/null +++ b/src/routes/edition/[vol]/[doc]/[unit]/+page.svelte @@ -0,0 +1,139 @@ + + + +
+ {#each allunits as unit} + {@html generatePageNumbers(unit)} + {/each} +
+ + +
{ + handleMarkClick(ev, selectedNote, multiMarkPopupIds); + }} + onkeydown={(e) => + e.key === 'Enter' || e.key === ' ' + ? handleMarkClick(ev, selectedNote, multiMarkPopupIds) + : null} + role="button" + tabindex="0" + aria-label="Select/Deselect annotated text" +> + {#each allunits as unit, idx} + + {/each} +
+ + +
+ {#each allunits as unit} + {@html generateLineNumbers(unit)} + {/each} +
+ +
+ {#each allunits as unit} + {@const notes = extractNoteIds(unit).map((id) => ({ + id: id, + content: allNotes[id]?.note_content + }))} + {#each notes as note} + + {/each} + {/each} +
+ + +{#if multiMarkPopupIds.ids.length > 0} + +{/if} + + diff --git a/src/routes/edition/[vol]/[doc]/[unit]/MultiMarkPopup.svelte b/src/routes/edition/[vol]/[doc]/[unit]/MultiMarkPopup.svelte new file mode 100644 index 0000000..b0d6871 --- /dev/null +++ b/src/routes/edition/[vol]/[doc]/[unit]/MultiMarkPopup.svelte @@ -0,0 +1,20 @@ + + +
+
    + {#each multiMarkPopupIds.ids as id} +
  • + +
  • + {/each} +
+
diff --git a/src/routes/edition/[vol]/[doc]/[unit]/Note.svelte b/src/routes/edition/[vol]/[doc]/[unit]/Note.svelte new file mode 100644 index 0000000..5411857 --- /dev/null +++ b/src/routes/edition/[vol]/[doc]/[unit]/Note.svelte @@ -0,0 +1,38 @@ + + +
{ + handleNoteClick(note.id); + selectedNote.id = note.id; + }} + onkeydown={(e) => (e.key === 'Enter' || e.key === ' ' ? handleNoteClick(note.id) : null)} + role="button" + tabindex="0" + aria-pressed={selectedNote.id === note.id} + aria-label="Focus note" +> + {@html note.content} +
+ + diff --git a/src/routes/edition/[vol]/[doc]/[unit]/Text.svelte b/src/routes/edition/[vol]/[doc]/[unit]/Text.svelte new file mode 100644 index 0000000..2f7bfab --- /dev/null +++ b/src/routes/edition/[vol]/[doc]/[unit]/Text.svelte @@ -0,0 +1,44 @@ + + + +
+ {@html text} +
+ + diff --git a/src/routes/edition/globals.svelte.js b/src/routes/edition/globals.svelte.js new file mode 100644 index 0000000..80d7d8d --- /dev/null +++ b/src/routes/edition/globals.svelte.js @@ -0,0 +1 @@ +export let copyWithoutLinebreaks = $state({ value: false }); diff --git a/static/icons/link.svg b/static/icons/link.svg new file mode 100644 index 0000000..b809935 --- /dev/null +++ b/static/icons/link.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file