diff --git a/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Demoner/Balorn.md b/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Demoner/Balorn.md new file mode 100755 index 000000000..9e6e2c850 --- /dev/null +++ b/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Demoner/Balorn.md @@ -0,0 +1,23 @@ +--- +aliases: + - Balorerna + - Balor + - Baloren +--- +Balorerna är [[balor|Balor]]. + +# Defences +**Hit points**: ~ +**AC**: 45 +**Fort** save: high +**Reflex/Will** save: mid + +# IWR +**Immunities**: [[Mechanics/Rule References/Fire|Fire]] +**Vulnerabilities**: [[Mechanics/Character Building/equipment/items/holy|Holy]] 20, [[cold-iron|Cold Iron]] 20 +**Resistances**: ? + +# Special abilities +- Big badaboom när de dör: 11d8 [[Mechanics/Rule References/Fire|Fire]] (ignore half resistances) i massive burst radius +- At will [[Dimension Door|Translocate]] +- [[Mechanics/Character Building/equipment/items/vorpal|Vorpal]]-runor på båda vapnen. \ No newline at end of file diff --git a/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Fiender.md b/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Fiender.md index fe59a2120..51e46e9cd 100755 --- a/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Fiender.md +++ b/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Fiender.md @@ -7,8 +7,8 @@ - [[Emalysra]] - [[Demondraken]] - **Demoner** + - [[Balorn]] - [[Contessa Lrilatha]] - - [[Coriolanus]] - [[Demontyper]] - [[Linteria, the Succubus]] - [[Drottning Abrogale Thrune II]] @@ -17,6 +17,9 @@ - [[Hybrid]] - [[Renviq Harduun, the Litch - RIP]] - [[Svarta Korpen - former Knight]] +- **Tellus demongudar** + - [[Coriolanus]] + - [[Titus]] - [[Vilree]] %% End Waypoint %% diff --git a/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Demoner/Coriolanus.md b/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Tellus demongudar/Coriolanus.md similarity index 100% rename from content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Demoner/Coriolanus.md rename to content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Tellus demongudar/Coriolanus.md diff --git a/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Tellus demongudar/Titus.md b/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Tellus demongudar/Titus.md new file mode 100755 index 000000000..3765f6bbc --- /dev/null +++ b/content/Worlds/1. Red Eclipse/1. Karaktärer/Fiender/Tellus demongudar/Titus.md @@ -0,0 +1,3 @@ +--- +status: alive +--- diff --git a/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Alex/Brev till Eloise.md b/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Alex/Brev till Eloise.md new file mode 100755 index 000000000..9b27d8f44 --- /dev/null +++ b/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Alex/Brev till Eloise.md @@ -0,0 +1,35 @@ +Två stycken pergament ligger ihoprullade tillsammans + +_Till mina äventyrarvänner i Röda Gänget (jag minns inte vad vi kallade oss, men det var väl någonting sådant - skyll inte på mig, jag var inte ens 3 månader när jag hörde det första gången, och vi använder det inte så ofta)._ + +_Jag antar att vänner är rätt ord; även om vi inte precis umgås med varandra så mycket socialt så har ni ändå lärt mig mycket om vem jag var._ + +_Det är synd att detta skulle vara det sista vi upplever tillsammans, men med tanke på vad vi åstadkommit för Golarion och framför allt Isger och även Cheliax, så känner jag mig stolt över våra bedrifter tillsammans._ + +_Som ett sista uppdrag så hoppas jag att ni kan ta med mina kvarlevor hem så att min kropp kan förmultna i Golarions välbekanta marker (gärna utanför Elidir), samt det efterföljande brevet. Se till att informera Eloise om min begravning, så att hon kan informera mina andra vänner. Ge henne även brevet._ + +_Tack för allt,_ + +_Alex_ + +--- + +_Till min kära Eloise,_ + +_Om du läser detta, så har min sista flygtur i världen tagits, och jag kan bara hoppas att mitt slut var ett värdigt sådant. Jag vill att du ska veta hur obeskrivligt glad jag är för att våra vägar möttes. För du är den eld som höll mig varm genom de mörkaste nätterna, min ständiga följeslagare i tanken, och garanterat det sista jag tänkte på innan det tog slut._ + +_Eloise, vi visste båda att jag inte var gjord för ett långt liv framför en brasa, inte för frid och trygghet. Jag var gjord för att kämpa. Jag var beredd att riskera allt, för det liv vi alltid drömde om – ett rike utan Thrunes. Ett rike där ditt folk inte lever under hennes tyranni, där framtiden är något mer än bara ett smalt fängelse för var och en av oss._ + +_Att få se ljuset i dina ögon när vi diskuterade på kvällarna i biblioteket – våra planer, våra galna idéer om frihet – det var då jag visste att jag måste försöka. Det var du som väckte mitt hjärta till den modiga, kanske dumdristiga, övertygelsen att **eftersom jag**_ _**kan så måste** **jag försöka** förändra världen till det bättre._ + +_Jag vet att du var orolig, jag vet att du bad mig att vara försiktig, men jag vet också att du vet att det inte fanns någon annan väg. Du, bättre än någon, visste att jag skulle gå på ända till slutet om så krävdes. Om detta brev når dig, så vet att jag har gjort det, och att jag gjorde det för oss alla. Jag tog steg som ledde mig bortom denna värld, men jag gjorde det för att göra vårt Isger till en plats där alla kan leva, utan rädslan för Thrune._ + +_Jag lämnar dig inte med bara sorg, Eloise. Jag lämnar dig med hopp, samma hopp som du tände i mig. Du vet var du ska leta. Jag vet att du kommer finna styrkan att fullfölja det som vi påbörjat._ + +_Så detta är mitt sista ord till dig: tack. Tack för att du såg mig, inte bara för den jag var, utan för den jag kunde bli. Tack för att du stod vid min sida. Och må du för alltid finna tröst inom bibliotekets väggar, med dess ord och hemligheter som både omfamnar och utbildar dig, precis som du en gång gjorde för mig._ + +_Med all kärlek och all den tacksamhet som mitt hjärta kan rymma,_ + +_Din älskade,_ + +_Ne-avak-ale x'ijat veter_ \ No newline at end of file diff --git a/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Alex/Untitled.md b/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Alex/Untitled.md new file mode 100755 index 000000000..e69de29bb diff --git a/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Mezisol.md b/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Mezisol.md index ab1a0ffb8..17baedcf1 100755 --- a/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Mezisol.md +++ b/content/Worlds/1. Red Eclipse/1. Karaktärer/Party/Mezisol.md @@ -1,6 +1,6 @@ --- aliases: - - Messi + - Mezi owner: Johannes character: pc status: alive @@ -21,7 +21,7 @@ Född i Golarion. Ej en sol-och-vårare -Auditory Spells with [[Sustain a Spell]] +Auditory Spells with [[Sustain]] [[Illusory Creature]] [[Enthrall]] [[Unfathomable Song]] diff --git a/content/Worlds/1. Red Eclipse/1. Red Eclipse.md b/content/Worlds/1. Red Eclipse/1. Red Eclipse.md index e035aaa09..36c05835e 100755 --- a/content/Worlds/1. Red Eclipse/1. Red Eclipse.md +++ b/content/Worlds/1. Red Eclipse/1. Red Eclipse.md @@ -12,9 +12,11 @@ - [[Past life 2 - Boulder]] - [[Past life 3 - Petal, Awett Vida]] - [[Quick]] + - [[Brev till Eloise]] - **Leninismen** - [[10 Handlingar]] - [[10 proklamationer]] + - [[Untitled]] - [[Char]] - [[Emsu]] - [[Glak]] @@ -166,6 +168,7 @@ - [[2024-10-09]] - [[2024-10-17]] - [[2024-10-23]] + - [[2024-11-06]] - **6. Meta** - **[[House Rules]]** - [[Historia]] diff --git a/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Alkebulan/Alkebulan.md b/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Alkebulan/Alkebulan.md index 6282a39af..6527c6a17 100755 --- a/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Alkebulan/Alkebulan.md +++ b/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Alkebulan/Alkebulan.md @@ -1,3 +1,4 @@ +Del av [[Tellus]] Styrs av [[Coriolanus]] Här är vi Corolianus har 4 [[balor]], 1 [[vrolikai]] som "generaler" diff --git a/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Tellus.md b/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Tellus.md index e90979ece..3bce68ca6 100755 --- a/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Tellus.md +++ b/content/Worlds/1. Red Eclipse/3. Platser/12 riken/Tellus/Tellus.md @@ -5,11 +5,11 @@ Leds av [[dispater-logm|Dispater]]. >800 år sedan människornas sista motstånd föll. -# 4 Landområden +# 4 Landområden (Kontinenter) ## Erebu Styrs av [[dispater-logm|Dispater]] själv, i staden Urbs Aeterna ## Assuwa -Styrs av Titus +Styrs av [[Titus]] Producerar krigsmateriel, forskning ## Anahuak Styrs av Scipio diff --git a/content/Worlds/1. Red Eclipse/4. Uppdrag/2. Pågående/Tellus/Plan för att krossa fortet.md b/content/Worlds/1. Red Eclipse/4. Uppdrag/2. Pågående/Tellus/Plan för att krossa fortet.md index 80fff8a87..e2b3d4a42 100755 --- a/content/Worlds/1. Red Eclipse/4. Uppdrag/2. Pågående/Tellus/Plan för att krossa fortet.md +++ b/content/Worlds/1. Red Eclipse/4. Uppdrag/2. Pågående/Tellus/Plan för att krossa fortet.md @@ -10,9 +10,9 @@ aliases: Fortets ytterdel, samt härskare [[Coriolanus]] är förpassad till lavan. # Kvarvarande potentiella uppgifter -- [ ] Rensa ut resterande boende +- [x] Rensa ut resterande boende - [x] Rädda [[Demondraken]] -- [ ] Sno luftskepp +- [x] Sno luftskepp # Alt.1 Alex flygtur ## Synopsis @@ -61,5 +61,5 @@ Förberedelser för [[Plan för att få tag på staven]] - Fåglar kanske inte är snabbare än en drake ## Dagen efter -- [ ] Döda alla kvarvarande [[balor]]s, om några -- [ ] Ta reda på om vi kan prata med Draken, och frigöra honom från sitt fängelse +- [x] Döda alla kvarvarande [[balor]]s, om några +- [x] ~~Ta reda på om vi kan prata med Draken, och frigöra honom från sitt fängelse~~ diff --git a/content/Worlds/1. Red Eclipse/5. Sessioner/2024/2024-10-23.md b/content/Worlds/1. Red Eclipse/5. Sessioner/2024/2024-10-23.md index bd467e27b..03fd21914 100755 --- a/content/Worlds/1. Red Eclipse/5. Sessioner/2024/2024-10-23.md +++ b/content/Worlds/1. Red Eclipse/5. Sessioner/2024/2024-10-23.md @@ -7,21 +7,10 @@ quest: "[[Plan för att krossa fortet]]" --- # Saker att göra -- [ ] Vaka för Ilju? -- [ ] [[Fireside Chats]] -- [ ] "Jag gillar inte hur lättvindigt hon offrar sina kompanjoner" -- [ ] Alma har bara ett öga -- [ ] [[Moment of Renewal]] add [[long-term-rest|Long-Term Rest]] calculation -- [ ] Vad är det för föremål som Miho använde mot drakarna? -- [ ] Alex har Freezing Rain uppe ([[Effortless Concentration]]) +- [x] [[Moment of Renewal]] add [[long-term-rest|Long-Term Rest]] calculation +- [x] Alex har Freezing Rain uppe ([[Effortless Concentration]]) # 2024-10-23 -Miss: 42 -Träff: 50 -Crit: 52 - off-guard+frightened - -Trolig AC: 45 - [[Emsu]] slår på [[Balor]], medan [[Glak]] gör en [[Opportune Backstab]], men missar. [[Balor]] börjar kasta en Spell, men [[Emsu]] gör en [[Reactive Strike]] och avbryter trollformeln. [[Balor]] slår på [[Lokwa]], som räddas av [[Breath of Life]] från [[Miho]]. diff --git a/content/Worlds/1. Red Eclipse/5. Sessioner/2024/2024-11-06.md b/content/Worlds/1. Red Eclipse/5. Sessioner/2024/2024-11-06.md new file mode 100755 index 000000000..10f7a90bc --- /dev/null +++ b/content/Worlds/1. Red Eclipse/5. Sessioner/2024/2024-11-06.md @@ -0,0 +1,63 @@ +--- +type: session +created: 2024-11-06 +location: "[[Alkebulan]]" +played: "[[Alex]]" +quest: "[[Plan för att krossa fortet]]" +--- + +# Saker att göra +- [ ] FALLA IHOP + - [ ] Föreslå vila, eller resa tillbaka? (kan vara sista chansen innan det börjar krylla av demoner) + - [ ] [[instant-fortress|Instant Fortress]] + - [ ] [[Brev till Eloise]] till [[Miho]] + - [ ] VARFÖR ÄR INTE ILJU DÖD? +- [x] ~~Vaka för Ilju?~~ +- [ ] [[Fireside Chats]] +- [ ] "Jag gillar inte hur lättvindigt hon offrar sina kompanjoner" +- [ ] Alma har bara ett öga +- [ ] Vad är det för föremål som Miho använde mot drakarna? +# 2024-11-06 +[[Balor]] teleporterar sig iväg, och [[Ilju]] springer ut och ser honom till slut, en mile bort. + +**[[Glak]]** börjar röra sig mot det lilla luftskeppet, och vi andra följer efter. + +**[[Emsu]]** ser demonen göra ett [[Dimension Door|Translocate]] på 120 feet och rör sig bortåt. **[[Alex]]** använder [[Updraft]] på **[[Emsu]]** som skickas iväg med en sjujäkla fart till skeppet, och tar sedan upp balorens [[Mechanics/Character Building/equipment/items/vorpal|vorpal]] [[Mechanics/Character Building/equipment/items/greatsword|Greatsword]]. + +**[[Glak]]** bär upp [[Lokwa]] till skeppet. + +[[Emsu]] får äran att försöka styra skeppet och trampar igång. **[[Glak]]** hittar ett brev som avslöjar att någon vid namn [[Titus]] troligen har [[Marcos|Marcos del Ray]]. Vi kommer iväg och börjar jaga efter demonen, vilket beräknas ta cirka 50 minuter att hinna ikapp. + +**[[Miho]]** behandlar skador medan vi flyger, och [[Alex]] [[refocus]] och hjälper till med att styra vinden. + +När vi kommer ikapp demonen försöker [[Emsu]] skjuta med skeppets "Autokanoner", men missar. **[[Miho]]** kastar en spell och ger en del skada - det verkar som att [[Holy]] är bra damage. + +Balorn har tröttnat på att bli jagad, kastar en ny spell och blinkar sig ned till marken. Vi flyger efter och Miho kastar en [[cantrip|Cantrip]] som crittar och ger skada. Trots att den inte ska göra mycket, så tar demonen skada av [[Mechanics/Character Building/equipment/items/holy|Holy]] igen. + +**[[Alex]]** hoppar ned till marken och försöker använda [[Ray of Frost|Frostbite]] på demonen, men utan större framgång. + +**[[Glak]]** försöker skjuta en pil, men det går inte heller så bra. Balorn kastar en ny kraftfull spell som ger massiv skada och blinkar bort. **[[Miho]]** använder [[Rebuke Death]] på [[Lokwa]], som hade gått ned, och helar sedan **[[Emsu]]**, som svänger skeppet mot den plats där **[[Balorn]]** är. + +**[[Mezisol]]** blinkar sig ur skeppet, och **[[Glak]]** säger åt **[[Lokwa]]** att hoppa ned. **[[Alex]]** försöker använda [[Eclipse Burst]]. + +**[[Balorn]]** blinkar till [[Mezisol]] och slår mot honom med piskan. **[[Emsu]]** svänger runt skeppet och skjuter med kanonerna och träffar! + +Miho helar lite, och [[Alex]] ger lite mer healing. + +**[[Balorn]]**, som hatar healers, blinkar sig bort till [[Alex]] och slår honom medvetslös. + +Skeppet "landar", och Emsu springer ut mot [[Balorn]] och framkallar ett [[Bastard Sword]]. + +**[[Miho]]** hoppar också ut och springer mot **[[Balorn]]**, eller alternativt mot [[Alex]]. + +[[Alex]] tar skada igen men får lite healing och återfår medvetandet. Balorn ogillar detta och slår ned honom igen. + +**[[Miho]]** använder [[Breath of Life]] på [[Alex]], men kan inte ge honom någon extra healing. + +**[[Emsu]]** springer fram och försöker slå, men lyckas inte fullt ut. + +**[[Glak]]** ansluter sig, medan **[[Mezisol]]** kastar [[Courageous Anthem]], vilket ger [[Emsu]] möjlighet att använda sitt reaktionsslag. Emsu träffar, och Glak gör en [[Opportunity Backstab]]. + +Balorn väljer att ta sitt eget liv för att undvika att bli dödad av [[Shardblade]]. En stor explosion ("Big Badaboom") sker; Alex är extremt nära döden och står och vinglar, Glak lyckas undvika en plötslig död. + +Skeppet tar skada och blir [[Broken]]. \ No newline at end of file diff --git a/quartz/plugins/transformers/ofm.ts b/quartz/plugins/transformers/ofm.ts index 108f7f779..0f215bbdb 100644 --- a/quartz/plugins/transformers/ofm.ts +++ b/quartz/plugins/transformers/ofm.ts @@ -17,6 +17,9 @@ import { toHtml } from "hast-util-to-html" import { PhrasingContent } from "mdast-util-find-and-replace/lib" import { capitalize } from "../../util/lang" import { PluggableList } from "unified" +import yaml from "js-yaml" +import toml from "toml" +import matter from "gray-matter" export interface Options { comments: boolean @@ -31,6 +34,9 @@ export interface Options { enableYouTubeEmbed: boolean enableVideoEmbed: boolean enableCheckbox: boolean + parsePropertiesWikilinks: boolean + delims: string + language: "yaml" | "toml" } const defaultOptions: Options = { @@ -46,6 +52,9 @@ const defaultOptions: Options = { enableYouTubeEmbed: true, enableVideoEmbed: true, enableCheckbox: false, + parsePropertiesWikilinks: true, + delims: "---", + language: "yaml", } const calloutMapping = { @@ -95,31 +104,40 @@ function canonicalizeCallout(calloutName: string): keyof typeof calloutMapping { return calloutMapping[normalizedCallout] ?? calloutName } +function propertyLinksToRegularMarkdown(obj: { [key: string]: any }): string { + // Parses wikilinks from FrontMatter properties and returns a string with all. + let result = "" + + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if ( + Array.isArray(obj[key]) && + typeof obj[key][0] === "string" && + obj[key][0].includes("[[") + ) { + result += `- ${key}: ${obj[key].join(", ")}\n` + } else if (typeof obj[key] === "string" && obj[key].includes("[[")) { + result += `- ${key}: ${obj[key]}\n` + } + } + } + + return result +} + export const externalLinkRegex = /^https?:\/\//i export const arrowRegex = new RegExp(/(-{1,2}>|={1,2}>|<-{1,2}|<={1,2})/, "g") -// !? -> optional embedding -// \[\[ -> open brace -// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) -// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) -// (\\?\|[^\[\]\#]+)? -> optional escape \ then | then one or more non-special characters (alias) +// !? -> optional embedding +// \[\[ -> open brace +// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) +// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) +// (\|[^\[\]\#]+)? -> | then one or more non-special characters (alias) export const wikilinkRegex = new RegExp( - /!?\[\[([^\[\]\|\#\\]+)?(#+[^\[\]\|\#\\]+)?(\\?\|[^\[\]\#]+)?\]\]/, + /!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\#]+)?\]\]/, "g", ) - -// ^\|([^\n])+\|\n(\|) -> matches the header row -// ( ?:?-{3,}:? ?\|)+ -> matches the header row separator -// (\|([^\n])+\|\n)+ -> matches the body rows -export const tableRegex = new RegExp( - /^\|([^\n])+\|\n(\|)( ?:?-{3,}:? ?\|)+\n(\|([^\n])+\|\n?)+/, - "gm", -) - -// matches any wikilink, only used for escaping wikilinks inside tables -export const tableWikilinkRegex = new RegExp(/(!?\[\[[^\]]*?\]\])/, "g") - const highlightRegex = new RegExp(/==([^=]+)==/, "g") const commentRegex = new RegExp(/%%[\s\S]*?%%/, "g") // from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts @@ -129,13 +147,9 @@ const calloutLineRegex = new RegExp(/^> *\[\!\w+\][+-]?.*$/, "gm") // #(...) -> capturing group, tag itself must start with # // (?:[-_\p{L}\d\p{Z}])+ -> non-capturing group, non-empty string of (Unicode-aware) alpha-numeric characters and symbols, hyphens and/or underscores // (?:\/[-_\p{L}\d\p{Z}]+)*) -> non-capturing group, matches an arbitrary number of tag strings separated by "/" -const tagRegex = new RegExp( - /(?:^| )#((?:[-_\p{L}\p{Emoji}\p{M}\d])+(?:\/[-_\p{L}\p{Emoji}\p{M}\d]+)*)/, - "gu", -) +const tagRegex = new RegExp(/(?:^| )#((?:[-_\p{L}\p{Emoji}\d])+(?:\/[-_\p{L}\p{Emoji}\d]+)*)/, "gu") const blockReferenceRegex = new RegExp(/\^([-_A-Za-z0-9]+)$/, "g") const ytLinkRegex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/ -const ytPlaylistLinkRegex = /[?&]list=([^#?&]*)/ const videoExtensionRegex = new RegExp(/\.(mp4|webm|ogg|avi|mov|flv|wmv|mkv|mpg|mpeg|3gp|m4v)$/) const wikilinkImageEmbedRegex = new RegExp( /^(?(?!^\d*x?\d*$).*?)?(\|?\s*?(?\d+)(x(?\d+))?)?$/, @@ -181,21 +195,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin src = src.toString() } - // replace all wikilinks inside a table first - src = src.replace(tableRegex, (value) => { - // escape all aliases and headers in wikilinks inside a table - return value.replace(tableWikilinkRegex, (value, ...capture) => { - const [raw]: (string | undefined)[] = capture - let escaped = raw ?? "" - escaped = escaped.replace("#", "\\#") - // escape pipe characters if they are not already escaped - escaped = escaped.replace(/((^|[^\\])(\\\\)*)\|/g, "$1\\|") - - return escaped - }) - }) - - // replace all other wikilinks src = src.replace(wikilinkRegex, (value, ...capture) => { const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture @@ -214,9 +213,42 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin }) } + // move Obsidian properties with links to the top of the file + if (opts.parsePropertiesWikilinks) { + if (src instanceof Buffer) { + src = src.toString() + } + + const { data } = matter(Buffer.from(src), { + ...opts, + engines: { + yaml: (s) => yaml.load(s, { schema: yaml.JSON_SCHEMA }) as object, + toml: (s) => toml.parse(s) as object, + }, + }) + const prop_links = propertyLinksToRegularMarkdown(data) + if (prop_links !== "") { + const yaml_props = src.split(opts.delims)[1] + const content = src.split(opts.delims).slice(2).join(opts.delims) + + src = + opts.delims + + "\n" + + yaml_props + + "\n" + + opts.delims + + "\n" + + prop_links + + "\n" + + opts.delims + + "\n" + + content + } + } + return src }, - markdownPlugins(_ctx) { + markdownPlugins() { const plugins: PluggableList = [] // regex replacements @@ -354,7 +386,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin children: [ { type: "text", - value: tag, + value: `#${tag}`, }, ], } @@ -438,7 +470,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin children: [ { type: "text", - value: useDefaultTitle ? capitalize(typeString) : titleContent + " ", + value: useDefaultTitle ? capitalize(calloutType) : titleContent + " ", }, ...restOfTitle, ], @@ -474,19 +506,13 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin // replace first line of blockquote with title and rest of the paragraph text node.children.splice(0, 1, ...blockquoteContent) - const classNames = ["callout", calloutType] - if (collapse) { - classNames.push("is-collapsible") - } - if (defaultState === "collapsed") { - classNames.push("is-collapsed") - } - // add properties to base blockquote node.data = { hProperties: { ...(node.data?.hProperties ?? {}), - className: classNames.join(" "), + className: `callout ${calloutType} ${collapse ? "is-collapsible" : ""} ${ + defaultState === "collapsed" ? "is-collapsed" : "" + }`, "data-callout": calloutType, "data-callout-fold": collapse, }, @@ -554,35 +580,12 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin last.value = last.value.slice(0, -matches[0].length) const block = matches[0].slice(1) - if (last.value === "") { - // this is an inline block ref but the actual block - // is the previous element above it - let idx = (index ?? 1) - 1 - while (idx >= 0) { - const element = parent?.children.at(idx) - if (!element) break - if (element.type !== "element") { - idx -= 1 - } else { - if (!Object.keys(file.data.blocks!).includes(block)) { - element.properties = { - ...element.properties, - id: block, - } - file.data.blocks![block] = element - } - return - } - } - } else { - // normal paragraph transclude - if (!Object.keys(file.data.blocks!).includes(block)) { - node.properties = { - ...node.properties, - id: block, - } - file.data.blocks![block] = node + if (!Object.keys(file.data.blocks!).includes(block)) { + node.properties = { + ...node.properties, + id: block, } + file.data.blocks![block] = node } } } @@ -601,9 +604,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin if (node.tagName === "img" && typeof node.properties.src === "string") { const match = node.properties.src.match(ytLinkRegex) const videoId = match && match[2].length == 11 ? match[2] : null - const playlistId = node.properties.src.match(ytPlaylistLinkRegex)?.[1] if (videoId) { - // YouTube video (with optional playlist) node.tagName = "iframe" node.properties = { class: "external-embed", @@ -611,20 +612,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin frameborder: 0, width: "600px", height: "350px", - src: playlistId - ? `https://www.youtube.com/embed/${videoId}?list=${playlistId}` - : `https://www.youtube.com/embed/${videoId}`, - } - } else if (playlistId) { - // YouTube playlist only. - node.tagName = "iframe" - node.properties = { - class: "external-embed", - allow: "fullscreen", - frameborder: 0, - width: "600px", - height: "350px", - src: `https://www.youtube.com/embed/videoseries?list=${playlistId}`, + src: `https://www.youtube.com/embed/${videoId}`, } } } @@ -678,7 +666,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin let mermaidImport = undefined document.addEventListener('nav', async () => { if (document.querySelector("code.mermaid")) { - mermaidImport ||= await import('https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.7.0/mermaid.esm.min.mjs') + mermaidImport ||= await import('https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs') const mermaid = mermaidImport.default const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark' mermaid.initialize({ @@ -709,4 +697,4 @@ declare module "vfile" { blocks: Record htmlAst: HtmlRoot } -} +} \ No newline at end of file