...
This commit is contained in:
parent
888b2372fa
commit
473c48689d
18 changed files with 965 additions and 2 deletions
BIN
Druckmaterial/Carousing (Zechen und Feiern)_A5.pdf
Normal file
BIN
Druckmaterial/Carousing (Zechen und Feiern)_A5.pdf
Normal file
Binary file not shown.
Binary file not shown.
BIN
Druckmaterial/autogen_Präsentation/Carousing.odt
Normal file
BIN
Druckmaterial/autogen_Präsentation/Carousing.odt
Normal file
Binary file not shown.
BIN
Druckmaterial/autogen_inbox/Carousing (Zechen und Feiern).odt
Normal file
BIN
Druckmaterial/autogen_inbox/Carousing (Zechen und Feiern).odt
Normal file
Binary file not shown.
8
RPG/.obsidian/appearance.json
vendored
8
RPG/.obsidian/appearance.json
vendored
|
|
@ -1,5 +1,9 @@
|
||||||
{
|
{
|
||||||
"cssTheme": "ITS Theme",
|
"cssTheme": "QuestJournal",
|
||||||
"nativeMenus": false,
|
"nativeMenus": false,
|
||||||
"theme": "moonstone"
|
"theme": "moonstone",
|
||||||
|
"enabledCssSnippets": [
|
||||||
|
"quest-journal-fontsize",
|
||||||
|
"quest-journal-kontrast"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
12
RPG/.obsidian/plugins/manual-sorting/data.json
vendored
12
RPG/.obsidian/plugins/manual-sorting/data.json
vendored
|
|
@ -2,6 +2,7 @@
|
||||||
"customOrder": {
|
"customOrder": {
|
||||||
"/": {
|
"/": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"2026-10-24.md",
|
||||||
"1-Sessions",
|
"1-Sessions",
|
||||||
"2-Spieler",
|
"2-Spieler",
|
||||||
"3-Welt",
|
"3-Welt",
|
||||||
|
|
@ -28,6 +29,9 @@
|
||||||
},
|
},
|
||||||
"1-Sessions/generische Tabellen": {
|
"1-Sessions/generische Tabellen": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"1-Sessions/generische Tabellen/Harissa Indoor-Waldläufertraining.md",
|
||||||
|
"1-Sessions/generische Tabellen/Magier Bibliotheks-Events.md",
|
||||||
|
"1-Sessions/generische Tabellen/Terian Kleriker-Gebetswoche.md",
|
||||||
"1-Sessions/generische Tabellen/Kreaturen",
|
"1-Sessions/generische Tabellen/Kreaturen",
|
||||||
"1-Sessions/generische Tabellen/Random Domain Events",
|
"1-Sessions/generische Tabellen/Random Domain Events",
|
||||||
"1-Sessions/generische Tabellen/Shop Catalog_v2.0.2.pdf",
|
"1-Sessions/generische Tabellen/Shop Catalog_v2.0.2.pdf",
|
||||||
|
|
@ -52,6 +56,7 @@
|
||||||
},
|
},
|
||||||
"1-Sessions/Info Snippets": {
|
"1-Sessions/Info Snippets": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"1-Sessions/Info Snippets/Notiz - Burn-Out System aktiviert.md",
|
||||||
"1-Sessions/Info Snippets/Baphomet.md",
|
"1-Sessions/Info Snippets/Baphomet.md",
|
||||||
"1-Sessions/Info Snippets/Definiere Schatz und Schatzkarte.md",
|
"1-Sessions/Info Snippets/Definiere Schatz und Schatzkarte.md",
|
||||||
"1-Sessions/Info Snippets/Der Kreuzritter Stadtstaat.md",
|
"1-Sessions/Info Snippets/Der Kreuzritter Stadtstaat.md",
|
||||||
|
|
@ -137,6 +142,7 @@
|
||||||
},
|
},
|
||||||
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026": {
|
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026/Unbenannt.md",
|
||||||
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026/Übersicht Prep 08.md",
|
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026/Übersicht Prep 08.md",
|
||||||
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026/Garana Events.md",
|
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026/Garana Events.md",
|
||||||
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026/Hooks.md"
|
"1-Sessions/Sitzungsarchiv/Sitzung 008 06.03.2026/Hooks.md"
|
||||||
|
|
@ -185,6 +191,7 @@
|
||||||
},
|
},
|
||||||
"3-Welt": {
|
"3-Welt": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"3-Welt/Weltstatus & Offene Enden.md",
|
||||||
"3-Welt/Wetter",
|
"3-Welt/Wetter",
|
||||||
"3-Welt/Geheimnisse",
|
"3-Welt/Geheimnisse",
|
||||||
"3-Welt/Königreich Taloria"
|
"3-Welt/Königreich Taloria"
|
||||||
|
|
@ -452,6 +459,9 @@
|
||||||
},
|
},
|
||||||
"5-Regeln/Hausregeln": {
|
"5-Regeln/Hausregeln": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"5-Regeln/Hausregeln/Carousing (Zechen und Feiern).md",
|
||||||
|
"5-Regeln/Hausregeln/Erwerb und Abschreiben von Zaubern.md",
|
||||||
|
"5-Regeln/Hausregeln/Wochen- und Rastaktivitäten.md",
|
||||||
"5-Regeln/Hausregeln/Fertigkeit_Kochen.md",
|
"5-Regeln/Hausregeln/Fertigkeit_Kochen.md",
|
||||||
"5-Regeln/Hausregeln/Westreich D&D Hausregeln V1.1.pdf"
|
"5-Regeln/Hausregeln/Westreich D&D Hausregeln V1.1.pdf"
|
||||||
],
|
],
|
||||||
|
|
@ -495,6 +505,7 @@
|
||||||
},
|
},
|
||||||
"7-Prep": {
|
"7-Prep": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"7-Prep/Markdown zu A5 exportieren.md",
|
||||||
"7-Prep/Abenteuer",
|
"7-Prep/Abenteuer",
|
||||||
"7-Prep/Bücher",
|
"7-Prep/Bücher",
|
||||||
"7-Prep/Ereignisse",
|
"7-Prep/Ereignisse",
|
||||||
|
|
@ -568,6 +579,7 @@
|
||||||
},
|
},
|
||||||
"zz_archiv/images": {
|
"zz_archiv/images": {
|
||||||
"children": [
|
"children": [
|
||||||
|
"zz_archiv/images/carouse-1.jpg",
|
||||||
"zz_archiv/images/Westreiche.jpeg",
|
"zz_archiv/images/Westreiche.jpeg",
|
||||||
"zz_archiv/images/Gharana_Umgebung.jpeg",
|
"zz_archiv/images/Gharana_Umgebung.jpeg",
|
||||||
"zz_archiv/images/Radomandeus.jpeg",
|
"zz_archiv/images/Radomandeus.jpeg",
|
||||||
|
|
|
||||||
17
RPG/.obsidian/snippets/quest-journal-fontsize.css
vendored
Normal file
17
RPG/.obsidian/snippets/quest-journal-fontsize.css
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* ==========================================================================
|
||||||
|
Quest Journal – größere Grundschrift
|
||||||
|
Wert (20px) nach Belieben anpassen (z. B. 18px oder 22px).
|
||||||
|
========================================================================== */
|
||||||
|
.markdown-source-view,
|
||||||
|
.markdown-preview-view {
|
||||||
|
font-size: 20px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
Dokumentenbaum (Datei-Explorer) – größere Schrift
|
||||||
|
Wert (18px) nach Belieben anpassen.
|
||||||
|
========================================================================== */
|
||||||
|
.nav-file-title,
|
||||||
|
.nav-folder-title {
|
||||||
|
font-size: 18px !important;
|
||||||
|
}
|
||||||
11
RPG/.obsidian/snippets/quest-journal-kontrast.css
vendored
Normal file
11
RPG/.obsidian/snippets/quest-journal-kontrast.css
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
/* ==========================================================================
|
||||||
|
Quest Journal – besserer Kontrast im Dunkelmodus („Ancient Leather“)
|
||||||
|
Deutlich hellerer Text auf dunkelbraunem Grund.
|
||||||
|
Werte nach Belieben anpassen.
|
||||||
|
========================================================================== */
|
||||||
|
body.theme-dark {
|
||||||
|
--text-normal: #efe7d3; /* Grundtext: fast weiß, deutlich heller */
|
||||||
|
--text-muted: #c4b69e; /* abgeschwächter Text (Metadata, Links …) */
|
||||||
|
--text-faint: #9c8f79; /* dezentester Text */
|
||||||
|
--text-navbar: #c4b69e; /* Datei-Explorer (Dokumentenbaum) */
|
||||||
|
}
|
||||||
9
RPG/.obsidian/themes/QuestJournal/manifest.json
vendored
Normal file
9
RPG/.obsidian/themes/QuestJournal/manifest.json
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"name": "Quest Journal",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"minAppVersion": "1.0.0",
|
||||||
|
"author": "Jack Lockwood",
|
||||||
|
"authorUrl": "",
|
||||||
|
"fundingUrl": "",
|
||||||
|
"isDesktopOnly": false
|
||||||
|
}
|
||||||
523
RPG/.obsidian/themes/QuestJournal/theme.css
vendored
Normal file
523
RPG/.obsidian/themes/QuestJournal/theme.css
vendored
Normal file
|
|
@ -0,0 +1,523 @@
|
||||||
|
/* @settings
|
||||||
|
name: Quest Journal Settings
|
||||||
|
id: quest-journal-settings
|
||||||
|
settings:
|
||||||
|
-
|
||||||
|
id: info-text-quest-journal
|
||||||
|
type: info-text
|
||||||
|
title: "Quest Journal Theme"
|
||||||
|
description: "A fantasy RPG inspired theme for Obsidian."
|
||||||
|
markdown: true
|
||||||
|
-
|
||||||
|
title: Typography
|
||||||
|
id: qj-typography
|
||||||
|
type: heading
|
||||||
|
level: 1
|
||||||
|
-
|
||||||
|
title: Header Font
|
||||||
|
id: qj-header-font
|
||||||
|
type: variable-text
|
||||||
|
default: "'Cinzel', 'Crimson Text', serif"
|
||||||
|
description: "Font family for headers (H1-H6)."
|
||||||
|
-
|
||||||
|
title: Body Font
|
||||||
|
id: qj-body-font
|
||||||
|
type: variable-text
|
||||||
|
default: "'Crimson Text', 'Georgia', serif"
|
||||||
|
description: "Font family for main text."
|
||||||
|
-
|
||||||
|
title: Appearance
|
||||||
|
id: qj-appearance
|
||||||
|
type: heading
|
||||||
|
level: 1
|
||||||
|
-
|
||||||
|
title: Hide Paper Texture
|
||||||
|
id: qj-hide-texture
|
||||||
|
type: class-toggle
|
||||||
|
description: "Removes the subtle lined paper background texture."
|
||||||
|
-
|
||||||
|
title: Header Underlines
|
||||||
|
id: qj-header-underlines
|
||||||
|
type: class-select
|
||||||
|
default: qj-header-underline-none
|
||||||
|
options:
|
||||||
|
-
|
||||||
|
label: Solid Line
|
||||||
|
value: qj-header-underline-solid
|
||||||
|
-
|
||||||
|
label: Double Line
|
||||||
|
value: qj-header-underline-double
|
||||||
|
-
|
||||||
|
label: Dotted Line
|
||||||
|
value: qj-header-underline-dotted
|
||||||
|
-
|
||||||
|
label: None
|
||||||
|
value: qj-header-underline-none
|
||||||
|
-
|
||||||
|
title: Colors (Light Mode)
|
||||||
|
id: qj-colors-light
|
||||||
|
type: heading
|
||||||
|
level: 2
|
||||||
|
-
|
||||||
|
title: Parchment Background
|
||||||
|
id: background-primary-light
|
||||||
|
type: variable-themed-color
|
||||||
|
format: hex
|
||||||
|
default-light: '#f0e6d2'
|
||||||
|
-
|
||||||
|
title: Ink Color
|
||||||
|
id: text-normal-light
|
||||||
|
type: variable-themed-color
|
||||||
|
format: hex
|
||||||
|
default-light: '#2b221b'
|
||||||
|
-
|
||||||
|
title: Accent Color (Wax Red)
|
||||||
|
id: text-accent-light
|
||||||
|
type: variable-themed-color
|
||||||
|
format: hex
|
||||||
|
default-light: '#8a3a3a'
|
||||||
|
-
|
||||||
|
title: Colors (Dark Mode)
|
||||||
|
id: qj-colors-dark
|
||||||
|
type: heading
|
||||||
|
level: 2
|
||||||
|
-
|
||||||
|
title: Leather Background
|
||||||
|
id: background-primary-dark
|
||||||
|
type: variable-themed-color
|
||||||
|
format: hex
|
||||||
|
default-dark: '#1e1915'
|
||||||
|
-
|
||||||
|
title: Gold Text
|
||||||
|
id: text-normal-dark
|
||||||
|
type: variable-themed-color
|
||||||
|
format: hex
|
||||||
|
default-dark: '#dcd0b8'
|
||||||
|
-
|
||||||
|
title: Accent Color (Magic Blue)
|
||||||
|
id: text-accent-dark
|
||||||
|
type: variable-themed-color
|
||||||
|
format: hex
|
||||||
|
default-dark: '#7ca8cf'
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
THEME: QUEST JOURNAL
|
||||||
|
STYLE: Parchment (Light) / Ancient Leather (Dark)
|
||||||
|
BASE: Tech001 Structure
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Import a classic serif font for that old-world feel */
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Crimson+Text:ital,wght@0,400;0,600;0,700;1,400&family=Cinzel:wght@400;700&display=swap');
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
1. VARIABLES & PALETTE
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
body {
|
||||||
|
--nav-indentation-guide-color: var(--text-faint) !important;
|
||||||
|
--nav-indentation-guide-width: 1px !important;
|
||||||
|
|
||||||
|
/* Typography - Default fallback if settings fail */
|
||||||
|
--font-interface: 'Crimson Text', 'Georgia', serif;
|
||||||
|
--font-text: 'Crimson Text', 'Georgia', serif;
|
||||||
|
--font-family-code: 'Consolas', 'Menlo', monospace;
|
||||||
|
--font-headers: 'Cinzel', 'Crimson Text', serif;
|
||||||
|
|
||||||
|
/* Shapes - Slightly softer edges */
|
||||||
|
--radius-s: 2px;
|
||||||
|
--radius-m: 4px;
|
||||||
|
--radius-l: 8px;
|
||||||
|
|
||||||
|
--h1-size: 2.4em;
|
||||||
|
--h2-size: 1.8em;
|
||||||
|
--h3-size: 1.4em;
|
||||||
|
--code-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Settings: Typography Overrides */
|
||||||
|
body {
|
||||||
|
--font-headers: var(--qj-header-font, 'Cinzel', 'Crimson Text', serif);
|
||||||
|
--font-text: var(--qj-body-font, 'Crimson Text', 'Georgia', serif);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- DARK THEME (ANCIENT LEATHER) --- */
|
||||||
|
body.theme-dark {
|
||||||
|
/* Backgrounds: Dark brown leather tones */
|
||||||
|
--background-primary: #1e1915;
|
||||||
|
--background-secondary: #251f1a;
|
||||||
|
--background-secondary-alt: #16120f;
|
||||||
|
--background-modifier-border: #3e3226;
|
||||||
|
--background-blockquote: #2a221d;
|
||||||
|
|
||||||
|
/* Text: Faded gold and old paper */
|
||||||
|
--text-normal: #dcd0b8;
|
||||||
|
--text-muted: #8c8175;
|
||||||
|
--text-faint: #5a5148;
|
||||||
|
--text-navbar: #8c8175;
|
||||||
|
--text-bold: #e8ded0;
|
||||||
|
|
||||||
|
/* Headers: Gold/Brass */
|
||||||
|
--h1-color: #cdb278;
|
||||||
|
--h2-color: #cdb278;
|
||||||
|
--h3-color: #bfa367;
|
||||||
|
--h4-color: #bfa367;
|
||||||
|
--h5-color: #bfa367;
|
||||||
|
--h6-color: #bfa367;
|
||||||
|
|
||||||
|
/* Accents: Muted Magic Blue/Purple */
|
||||||
|
--text-accent: #7ca8cf;
|
||||||
|
--text-accent-hover: #9ec1e0;
|
||||||
|
--interactive-accent: #3b2e25;
|
||||||
|
--caret-color: #cdb278;
|
||||||
|
|
||||||
|
/* Code */
|
||||||
|
--code-background: #15110e;
|
||||||
|
--code-border-color: #3e3226;
|
||||||
|
--code-normal: #dcd0b8;
|
||||||
|
--code-comment: #5a5148;
|
||||||
|
--code-string: #c17e73; /* Muted Red */
|
||||||
|
--code-function: #cdb278; /* Gold */
|
||||||
|
--code-keyword: #7ca8cf; /* Blue */
|
||||||
|
--code-operator: #8c8175;
|
||||||
|
--code-property: #8fb58e; /* Muted Green */
|
||||||
|
--code-value: #d4a768;
|
||||||
|
|
||||||
|
/* UI Specific */
|
||||||
|
--scrollbar-thumb: #3e3226;
|
||||||
|
--tab-hover: rgba(205, 178, 120, 0.05);
|
||||||
|
--sidebar-hover: rgba(205, 178, 120, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Settings: Dark Mode Colors Override */
|
||||||
|
body.theme-dark {
|
||||||
|
--background-primary: var(--background-primary-dark, #1e1915);
|
||||||
|
--text-normal: var(--text-normal-dark, #dcd0b8);
|
||||||
|
--text-accent: var(--text-accent-dark, #7ca8cf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- LIGHT THEME (QUEST PARCHMENT) --- */
|
||||||
|
body.theme-light {
|
||||||
|
/* Backgrounds: Warm Paper */
|
||||||
|
--background-primary: #f0e6d2;
|
||||||
|
--background-secondary: #e6dac1;
|
||||||
|
--background-secondary-alt: #f7f1e3;
|
||||||
|
--background-modifier-border: #c9bca6;
|
||||||
|
--background-blockquote: #e8dcc5;
|
||||||
|
|
||||||
|
/* Text: Dark Ink */
|
||||||
|
--text-normal: #2b221b;
|
||||||
|
--text-muted: #6b5a4b;
|
||||||
|
--text-faint: #a69686;
|
||||||
|
--text-navbar: #6b5a4b;
|
||||||
|
--text-bold: #1a1410;
|
||||||
|
|
||||||
|
/* Headers: Sealing Wax Red / Deep Ink */
|
||||||
|
--h1-color: #8a3a3a;
|
||||||
|
--h2-color: #2b221b;
|
||||||
|
--h3-color: #4a3c31;
|
||||||
|
--h4-color: #4a3c31;
|
||||||
|
--h5-color: #4a3c31;
|
||||||
|
--h6-color: #4a3c31;
|
||||||
|
|
||||||
|
/* Accents: Ink Blue / Rustic Gold */
|
||||||
|
--text-accent: #8a3a3a; /* Rust Red links */
|
||||||
|
--text-accent-hover: #a84b4b;
|
||||||
|
--interactive-accent: #dcd0b8;
|
||||||
|
--caret-color: #8a3a3a;
|
||||||
|
|
||||||
|
/* Code */
|
||||||
|
--code-background: #e9e1d1;
|
||||||
|
--code-border-color: #c9bca6;
|
||||||
|
--code-normal: #2b221b;
|
||||||
|
--code-comment: #8c8175;
|
||||||
|
--code-string: #a04040;
|
||||||
|
--code-function: #2b5c85;
|
||||||
|
--code-keyword: #5c3a75;
|
||||||
|
--code-operator: #6b5a4b;
|
||||||
|
--code-property: #3a6b3d;
|
||||||
|
--code-value: #9c6b1f;
|
||||||
|
|
||||||
|
/* UI Specific */
|
||||||
|
--scrollbar-thumb: #c9bca6;
|
||||||
|
--tab-hover: rgba(138, 58, 58, 0.05);
|
||||||
|
--sidebar-hover: rgba(138, 58, 58, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Settings: Light Mode Colors Override */
|
||||||
|
body.theme-light {
|
||||||
|
--background-primary: var(--background-primary-light, #f0e6d2);
|
||||||
|
--text-normal: var(--text-normal-light, #2b221b);
|
||||||
|
--text-accent: var(--text-accent-light, #8a3a3a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
2. GLOBAL LAYOUT & TYPOGRAPHY
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.markdown-source-view,
|
||||||
|
.markdown-preview-view {
|
||||||
|
font-family: var(--font-text);
|
||||||
|
line-height: 1.8; /* Slightly looser line height for journal feel */
|
||||||
|
font-size: 17px;
|
||||||
|
color: var(--text-normal);
|
||||||
|
background-image: linear-gradient(rgba(0,0,0,0.02) 1px, transparent 1px);
|
||||||
|
background-size: 100% 2em; /* Subtle lined paper effect */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Settings: Hide Texture */
|
||||||
|
body.qj-hide-texture .markdown-source-view,
|
||||||
|
body.qj-hide-texture .markdown-preview-view {
|
||||||
|
background-image: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- TEXT HIERARCHY --- */
|
||||||
|
.cm-header, h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: var(--h1-color) !important;
|
||||||
|
font-family: var(--font-headers) !important;
|
||||||
|
font-variant: small-caps;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
margin-bottom: 0.7em !important;
|
||||||
|
margin-top: 1.5em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Settings: Header Underline Styles */
|
||||||
|
body.qj-header-underline-solid .cm-header,
|
||||||
|
body.qj-header-underline-solid h1,
|
||||||
|
body.qj-header-underline-solid h2,
|
||||||
|
body.qj-header-underline-solid h3 {
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-height: 0.05px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.qj-header-underline-double .cm-header,
|
||||||
|
body.qj-header-underline-double h1,
|
||||||
|
body.qj-header-underline-double h2,
|
||||||
|
body.qj-header-underline-double h3 {
|
||||||
|
border-bottom-style: double;
|
||||||
|
border-bottom-width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.qj-header-underline-dotted .cm-header,
|
||||||
|
body.qj-header-underline-dotted h1,
|
||||||
|
body.qj-header-underline-dotted h2,
|
||||||
|
body.qj-header-underline-dotted h3 {
|
||||||
|
border-bottom-style: dotted;
|
||||||
|
border-bottom-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.qj-header-underline-none .cm-header,
|
||||||
|
body.qj-header-underline-none h1,
|
||||||
|
body.qj-header-underline-none h2,
|
||||||
|
body.qj-header-underline-none h3 {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { text-align: center; border-bottom: 2px solid var(--text-accent); }
|
||||||
|
|
||||||
|
.cm-line, p, li, ul, ol {
|
||||||
|
color: var(--text-normal) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
strong, b, .cm-strong {
|
||||||
|
color: var(--text-bold) !important;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Minimalist Scrollbars (Adapted to look rustic) */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 12px; height: 12px; background: transparent;
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--scrollbar-thumb);
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 2px solid var(--background-primary);
|
||||||
|
}
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
3. CENTERED LAYOUT (Retained from Tech001)
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.markdown-source-view.mod-cm6 .cm-scroller,
|
||||||
|
.markdown-preview-view {
|
||||||
|
padding-top: 50px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-source-view.mod-cm6:not(.is-readable-line-width) .cm-sizer,
|
||||||
|
.markdown-preview-view:not(.is-readable-line-width) .markdown-preview-sizer {
|
||||||
|
max-width: 1800px !important; /* Slightly narrower for reading comfort */
|
||||||
|
width: 100% !important;
|
||||||
|
margin-left: auto !important;
|
||||||
|
margin-right: auto !important;
|
||||||
|
margin-inline: auto !important;
|
||||||
|
padding-left: 40px !important;
|
||||||
|
padding-right: 40px !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
/* Paper Texture Shadow */
|
||||||
|
box-shadow: 0 0 50px -10px rgba(0,0,0,0.1);
|
||||||
|
background-color: var(--background-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
4. UI ELEMENTS
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.titlebar { background-color: transparent !important; z-index: 0; }
|
||||||
|
|
||||||
|
.titlebar-button-container {
|
||||||
|
background-color: var(--background-secondary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tabs like bookmarks */
|
||||||
|
.workspace-tab-header-container {
|
||||||
|
background-color: var(--background-secondary) !important;
|
||||||
|
border-bottom: 2px solid var(--background-modifier-border);
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-tab-header {
|
||||||
|
background-color: var(--background-secondary-alt) !important;
|
||||||
|
color: var(--text-muted);
|
||||||
|
border: 1px solid var(--background-modifier-border);
|
||||||
|
border-bottom: none;
|
||||||
|
border-radius: 6px 6px 0 0;
|
||||||
|
margin-right: 2px;
|
||||||
|
font-family: var(--font-headers);
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workspace-tab-header.is-active {
|
||||||
|
background-color: var(--background-primary) !important;
|
||||||
|
color: var(--text-accent);
|
||||||
|
font-weight: bold;
|
||||||
|
border-top: 2px solid var(--text-accent);
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar */
|
||||||
|
.nav-folder-title, .nav-file-title {
|
||||||
|
font-family: var(--font-interface);
|
||||||
|
font-size: 1em;
|
||||||
|
color: var(--text-navbar);
|
||||||
|
border-radius: var(--radius-m);
|
||||||
|
padding: 6px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-file-title.is-active {
|
||||||
|
color: var(--text-normal) !important;
|
||||||
|
background-color: var(--sidebar-hover);
|
||||||
|
border-left: 3px solid var(--text-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
5. EDITOR STYLES (Journal Specific)
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
/* Blockquotes - Scroll Style */
|
||||||
|
blockquote {
|
||||||
|
border: 1px solid var(--background-modifier-border);
|
||||||
|
border-left: 4px solid var(--text-accent);
|
||||||
|
background-color: var(--background-blockquote);
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 16px 24px;
|
||||||
|
margin: 1.5em 0;
|
||||||
|
color: var(--text-normal);
|
||||||
|
font-style: italic;
|
||||||
|
font-family: var(--font-interface);
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 2px 2px 5px rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checkboxes - Ink Squares */
|
||||||
|
input[type=checkbox] {
|
||||||
|
-webkit-appearance: none; appearance: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1.5px solid var(--text-muted);
|
||||||
|
width: 16px; height: 16px;
|
||||||
|
position: relative; top: 3px;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
input[type=checkbox]:checked {
|
||||||
|
background-color: transparent;
|
||||||
|
border-color: var(--text-accent);
|
||||||
|
}
|
||||||
|
input[type=checkbox]:checked:after {
|
||||||
|
content: 'x';
|
||||||
|
color: var(--text-accent);
|
||||||
|
position: absolute;
|
||||||
|
top: -4px; left: 2px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-family: cursive;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Horizontal Rules - Ornamental */
|
||||||
|
hr {
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
background-image: linear-gradient(to right, transparent, var(--text-muted), transparent);
|
||||||
|
margin: 3em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
6. CODE BLOCKS
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.markdown-reading-view code,
|
||||||
|
.markdown-source-view.is-live-preview .cm-inline-code:not(.cm-formatting) {
|
||||||
|
color: var(--text-normal) !important;
|
||||||
|
background-color: var(--background-secondary) !important;
|
||||||
|
border: 1px solid var(--background-modifier-border);
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 2px 6px;
|
||||||
|
font-family: var(--font-family-code);
|
||||||
|
font-size: 0.85em !important;
|
||||||
|
box-shadow: inset 1px 1px 3px rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code Blocks Container */
|
||||||
|
.markdown-reading-view pre,
|
||||||
|
.markdown-source-view.is-live-preview .HyperMD-codeblock {
|
||||||
|
background-color: var(--code-background);
|
||||||
|
border: 1px dashed var(--background-modifier-border);
|
||||||
|
border-radius: 2px;
|
||||||
|
font-family: var(--font-family-code);
|
||||||
|
line-height: 1.5 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-source-view.is-live-preview .HyperMD-codeblock-begin,
|
||||||
|
.markdown-source-view.is-live-preview .HyperMD-codeblock-end {
|
||||||
|
border: none;
|
||||||
|
background-color: var(--code-background);
|
||||||
|
color: var(--text-faint);
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
7. CUSTOM ICONS (Ink Dots)
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.nav-folder-title-content,
|
||||||
|
.nav-file-title-content {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simple ink dot for files */
|
||||||
|
body:not(.remove-file-icons) .nav-file-title .nav-file-title-content:not(.mk-tree-text)::before {
|
||||||
|
content: "•";
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 1.5em;
|
||||||
|
line-height: 0.5em;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-file-title.is-active .nav-file-title-content::before {
|
||||||
|
color: var(--text-accent);
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
![[carouse-1.jpg|255]]
|
||||||
|
|
||||||
# Hausregel: Carousing (Zechen & Feiern für Erfahrungspunkte)
|
# Hausregel: Carousing (Zechen & Feiern für Erfahrungspunkte)
|
||||||
|
|
||||||
> **Zweck:** In OSR-Spielen (und passend zu Kämpfern wie Rain) dient Gold oft als direkte Quelle für Erfahrungspunkte (XP) – allerdings nicht, indem es im Beutel versauert, sondern indem es ausgegeben wird! *Carousing* (Zechen, Feiern, Wetten und Großzügigkeit in Tavernen) belohnt das Verprassen von Schätzen mit XP, birgt aber auch typische Abenteuer-Kater-Risiken.
|
> **Zweck:** In OSR-Spielen (und passend zu Kämpfern wie Rain) dient Gold oft als direkte Quelle für Erfahrungspunkte (XP) – allerdings nicht, indem es im Beutel versauert, sondern indem es ausgegeben wird! *Carousing* (Zechen, Feiern, Wetten und Großzügigkeit in Tavernen) belohnt das Verprassen von Schätzen mit XP, birgt aber auch typische Abenteuer-Kater-Risiken.
|
||||||
|
|
|
||||||
100
RPG/7-Prep/Markdown zu A5 exportieren.md
Normal file
100
RPG/7-Prep/Markdown zu A5 exportieren.md
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
# Markdown zu A5 exportieren (LibreOffice ODT)
|
||||||
|
|
||||||
|
Aus den Markdown-Notizen dieser Knowledgebase lassen sich **editierbare A5-Dokumente**
|
||||||
|
für LibreOffice Writer erzeugen, die dort manuell nachbearbeitet werden können.
|
||||||
|
|
||||||
|
Alle Befehle werden aus dem Repo-Wurzelverzeichnis ausgeführt (dort, wo `tools/`, `RPG/`
|
||||||
|
und `Druckmaterial/` liegen).
|
||||||
|
|
||||||
|
## Arbeitsablauf
|
||||||
|
|
||||||
|
1. **Generieren** – das Skript erzeugt ein ODT nach `Druckmaterial/autogen_inbox/`.
|
||||||
|
2. **Bearbeiten** – das ODT in LibreOffice Writer öffnen und anpassen.
|
||||||
|
3. **Sichern** – nachbearbeitete Dokumente manuell nach `Druckmaterial/autogen_Präsentation/`
|
||||||
|
verschieben (dort sind sie vor erneuter Generierung sicher).
|
||||||
|
4. **PDF-Export** – bei Bedarf manuell in LibreOffice (`Datei → Exportieren als PDF`).
|
||||||
|
|
||||||
|
`autogen_inbox/` darf jederzeit überschrieben werden; `autogen_Präsentation/` enthält nur
|
||||||
|
die nachbearbeiteten Dokumente.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Befehl
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./tools/md2odt.sh "RPG/5-Regeln/Hausregeln/Carousing (Zechen und Feiern).md"
|
||||||
|
```
|
||||||
|
|
||||||
|
→ Ausgabe: `Druckmaterial/autogen_inbox/<Name>.odt`
|
||||||
|
|
||||||
|
**Optionaler zweiter Parameter** setzt einen eigenen Ausgabenamen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./tools/md2odt.sh "RPG/…/datei.md" "Mein_Name"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Was automatisch behandelt wird (Obsidian-Syntax)
|
||||||
|
|
||||||
|
- `[[Bild.jpg|375]]` → eingebettetes Bild, Breite 375 px (wird in cm umgerechnet)
|
||||||
|
- `[[Bild.jpg]]` → eingebettetes Bild in voller Textbreite
|
||||||
|
- `[[Notizname]]` → Klartext (der Notizname)
|
||||||
|
- `👉` → `→` und `🟡` → `●` (drucktaugliche Glyphen)
|
||||||
|
- `☀` und `⚠` → bleiben erhalten (LibreOffice setzt automatisch eine Fallback-Schrift ein)
|
||||||
|
- dekorative Emojis (`🌸`, `🗺`, …) → werden entfernt (der Text dahinter trägt die Bedeutung)
|
||||||
|
- `==Markierung==` → fett
|
||||||
|
- `%%Kommentar%%` → entfernt
|
||||||
|
- Pipe-Tabellen → echte Writer-Tabellen, Spaltenbreiten automatisch proportional zum Inhalt
|
||||||
|
- YAML-Frontmatter → wird von Pandoc als Metadaten genutzt
|
||||||
|
|
||||||
|
Bilder werden unabhängig vom Arbeitsverzeichnis über absolute Pfade gefunden.
|
||||||
|
Die Überschriften bleiben echte Stile („Überschrift 1/2/…“), sodass sie sich über
|
||||||
|
`F11` (Formatvorlagen) global anpassen lassen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Layout anpassen
|
||||||
|
|
||||||
|
Das A5-Layout (Seitenmaß, Ränder, Schriften, Schriftgröße) steckt in
|
||||||
|
`tools/make_reference_odt.py`. Nach einer Änderung dort:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 tools/make_reference_odt.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Das schreibt `tools/a5-reference.odt` neu. Danach erzeugte ODTs nutzen das neue Layout.
|
||||||
|
|
||||||
|
Aktuelle Werte:
|
||||||
|
|
||||||
|
| Was | Wo in `tools/make_reference_odt.py` |
|
||||||
|
|---|---|
|
||||||
|
| **Seitenmaß** | `fo:page-width/height` (14,801 × 21,001 cm = A5) |
|
||||||
|
| **Ränder** | `fo:margin-top/bottom/left/right` (0,8 / 1,0 / 1,0 / 0,7 cm) |
|
||||||
|
| **Grundschrift** | `"Times New Roman"` → `"Alegreya"` |
|
||||||
|
| **Überschriften** | `"Arial"` → `"Cinzel"` |
|
||||||
|
| **Schriftgröße** | `fo:font-size="12pt"` → `"10pt"` |
|
||||||
|
| **Seitennummern** | Footer im Master-Page (aktuell entfernt) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dateien der Werkzeugkette (in `tools/`)
|
||||||
|
|
||||||
|
| Datei | Zweck |
|
||||||
|
|---|---|
|
||||||
|
| `md2odt.sh` | Markdown → A5-ODT (nach `autogen_inbox/`) |
|
||||||
|
| `obsidian_preprocess.py` | Obsidian-Syntax (Wikilinks, Emojis, `==…==`, `%%…%%`) → sauberes Markdown |
|
||||||
|
| `autowidth.lua` | Tabellen-Spaltenbreiten proportional zum Inhalt |
|
||||||
|
| `a5-reference.odt` | ODT-Vorlage (Stile, A5-Layout) |
|
||||||
|
| `make_reference_odt.py` | erzeugt `a5-reference.odt` neu |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Einrichtung (einmalig, bereits erledigt)
|
||||||
|
|
||||||
|
Damit der Befehl läuft, ist Folgendes installiert:
|
||||||
|
|
||||||
|
- **Pandoc** 3.12 (`~/bin/pandoc`)
|
||||||
|
- **Alegreya** (Grundschrift) und **Cinzel** (Überschriften) unter `~/.local/share/fonts/`
|
||||||
|
|
||||||
|
Auf einem neuen Rechner müssten diese Komponenten entsprechend nachinstalliert werden.
|
||||||
BIN
RPG/zz_archiv/images/carouse-1.jpg
Normal file
BIN
RPG/zz_archiv/images/carouse-1.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
BIN
tools/a5-reference.odt
Normal file
BIN
tools/a5-reference.odt
Normal file
Binary file not shown.
58
tools/autowidth.lua
Normal file
58
tools/autowidth.lua
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
-- Verteilt Tabellenspalten proportional zur Inhaltslänge (statt gleicher
|
||||||
|
-- Breiten aus der Markdown-Trennzeile). Für Tabellen mit langer
|
||||||
|
-- Beschreibungsspalte (typisch bei RPG-Tabellen) deutlich besser lesbar.
|
||||||
|
--
|
||||||
|
-- Die Breite einer Spalte = max. Zeichenlänge ihrer Zellen (Header + Rumpf),
|
||||||
|
-- normalisiert auf Anteile. Mindestbreite 12 %, um schmale Kennspalten
|
||||||
|
-- (z. B. "d6") nicht zu erdrücken.
|
||||||
|
|
||||||
|
local FLOOR = 0.08
|
||||||
|
|
||||||
|
local function strlen(s)
|
||||||
|
local ok, n = pcall(utf8.len, s)
|
||||||
|
if ok then return n end
|
||||||
|
return #s
|
||||||
|
end
|
||||||
|
|
||||||
|
local function celltext(blocks)
|
||||||
|
return pandoc.utils.stringify(blocks)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Table(tbl)
|
||||||
|
local ncols = #tbl.colspecs
|
||||||
|
if ncols < 1 then return tbl end
|
||||||
|
|
||||||
|
local lens = {}
|
||||||
|
for i = 1, ncols do lens[i] = 1 end
|
||||||
|
|
||||||
|
local function measure(cells)
|
||||||
|
for i, cell in ipairs(cells) do
|
||||||
|
local l = strlen(celltext(cell.contents))
|
||||||
|
if l > lens[i] then lens[i] = l end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if tbl.head and tbl.head.rows then
|
||||||
|
for _, row in ipairs(tbl.head.rows) do measure(row.cells) end
|
||||||
|
end
|
||||||
|
for _, body in ipairs(tbl.bodies) do
|
||||||
|
for _, row in ipairs(body.body) do measure(row.cells) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local total = 0
|
||||||
|
for i = 1, ncols do
|
||||||
|
lens[i] = math.sqrt(lens[i])
|
||||||
|
total = total + lens[i]
|
||||||
|
end
|
||||||
|
|
||||||
|
if total > 0 then
|
||||||
|
for i = 1, ncols do
|
||||||
|
local w = lens[i] / total
|
||||||
|
if w < FLOOR then w = FLOOR end
|
||||||
|
-- ColSpec ist positionsbasiert: [1]=align, [2]=width
|
||||||
|
tbl.colspecs[i][2] = w
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return tbl
|
||||||
|
end
|
||||||
69
tools/make_reference_odt.py
Executable file
69
tools/make_reference_odt.py
Executable file
|
|
@ -0,0 +1,69 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Erzeugt tools/a5-reference.odt aus der Pandoc-Standardreferenz,
|
||||||
|
angepasst an dein A5-Layout:
|
||||||
|
|
||||||
|
- A5 (14,801 x 21,001 cm), Ränder oben 0,8 / unten 1,0 / links 1,0 / rechts 0,7 cm
|
||||||
|
- Grundschrift Alegreya 10 pt, Überschriften Cinzel
|
||||||
|
- keine Seitennummern (Footer entfernt)
|
||||||
|
|
||||||
|
Aufruf: python3 make_reference_odt.py
|
||||||
|
"""
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import zipfile
|
||||||
|
|
||||||
|
TOOLS = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
OUT = os.path.join(TOOLS, "a5-reference.odt")
|
||||||
|
|
||||||
|
# 1) Pandoc-Standardreferenz holen
|
||||||
|
default = subprocess.check_output(
|
||||||
|
["pandoc", "--print-default-data-file", "reference.odt"]
|
||||||
|
)
|
||||||
|
|
||||||
|
zin = zipfile.ZipFile(io.BytesIO(default))
|
||||||
|
names = zin.namelist()
|
||||||
|
items = {n: zin.read(n) for n in names}
|
||||||
|
|
||||||
|
styles = items["styles.xml"].decode("utf-8")
|
||||||
|
|
||||||
|
# 2) Gezielte Ersetzungen
|
||||||
|
REPL = [
|
||||||
|
# --- Seite A5 + Ränder ---
|
||||||
|
('fo:page-width="8.5in"', 'fo:page-width="14.801cm"'),
|
||||||
|
('fo:page-height="11in"', 'fo:page-height="21.001cm"'),
|
||||||
|
('fo:margin-top="1in"', 'fo:margin-top="0.8cm"'),
|
||||||
|
('fo:margin-bottom="1in"', 'fo:margin-bottom="1cm"'),
|
||||||
|
('fo:margin-left="1in"', 'fo:margin-left="1cm"'),
|
||||||
|
('fo:margin-right="1in"', 'fo:margin-right="0.7cm"'),
|
||||||
|
# --- Schriften ---
|
||||||
|
("Times New Roman", "Alegreya"),
|
||||||
|
("Arial", "Cinzel"),
|
||||||
|
("Lucida Sans Unicode", "Cinzel"),
|
||||||
|
("Tahoma1", "Cinzel"),
|
||||||
|
("Tahoma", "Cinzel"),
|
||||||
|
# --- Grundschrift 12 pt -> 10 pt ---
|
||||||
|
('fo:font-size="12pt"', 'fo:font-size="10pt"'),
|
||||||
|
('font-size-asian="12pt"', 'font-size-asian="10pt"'),
|
||||||
|
('font-size-complex="12pt"', 'font-size-complex="10pt"'),
|
||||||
|
]
|
||||||
|
|
||||||
|
for a, b in REPL:
|
||||||
|
styles = styles.replace(a, b)
|
||||||
|
|
||||||
|
# 3) Footer (Seitennummer) aus dem Master-Page entfernen
|
||||||
|
styles = re.sub(r"<style:footer>.*?</style:footer>", "", styles, flags=re.S)
|
||||||
|
|
||||||
|
items["styles.xml"] = styles.encode("utf-8")
|
||||||
|
|
||||||
|
# 4) Neu packen: mimetype zuerst und unkomprimiert
|
||||||
|
with zipfile.ZipFile(OUT, "w") as z:
|
||||||
|
z.writestr("mimetype", items["mimetype"], compress_type=zipfile.ZIP_STORED)
|
||||||
|
for n in names:
|
||||||
|
if n == "mimetype":
|
||||||
|
continue
|
||||||
|
z.writestr(n, items[n], compress_type=zipfile.ZIP_DEFLATED)
|
||||||
|
|
||||||
|
print("OK:", OUT)
|
||||||
42
tools/md2odt.sh
Executable file
42
tools/md2odt.sh
Executable file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Markdown (Obsidian) -> editierbares LibreOffice-ODT (A5)
|
||||||
|
#
|
||||||
|
# Aufruf:
|
||||||
|
# ./tools/md2odt.sh <datei.md> [ausgabename-ohne-endung]
|
||||||
|
#
|
||||||
|
# Ausgabe (Standard): Druckmaterial/<name>.odt
|
||||||
|
#
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
VAULT="$ROOT/RPG"
|
||||||
|
TOOLS="$ROOT/tools"
|
||||||
|
OUTDIR="${OUTDIR:-$ROOT/Druckmaterial/autogen_inbox}"
|
||||||
|
|
||||||
|
if [ "$#" -lt 1 ]; then
|
||||||
|
echo "Aufruf: $0 <datei.md> [ausgabename]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SRC="$(realpath "$1")"
|
||||||
|
NAME="${2:-$(basename "$SRC" .md)}"
|
||||||
|
OUT="$OUTDIR/${NAME}.odt"
|
||||||
|
|
||||||
|
mkdir -p "$OUTDIR"
|
||||||
|
|
||||||
|
TMP="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$TMP"' EXIT
|
||||||
|
|
||||||
|
# 1) Obsidian-Syntax vorverarbeiten
|
||||||
|
python3 "$TOOLS/obsidian_preprocess.py" "$VAULT" < "$SRC" > "$TMP/in.md"
|
||||||
|
|
||||||
|
# 2) Markdown -> ODT (A5-Referenzvorlage; H1 bleibt als "Heading 1" erhalten)
|
||||||
|
pandoc "$TMP/in.md" \
|
||||||
|
-f markdown+raw_html \
|
||||||
|
-t odt \
|
||||||
|
--reference-doc="$TOOLS/a5-reference.odt" \
|
||||||
|
--lua-filter="$TOOLS/autowidth.lua" \
|
||||||
|
-o "$OUT"
|
||||||
|
|
||||||
|
echo "OK: $OUT"
|
||||||
116
tools/obsidian_preprocess.py
Normal file
116
tools/obsidian_preprocess.py
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Vorverarbeitung von Obsidian-Markdown zu sauberem Pandoc-Markdown.
|
||||||
|
|
||||||
|
Behandelt:
|
||||||
|
- Obsidian-Wikilinks: [[Ziel]] [[Ziel|Anzeige]] [[bild.jpg|BreitePx]]
|
||||||
|
- Emoji -> drucktaugliche Glyphen bzw. Text (dekorative Emojis werden entfernt)
|
||||||
|
- ==Markierung== -> **fett** (drucktauglicher Ersatz)
|
||||||
|
- %% Kommentare %% -> entfernt
|
||||||
|
- Variation-Selektoren (U+FE0F/U+FE0E) entfernen
|
||||||
|
|
||||||
|
Aufruf:
|
||||||
|
obsidian_preprocess.py <VAULT_ROOT> < eingabe.md > ausgabe.md
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
IMG_EXT = {".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".svg", ".avif"}
|
||||||
|
|
||||||
|
# Emoji -> Ersatz (leerer String = entfernen)
|
||||||
|
EMOJI = {
|
||||||
|
"\U0001F449": "\u2192", # 👉 ->
|
||||||
|
"\U0001F7E1": "\u25CF", # 🟡 ●
|
||||||
|
"\u26A0": "\u26A0", # ⚠ (wird über DejaVu-Fallback gesetzt)
|
||||||
|
"\u2600": "\u2600", # ☀ (DejaVu-Fallback)
|
||||||
|
"\U0001F338": "", # 🌸
|
||||||
|
"\U0001F342": "", # 🍂
|
||||||
|
"\u2744": "", # ❄
|
||||||
|
"\U0001F324": "", # 🌤
|
||||||
|
"\U0001F5FA": "", # 🗺
|
||||||
|
"\U0001F3D4": "", # 🏔
|
||||||
|
"\U0001F5E3": "", # 🗣
|
||||||
|
"\U0001F48E": "", # 💎
|
||||||
|
"\U0001F3B2": "", # 🎲
|
||||||
|
"\u26A1": "", # ⚡
|
||||||
|
"\U0001F4C8": "", # 📈
|
||||||
|
"\U0001F4C9": "", # 📉
|
||||||
|
"\U0001F504": "", # 🔄
|
||||||
|
}
|
||||||
|
VS = {"\uFE0F", "\uFE0E"}
|
||||||
|
|
||||||
|
SKIP_DIRS = {".git", ".obsidian", ".trash", "node_modules"}
|
||||||
|
|
||||||
|
|
||||||
|
def scan_images(root: str) -> dict:
|
||||||
|
"""basename(lower) -> absoluter Pfad (nur Nicht-.trash-Pfade)."""
|
||||||
|
mapping = {}
|
||||||
|
|
||||||
|
def walk():
|
||||||
|
for dirpath, dirnames, filenames in os.walk(root):
|
||||||
|
dirnames[:] = [d for d in dirnames if d not in SKIP_DIRS]
|
||||||
|
for fn in filenames:
|
||||||
|
if os.path.splitext(fn)[1].lower() in IMG_EXT:
|
||||||
|
# Absoluter Pfad, damit Pandoc das Bild unabhängig vom
|
||||||
|
# aktuellen Arbeitsverzeichnis findet.
|
||||||
|
full = os.path.abspath(os.path.join(dirpath, fn))
|
||||||
|
key = fn.lower()
|
||||||
|
mapping.setdefault(key, full)
|
||||||
|
walk()
|
||||||
|
return mapping
|
||||||
|
|
||||||
|
|
||||||
|
def px_to_cm(px: float) -> float:
|
||||||
|
return round(px / 96.0 * 2.54, 2)
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_wikilink(image_map: dict, inner: str) -> str:
|
||||||
|
if "|" in inner:
|
||||||
|
target, disp = inner.split("|", 1)
|
||||||
|
else:
|
||||||
|
target, disp = inner, None
|
||||||
|
target = target.strip()
|
||||||
|
ext = os.path.splitext(target.lower())[1]
|
||||||
|
if ext in IMG_EXT:
|
||||||
|
path = image_map.get(target.lower(), target)
|
||||||
|
alt = os.path.basename(target)
|
||||||
|
if disp is not None and disp.strip().isdigit():
|
||||||
|
width = px_to_cm(int(disp.strip()))
|
||||||
|
return f"{{width={width}cm}}"
|
||||||
|
return f"{{width=100%}}"
|
||||||
|
# Notiz-Link -> Klartext
|
||||||
|
return (disp.strip() if disp is not None else target)
|
||||||
|
|
||||||
|
|
||||||
|
def process(text: str, image_map: dict) -> str:
|
||||||
|
# 1. Kommentare
|
||||||
|
text = re.sub(r"%%.*?%%", "", text, flags=re.DOTALL)
|
||||||
|
# 2. Wikilinks
|
||||||
|
text = re.sub(r"\[\[([^\]]+)\]\]", lambda m: resolve_wikilink(image_map, m.group(1)), text)
|
||||||
|
# 3. Variation-Selektoren
|
||||||
|
for vs in VS:
|
||||||
|
text = text.replace(vs, "")
|
||||||
|
# 4. Emoji
|
||||||
|
for k, v in EMOJI.items():
|
||||||
|
text = text.replace(k, v)
|
||||||
|
# 5. ==mark== -> **fett**
|
||||||
|
text = re.sub(r"==([^=\n]+)==", r"**\1**", text)
|
||||||
|
# 6. Leerraum glätten (nach Emoji-Entfernung), aber Tabellen/Code unberührt
|
||||||
|
out = []
|
||||||
|
for line in text.split("\n"):
|
||||||
|
stripped = line.lstrip()
|
||||||
|
if not stripped.startswith("|") and not stripped.startswith("```"):
|
||||||
|
line = re.sub(r"[ \t]{2,}", " ", line)
|
||||||
|
out.append(line)
|
||||||
|
return "\n".join(out)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
root = sys.argv[1] if len(sys.argv) > 1 else "."
|
||||||
|
image_map = scan_images(root)
|
||||||
|
sys.stdout.write(process(sys.stdin.read(), image_map))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue