Quartz sync: Nov 7, 2024, 9:13 PM

This commit is contained in:
Robin Sving 2024-11-07 21:13:42 +01:00
parent 3882759f5b
commit c804b495a5
14 changed files with 226 additions and 118 deletions

View file

@ -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.

View file

@ -7,8 +7,8 @@
- [[Emalysra]] - [[Emalysra]]
- [[Demondraken]] - [[Demondraken]]
- **Demoner** - **Demoner**
- [[Balorn]]
- [[Contessa Lrilatha]] - [[Contessa Lrilatha]]
- [[Coriolanus]]
- [[Demontyper]] - [[Demontyper]]
- [[Linteria, the Succubus]] - [[Linteria, the Succubus]]
- [[Drottning Abrogale Thrune II]] - [[Drottning Abrogale Thrune II]]
@ -17,6 +17,9 @@
- [[Hybrid]] - [[Hybrid]]
- [[Renviq Harduun, the Litch - RIP]] - [[Renviq Harduun, the Litch - RIP]]
- [[Svarta Korpen - former Knight]] - [[Svarta Korpen - former Knight]]
- **Tellus demongudar**
- [[Coriolanus]]
- [[Titus]]
- [[Vilree]] - [[Vilree]]
%% End Waypoint %% %% End Waypoint %%

View file

@ -0,0 +1,3 @@
---
status: alive
---

View file

@ -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_

View file

@ -1,6 +1,6 @@
--- ---
aliases: aliases:
- Messi - Mezi
owner: Johannes owner: Johannes
character: pc character: pc
status: alive status: alive
@ -21,7 +21,7 @@ Född i Golarion.
Ej en sol-och-vårare Ej en sol-och-vårare
Auditory Spells with [[Sustain a Spell]] Auditory Spells with [[Sustain]]
[[Illusory Creature]] [[Illusory Creature]]
[[Enthrall]] [[Enthrall]]
[[Unfathomable Song]] [[Unfathomable Song]]

View file

@ -12,9 +12,11 @@
- [[Past life 2 - Boulder]] - [[Past life 2 - Boulder]]
- [[Past life 3 - Petal, Awett Vida]] - [[Past life 3 - Petal, Awett Vida]]
- [[Quick]] - [[Quick]]
- [[Brev till Eloise]]
- **Leninismen** - **Leninismen**
- [[10 Handlingar]] - [[10 Handlingar]]
- [[10 proklamationer]] - [[10 proklamationer]]
- [[Untitled]]
- [[Char]] - [[Char]]
- [[Emsu]] - [[Emsu]]
- [[Glak]] - [[Glak]]
@ -166,6 +168,7 @@
- [[2024-10-09]] - [[2024-10-09]]
- [[2024-10-17]] - [[2024-10-17]]
- [[2024-10-23]] - [[2024-10-23]]
- [[2024-11-06]]
- **6. Meta** - **6. Meta**
- **[[House Rules]]** - **[[House Rules]]**
- [[Historia]] - [[Historia]]

View file

@ -1,3 +1,4 @@
Del av [[Tellus]]
Styrs av [[Coriolanus]] Styrs av [[Coriolanus]]
Här är vi Här är vi
Corolianus har 4 [[balor]], 1 [[vrolikai]] som "generaler" Corolianus har 4 [[balor]], 1 [[vrolikai]] som "generaler"

View file

@ -5,11 +5,11 @@ Leds av [[dispater-logm|Dispater]].
>800 år sedan människornas sista motstånd föll. >800 år sedan människornas sista motstånd föll.
# 4 Landområden # 4 Landområden (Kontinenter)
## Erebu ## Erebu
Styrs av [[dispater-logm|Dispater]] själv, i staden Urbs Aeterna Styrs av [[dispater-logm|Dispater]] själv, i staden Urbs Aeterna
## Assuwa ## Assuwa
Styrs av Titus Styrs av [[Titus]]
Producerar krigsmateriel, forskning Producerar krigsmateriel, forskning
## Anahuak ## Anahuak
Styrs av Scipio Styrs av Scipio

View file

@ -10,9 +10,9 @@ aliases:
Fortets ytterdel, samt härskare [[Coriolanus]] är förpassad till lavan. Fortets ytterdel, samt härskare [[Coriolanus]] är förpassad till lavan.
# Kvarvarande potentiella uppgifter # Kvarvarande potentiella uppgifter
- [ ] Rensa ut resterande boende - [x] Rensa ut resterande boende
- [x] Rädda [[Demondraken]] - [x] Rädda [[Demondraken]]
- [ ] Sno luftskepp - [x] Sno luftskepp
# Alt.1 Alex flygtur # Alt.1 Alex flygtur
## Synopsis ## 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 - Fåglar kanske inte är snabbare än en drake
## Dagen efter ## Dagen efter
- [ ] Döda alla kvarvarande [[balor]]s, om några - [x] 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] ~~Ta reda på om vi kan prata med Draken, och frigöra honom från sitt fängelse~~

View file

@ -7,21 +7,10 @@ quest: "[[Plan för att krossa fortet]]"
--- ---
# Saker att göra # Saker att göra
- [ ] Vaka för Ilju? - [x] [[Moment of Renewal]] add [[long-term-rest|Long-Term Rest]] calculation
- [ ] [[Fireside Chats]] - [x] Alex har Freezing Rain uppe ([[Effortless Concentration]])
- [ ] "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]])
# 2024-10-23 # 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. [[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]]. [[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]].

View file

@ -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]].

View file

@ -17,6 +17,9 @@ import { toHtml } from "hast-util-to-html"
import { PhrasingContent } from "mdast-util-find-and-replace/lib" import { PhrasingContent } from "mdast-util-find-and-replace/lib"
import { capitalize } from "../../util/lang" import { capitalize } from "../../util/lang"
import { PluggableList } from "unified" import { PluggableList } from "unified"
import yaml from "js-yaml"
import toml from "toml"
import matter from "gray-matter"
export interface Options { export interface Options {
comments: boolean comments: boolean
@ -31,6 +34,9 @@ export interface Options {
enableYouTubeEmbed: boolean enableYouTubeEmbed: boolean
enableVideoEmbed: boolean enableVideoEmbed: boolean
enableCheckbox: boolean enableCheckbox: boolean
parsePropertiesWikilinks: boolean
delims: string
language: "yaml" | "toml"
} }
const defaultOptions: Options = { const defaultOptions: Options = {
@ -46,6 +52,9 @@ const defaultOptions: Options = {
enableYouTubeEmbed: true, enableYouTubeEmbed: true,
enableVideoEmbed: true, enableVideoEmbed: true,
enableCheckbox: false, enableCheckbox: false,
parsePropertiesWikilinks: true,
delims: "---",
language: "yaml",
} }
const calloutMapping = { const calloutMapping = {
@ -95,31 +104,40 @@ function canonicalizeCallout(calloutName: string): keyof typeof calloutMapping {
return calloutMapping[normalizedCallout] ?? calloutName 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 externalLinkRegex = /^https?:\/\//i
export const arrowRegex = new RegExp(/(-{1,2}>|={1,2}>|<-{1,2}|<={1,2})/, "g") export const arrowRegex = new RegExp(/(-{1,2}>|={1,2}>|<-{1,2}|<={1,2})/, "g")
// !? -> optional embedding // !? -> optional embedding
// \[\[ -> open brace // \[\[ -> open brace
// ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name) // ([^\[\]\|\#]+) -> one or more non-special characters ([,],|, or #) (name)
// (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link) // (#[^\[\]\|\#]+)? -> # then one or more non-special characters (heading link)
// (\\?\|[^\[\]\#]+)? -> optional escape \ then | then one or more non-special characters (alias) // (\|[^\[\]\#]+)? -> | then one or more non-special characters (alias)
export const wikilinkRegex = new RegExp( export const wikilinkRegex = new RegExp(
/!?\[\[([^\[\]\|\#\\]+)?(#+[^\[\]\|\#\\]+)?(\\?\|[^\[\]\#]+)?\]\]/, /!?\[\[([^\[\]\|\#]+)?(#+[^\[\]\|\#]+)?(\|[^\[\]\#]+)?\]\]/,
"g", "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 highlightRegex = new RegExp(/==([^=]+)==/, "g")
const commentRegex = new RegExp(/%%[\s\S]*?%%/, "g") const commentRegex = new RegExp(/%%[\s\S]*?%%/, "g")
// from https://github.com/escwxyz/remark-obsidian-callout/blob/main/src/index.ts // 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 # // #(...) -> 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, 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 "/" // (?:\/[-_\p{L}\d\p{Z}]+)*) -> non-capturing group, matches an arbitrary number of tag strings separated by "/"
const tagRegex = new RegExp( const tagRegex = new RegExp(/(?:^| )#((?:[-_\p{L}\p{Emoji}\d])+(?:\/[-_\p{L}\p{Emoji}\d]+)*)/, "gu")
/(?:^| )#((?:[-_\p{L}\p{Emoji}\p{M}\d])+(?:\/[-_\p{L}\p{Emoji}\p{M}\d]+)*)/,
"gu",
)
const blockReferenceRegex = new RegExp(/\^([-_A-Za-z0-9]+)$/, "g") const blockReferenceRegex = new RegExp(/\^([-_A-Za-z0-9]+)$/, "g")
const ytLinkRegex = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/ 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 videoExtensionRegex = new RegExp(/\.(mp4|webm|ogg|avi|mov|flv|wmv|mkv|mpg|mpeg|3gp|m4v)$/)
const wikilinkImageEmbedRegex = new RegExp( const wikilinkImageEmbedRegex = new RegExp(
/^(?<alt>(?!^\d*x?\d*$).*?)?(\|?\s*?(?<width>\d+)(x(?<height>\d+))?)?$/, /^(?<alt>(?!^\d*x?\d*$).*?)?(\|?\s*?(?<width>\d+)(x(?<height>\d+))?)?$/,
@ -181,21 +195,6 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
src = src.toString() 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) => { src = src.replace(wikilinkRegex, (value, ...capture) => {
const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture const [rawFp, rawHeader, rawAlias]: (string | undefined)[] = capture
@ -214,9 +213,42 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
}) })
} }
// 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 return src
}, },
markdownPlugins(_ctx) { markdownPlugins() {
const plugins: PluggableList = [] const plugins: PluggableList = []
// regex replacements // regex replacements
@ -354,7 +386,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
children: [ children: [
{ {
type: "text", type: "text",
value: tag, value: `#${tag}`,
}, },
], ],
} }
@ -438,7 +470,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
children: [ children: [
{ {
type: "text", type: "text",
value: useDefaultTitle ? capitalize(typeString) : titleContent + " ", value: useDefaultTitle ? capitalize(calloutType) : titleContent + " ",
}, },
...restOfTitle, ...restOfTitle,
], ],
@ -474,19 +506,13 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
// replace first line of blockquote with title and rest of the paragraph text // replace first line of blockquote with title and rest of the paragraph text
node.children.splice(0, 1, ...blockquoteContent) 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 // add properties to base blockquote
node.data = { node.data = {
hProperties: { hProperties: {
...(node.data?.hProperties ?? {}), ...(node.data?.hProperties ?? {}),
className: classNames.join(" "), className: `callout ${calloutType} ${collapse ? "is-collapsible" : ""} ${
defaultState === "collapsed" ? "is-collapsed" : ""
}`,
"data-callout": calloutType, "data-callout": calloutType,
"data-callout-fold": collapse, "data-callout-fold": collapse,
}, },
@ -554,35 +580,12 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
last.value = last.value.slice(0, -matches[0].length) last.value = last.value.slice(0, -matches[0].length)
const block = matches[0].slice(1) const block = matches[0].slice(1)
if (last.value === "") { if (!Object.keys(file.data.blocks!).includes(block)) {
// this is an inline block ref but the actual block node.properties = {
// is the previous element above it ...node.properties,
let idx = (index ?? 1) - 1 id: block,
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
} }
file.data.blocks![block] = node
} }
} }
} }
@ -601,9 +604,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
if (node.tagName === "img" && typeof node.properties.src === "string") { if (node.tagName === "img" && typeof node.properties.src === "string") {
const match = node.properties.src.match(ytLinkRegex) const match = node.properties.src.match(ytLinkRegex)
const videoId = match && match[2].length == 11 ? match[2] : null const videoId = match && match[2].length == 11 ? match[2] : null
const playlistId = node.properties.src.match(ytPlaylistLinkRegex)?.[1]
if (videoId) { if (videoId) {
// YouTube video (with optional playlist)
node.tagName = "iframe" node.tagName = "iframe"
node.properties = { node.properties = {
class: "external-embed", class: "external-embed",
@ -611,20 +612,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
frameborder: 0, frameborder: 0,
width: "600px", width: "600px",
height: "350px", height: "350px",
src: playlistId src: `https://www.youtube.com/embed/${videoId}`,
? `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}`,
} }
} }
} }
@ -678,7 +666,7 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
let mermaidImport = undefined let mermaidImport = undefined
document.addEventListener('nav', async () => { document.addEventListener('nav', async () => {
if (document.querySelector("code.mermaid")) { 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 mermaid = mermaidImport.default
const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark' const darkMode = document.documentElement.getAttribute('saved-theme') === 'dark'
mermaid.initialize({ mermaid.initialize({
@ -709,4 +697,4 @@ declare module "vfile" {
blocks: Record<string, Element> blocks: Record<string, Element>
htmlAst: HtmlRoot htmlAst: HtmlRoot
} }
} }