···25252626and here is another
27272828+Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
2929+3030+::breakout::test:: Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
3131+3232+::full-width::test::@div::@nest:: Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
3333+3434+::breakout::  Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
3535+3636+Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat. In id cursus mi pretium tellus duis convallis. Tempus leo eu aenean sed diam urna tempor. Pulvinar vivamus fringilla lacus nec metus bibendum egestas. Iaculis massa nisl malesuada lacinia integer nunc posuere. Ut hendrerit semper vel class aptent taciti sociosqu. Ad litora torquent per conubia nostra inceptos himenaeos.
3737+2838paragraph with **_strong emph_**, **\*strong** in emph\*, **_emph_ in strong**, **in strong _emph_**, and \*in emph **strong\*** but not ~~this text~~ bc i said so
29393040now heres a paragraph with a [link](/blog "Goes to blog") which goes to blog, [a link](https://vielle.dev/) which points to my site, and a link to <https://deer.social>
+79-27
rehype-custom-html.ts
···11import type { Plugin } from "unified";
22-import type { Root, Element, Node } from "hast";
22+import type {
33+ Root,
44+ Element,
55+ Node,
66+ ElementContent,
77+ RootContent,
88+ Text,
99+} from "hast";
310type Options = {};
1111+412/*
513 blockquote flags go in the first line
614 they are formatted as:
···5159 })()
5260 ).toString();
53615454- console.log(alt);
5562 // match section before |
5663 const prefixes = alt.match(/.*?(?= \|.*)/gm);
5764 node.properties.alt = alt.match(/(?<= \| ).*/gm);
5865 if (!prefixes) return;
5966 const flags = prefixes[0].split(" ");
6067 for (const flag of flags) {
6161- console.log(flag);
6268 node.properties[`data-img-flag--${flag}`] = true;
6369 }
6464- console.log(flags);
6570}
66716767-const plugin: Plugin<[Options], Root> = function (options) {
6868- return function (root, _) {
6969- for (let node of root.children) {
7070- if (node.type === "element") {
7171- switch (node.tagName) {
7272- case "blockquote": {
7373- blockquote(node);
7474- break;
7575- }
7676- case "p": {
7777- let found = false;
7878- for (const n of node.children) {
7979- if (n.type === "element" && n.tagName === "img") {
8080- node = n;
8181- found = true;
8282- }
8383- }
8484- if (!found) break;
8585- }
8686- case "img": {
8787- image(node);
8888- break;
8989- }
7272+/*
7373+ paragraph flags go at the start
7474+ to use paragraph flags, include the following syntax at the start of a paragraph:
7575+ `::FLAG[::FLAG]*::`, where FLAG is a flag which is included as [data-para-flag--FLAG]
7676+ if FLAG starts with an `@`, it will be treated as a directive
7777+ current directives:
7878+ - @nest: replaces children with a p tag and moves children into it
7979+ - @div: replaces self with div
8080+*/
8181+8282+function para(value: Text, parent: Element) {
8383+ const flags = value.value.match(/(?<=^::).*(?=::)/gm);
8484+8585+ if (!flags) return;
8686+8787+ const txt = value.value.match(/(?<=^::.*:: ).*/gm);
8888+ value.value =
8989+ !txt || txt.length !== 1 ? "Err: Parser Error (custom HTML)" : txt[0];
9090+9191+ for (const flag of flags[0].split("::")) {
9292+ if (flag[0] === "@") {
9393+ switch (flag.slice(1)) {
9494+ case "nest": {
9595+ const prevChildren = parent.children;
9696+ parent.children = [
9797+ {
9898+ type: "element",
9999+ tagName: "p",
100100+ properties: {},
101101+ children: prevChildren,
102102+ } satisfies Element,
103103+ ];
104104+ break;
105105+ }
106106+ case "div": {
107107+ parent.tagName = "div";
108108+ break;
109109+ }
110110+ default: {
111111+ console.warn("Unknown paragraph directive:", flag);
90112 }
91113 }
114114+ } else parent.properties[`data-para-flag--${flag}`] = true;
115115+ }
116116+}
117117+118118+const forChild = (children: ElementContent[] | RootContent[]) => {
119119+ for (const node of children) {
120120+ if (node.type !== "element") continue;
121121+122122+ switch (node.tagName) {
123123+ case "blockquote": {
124124+ blockquote(node);
125125+ break;
126126+ }
127127+128128+ case "img": {
129129+ image(node);
130130+ break;
131131+ }
132132+133133+ case "p": {
134134+ if (node.children[0].type === "text") para(node.children[0], node);
135135+136136+ forChild(node.children);
137137+ }
92138 }
139139+ }
140140+};
141141+142142+const plugin: Plugin<[Options], Root> = function (options) {
143143+ return function (root, _) {
144144+ forChild(root.children);
93145 };
94146};
95147
+11-6
src/pages/blog/[id].astro
···24242525 if (!post.filePath) throw new Error("Post does not have a filepath");
2626 return import(`../../content/posts/${parse(post.filePath).name}.mdx`).then(
2727- (x) => x.Content
2727+ (x) => x.Content,
2828 );
2929})();
3030---
···5151 const els = document.querySelectorAll("main[data-colour-scheme-nojs]");
5252 if (els.length !== 1)
5353 throw new Error(
5454- "No `main[data-colour-scheme-nojs]`` found, or multiple found"
5454+ "No `main[data-colour-scheme-nojs]`` found, or multiple found",
5555 );
5656 const el = els[0];
5757 if (!(el instanceof HTMLElement)) throw new Error("Not HTML Element!");
···278278 }
279279280280 .content,
281281- .full-width {
282282- padding-block: 4em;
281281+ :global(.full-width),
282282+ :global([data-para-flag--full-width]) {
283283+ &.content {
284284+ padding-block: 4em;
285285+ }
283286284287 --padding-inline: 2rem;
285288 --content-max-width: 60ch;
···305308 grid-column: content;
306309 }
307310308308- & > :global(.breakout) {
311311+ & > :global(.breakout),
312312+ & > :global([data-para-flag--breakout]) {
309313 grid-column: breakout;
310314 }
311315312312- & > :global(.full-width) {
316316+ & > :global(.full-width),
317317+ & > :global([data-para-flag--full-width]) {
313318 grid-column: full-width;
314319 }
315320 }