Skip to content

Commit 3c91977

Browse files
committed
add side-by-side
1 parent f63b9e8 commit 3c91977

File tree

3 files changed

+120
-11
lines changed

3 files changed

+120
-11
lines changed

docs-obsidian.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,24 @@ This text is already on the page.
9797
- these three
9898
- lines
9999
```
100-
So you may see the `##fragment` tag as some kind of a `stop here and wait for me to press space` tag.
100+
So you may see the `##fragment` tag as some kind of a `stop here and wait for me to press space` tag.
101+
## Side-By-Side in Reveal.js
102+
It's possible to make columns that only work when making a presentation in Reveal.js.
103+
You may denote a side-by-side number of columns this and every section (column) will then render side by side, from left to right. This enables you to fill a wide-screen with, let's say, an image and a table with an explanation besides it.
104+
```bash
105+
Normal text. Will be displayed centered.
106+
##side-by-side-start
107+
This text will be on the left side...
108+
- one
109+
- two
110+
##separator
111+
- three
112+
- four
113+
114+
This will be on the right side
115+
##side-by-side-end
116+
117+
and this will be below the side-by-side element on the bottom.
118+
```
119+
When watching the document in the normal HTML view those tags have no effect.
120+
You can specify more than one separator resulting in more columns.

md/test-md-file.md

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,37 @@ Text
148148
>+ two ##fragment
149149
>+ three ##fragment
150150
151-
Done.
151+
Done.
152+
## Side-By-Side
153+
Normal text. Will be displayed centered.
154+
##side-by-side-start
155+
This text will be on the left side...
156+
- one
157+
- two
158+
##separator
159+
- three
160+
- four
161+
162+
This will be on the right side
163+
##side-by-side-end
164+
165+
and this will be below the side-by-side element on the bottom.
166+
## Side-By-Side 3 Cols
167+
Normal text. Will be displayed centered.
168+
##side-by-side-start
169+
This text will be on the left side...
170+
- one
171+
- two
172+
##separator
173+
- three
174+
- four
175+
176+
This will be in the middle
177+
##separator
178+
- three
179+
- four
180+
181+
This will be on the right side
182+
##side-by-side-end
183+
184+
and this will be below the side-by-side element on the bottom.

obsidian.js

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,18 @@ const internalSubstitutions = {
2727
},
2828
fragment_single: {
2929
string: "<!-- __fragment-marker__ -->"
30-
}
30+
},
31+
side_by_side_start: {
32+
string: "<!-- __side-by-side-start__ -->"
33+
},
34+
side_by_side_separator: {
35+
string: "<!-- __side-by-side-separator__ -->"
36+
},
37+
side_by_side_end: {
38+
string: "<!-- __side-by-side-end__ -->"
39+
},
3140
};
41+
3242
let codeList = [];
3343
let openNavTreeScript = "";
3444

@@ -373,6 +383,7 @@ export async function preParse(md, req) {
373383
r = preReplaceObsidianFileLinks(r, req);
374384
r = preMarkCallouts(r);
375385
r = preprocessFragments(r)
386+
r = preprocessSideBySide(r);
376387
r = unmarkCode(r);
377388
return r;
378389
}
@@ -451,6 +462,29 @@ function getFollowingQuotedLines(md, index) {
451462
return { trimmedLines: lines.slice(0, i).join("\n"), originalLength };
452463
}
453464

465+
function preprocessSideBySide(md) {
466+
const START = "##side-by-side-start";
467+
const END = "##side-by-side-end";
468+
const SEP = "##separator";
469+
470+
// Regex für kompletten Block
471+
const blockRegex = new RegExp(`${START}[\\s\\S]*?${END}`, "g");
472+
473+
return md.replace(blockRegex, (block) => {
474+
const content = block
475+
.replace(START, "")
476+
.replace(END, "")
477+
.trim();
478+
479+
const columns = content.split(SEP).map(col => col.trim());
480+
481+
// Jede Spalte in divs packen
482+
const htmlColumns = columns.map(col => `<div class="side-by-side-col">\n\n${col}\n\n</div>`);
483+
484+
return `<div class="side-by-side">\n${htmlColumns.join("\n")}\n</div>\n\n`;
485+
});
486+
}
487+
454488
function preprocessFragments(md) {
455489
const marker = internalSubstitutions.fragment_single.string;
456490
const r = md.replace(/##fragment(?=\s|$)/g, marker)
@@ -467,28 +501,35 @@ function postprocessFragments(html) {
467501
let fragmentIndex = -1;
468502
let started = false;
469503

504+
function resetFragmentIndex() {
505+
fragmentIndex = -1;
506+
started = false;
507+
}
508+
470509
function walk(node) {
471510
if (!node) return;
472511

473512
const childNodes = Array.from(node.childNodes);
474513
for (let child of childNodes) {
475-
// Marker detection
514+
// Reset bei h2 oder h3
515+
if (child.nodeType === 1 && (child.tagName === "H2" || child.tagName === "H3")) {
516+
resetFragmentIndex();
517+
}
518+
519+
// Fragmentmarker
476520
if (child.nodeType === 8 && child.nodeValue.trim() === markerValue) {
477521
fragmentIndex++;
478522
started = true;
479523
child.remove();
480524
continue;
481525
}
482526

483-
// Skip before first marker
484527
if (!started) {
485-
if (child.nodeType === 1) {
486-
walk(child); // still traverse deeper
487-
}
528+
if (child.nodeType === 1) walk(child);
488529
continue;
489530
}
490531

491-
// Text node
532+
// Text-Node
492533
if (child.nodeType === 3 && child.textContent.trim() !== "") {
493534
const span = document.createElement("span");
494535
span.classList.add("fragment");
@@ -498,11 +539,11 @@ function postprocessFragments(html) {
498539
continue;
499540
}
500541

501-
// Element node
542+
// Element-Node
502543
if (child.nodeType === 1) {
503544
child.classList.add("fragment");
504545
child.setAttribute("data-fragment-index", fragmentIndex);
505-
walk(child); // recurse
546+
walk(child); // Rekursiv in Tiefe gehen
506547
}
507548
}
508549
}
@@ -511,6 +552,8 @@ function postprocessFragments(html) {
511552
return document.body.innerHTML;
512553
}
513554

555+
556+
514557
function preReplaceObsidianFileLinks(html, req) {
515558
const regex = /(?<!\!)\[\[([^\]\n]+)\]\]/g;
516559

@@ -1367,6 +1410,19 @@ export async function wrapInReveal(reveal, req) {
13671410
font-size: 32px;
13681411
font-weight: 300;
13691412
}
1413+
.side-by-side {
1414+
display: flex;
1415+
flex-wrap: nowrap;
1416+
justify-content: stretch;
1417+
align-items: flex-start;
1418+
gap: 2rem;
1419+
width: 100%;
1420+
}
1421+
1422+
.side-by-side-col {
1423+
flex: 1 1 0;
1424+
min-width: 0;
1425+
}
13701426
</style>
13711427
<link rel="stylesheet" href="/obsidian-page.css">
13721428
<link rel="shortcut icon" href="/assets/favicon.ico" type="image/x-icon" />

0 commit comments

Comments
 (0)