From a1a55e51e673555d27221480c370421c8b556713 Mon Sep 17 00:00:00 2001 From: "Philipp A." Date: Wed, 19 Feb 2025 16:23:32 +0100 Subject: [PATCH] Hacky footnote support --- ...2024-11-17-expectations-disappointment.rst | 18 +++--- src/build-tools/rst.tsx | 59 ++++++++++++++++--- src/components/markup/MarkupNodeComponent.tsx | 6 +- src/markup/MarkupDocument.ts | 15 +++++ typings/restructured/index.d.ts | 9 ++- 5 files changed, 90 insertions(+), 17 deletions(-) diff --git a/posts/2024-11-17-expectations-disappointment.rst b/posts/2024-11-17-expectations-disappointment.rst index 83239aa..eb1d631 100644 --- a/posts/2024-11-17-expectations-disappointment.rst +++ b/posts/2024-11-17-expectations-disappointment.rst @@ -3,24 +3,24 @@ Expectations and Disappointment It’s your responsibility to deal with your frustration when you wanted someone to want something, and they don’t. -Being close with someone means you build a mental model of their behavior. +Getting to know someone means you build a mental model of their behavior. You spend enough time around them that you come to trust this model to predict how they are going to react to something. And then they don’t. And you were actually looking forward to the other response they could have given, the one they didn’t give. This feeling is called “frustration”. -Now there are a few ways people tend to go from here. +Now there are a few ways people tend to go from here. E.g. I don’t deserve to feel frustrated, that’s not fair. - This person I’m close with is not very nice to do that to me. + This person is not very nice to do that to me. -We could say, they expect the other person to be able to read minds. -To react in a way that caters to the unspoken expectations of someone else. +We could say, they expect the other person to be able to read minds – +to react in a way that caters to the unspoken expectations of someone else. or - I really believed that person I’m close with to be the kind of person that would have done the other thing. - Maybe they just did this thing I didn’t like that once, that would be naughty of them. + I really believed that person to be the kind of person that would have done the other thing. + Maybe they just did this thing I didn’t like that one time, that would be naughty of them. Or it’s a character flaw of them to be the kind of person that doesn’t do that. In other words, they are filling in the blanks in their mental model with themselves; @@ -31,6 +31,8 @@ or The other way to react ---------------------- +I often have to remind myself of the rationalist mantra. [1]_ + .. epigraph:: As a rationalist, my strength is to be more confused by fiction than reality. @@ -47,3 +49,5 @@ don’t make the situation toxic by expecting the worst, but think “I notice t PS: People tend to forget rules that rarely come into play. Especially if they aren’t aware that how important they are to you. So make sure that close others know what’s important to you. + +.. [1] The problems in the rationalist community notwithstanding, they do have nice ideals. diff --git a/src/build-tools/rst.tsx b/src/build-tools/rst.tsx index adc9fef..4fae220 100644 --- a/src/build-tools/rst.tsx +++ b/src/build-tools/rst.tsx @@ -50,13 +50,33 @@ function convertNode(node: RSTNode, level: number): m.Node[] { switch (node.type) { case 'document': return convertChildren(node, level) - case 'comment': + case 'comment': { + const comment = (node.children as [RSTInlineNode])[0].value + + const [name, text] = parseCommentAsFootnote(comment) + if (name !== null && text !== null) { + return [ + // TODO: anchor + + {text} + , + ] + } return [] - case 'reference': { - const name = (node.children[0] as RSTInlineNode).value + } + case 'reference': + case 'footnote_reference': { + const text = (node.children[0] as RSTInlineNode).value + const [name, label] = + node.type === 'footnote_reference' + ? [ + `footnote-${text}`, + {text}, + ] + : [text, text] return [ - {name} + {label} , ] } @@ -289,16 +309,39 @@ function* extractTargetsInner( yield [name, `#${anchor}`] } else if (child.type === 'comment') { const comment = (child.children as [RSTInlineNode])[0].value - const [, name = null, href = null] = - /^_([^:]+):\s+(.+)$/.exec(comment) ?? [] - // TODO: “_`name with backticks`: ...” - if (name !== null && href !== null) yield [name.toLocaleLowerCase(), href] + + { + // normal reference + const [, name = null, href = null] = + /^_([^:]+):\s+(.+)$/.exec(comment) ?? [] + // TODO: “_`name with backticks`: ...” + if (name !== null && href !== null) { + yield [name.toLocaleLowerCase(), href] + } + } + + { + // footnote reference + const [name, text] = parseCommentAsFootnote(comment) + if (name !== null && text !== null) { + const ref = `footnote-${name.toLocaleLowerCase()}` + yield [ref, `#${ref}`] + } + } } else if ('children' in child) { yield* extractTargetsInner(child) } } } +function parseCommentAsFootnote( + comment: string, +): [string | null, string | null] { + const [, name = null, text = null] = + /^\[([^\]]+)\]\s+(.+)$/.exec(comment) ?? [] + return [name, text] +} + const URL_SCHEMA = /^https?:.*$/ const ANCHOR_SCHEMA = /^#.*$/ diff --git a/src/components/markup/MarkupNodeComponent.tsx b/src/components/markup/MarkupNodeComponent.tsx index 815ecbf..c2106b1 100644 --- a/src/components/markup/MarkupNodeComponent.tsx +++ b/src/components/markup/MarkupNodeComponent.tsx @@ -112,7 +112,7 @@ const MarkupNodeComponentInner: FC = ({ node, level }) => { } case Type.EnumList: return ( -
    +
      {convertChildren(node, level)}
    ) @@ -168,6 +168,10 @@ const MarkupNodeComponentInner: FC = ({ node, level }) => { return {convertChildren(node, level)} case Type.Strong: return {convertChildren(node, level)} + case Type.Subscript: + return {convertChildren(node, level)} + case Type.Superscript: + return {convertChildren(node, level)} case Type.Link: { if ('name' in node.ref) throw new ASTError(`Unresolved reference ${node.ref.name}`, node) diff --git a/src/markup/MarkupDocument.ts b/src/markup/MarkupDocument.ts index eee6737..1f0c0df 100644 --- a/src/markup/MarkupDocument.ts +++ b/src/markup/MarkupDocument.ts @@ -24,6 +24,8 @@ export enum Type { LineBreak, Emph, Strong, + Subscript, + Superscript, Link, Code, InlineMath, @@ -101,6 +103,8 @@ export type Elem = | LineBreak | Emph | Strong + | Subscript + | Superscript | Link | Code | InlineMath @@ -192,6 +196,7 @@ export const BulletList = mkFun(Type.BulletList) export interface EnumList extends Element { type: Type.EnumList enumeration?: Enumeration + start?: number | undefined } export const EnumList = mkFun(Type.EnumList) export interface ListItem extends Element { @@ -263,6 +268,16 @@ export interface Strong extends Element { } export const Strong = mkFun(Type.Strong) +export interface Subscript extends Element { + type: Type.Subscript +} +export const Subscript = mkFun(Type.Subscript) + +export interface Superscript extends Element { + type: Type.Superscript +} +export const Superscript = mkFun(Type.Superscript) + export interface Link extends Element { type: Type.Link ref: { name: string } | { href: string } diff --git a/typings/restructured/index.d.ts b/typings/restructured/index.d.ts index 4534126..67af8b7 100644 --- a/typings/restructured/index.d.ts +++ b/typings/restructured/index.d.ts @@ -1,10 +1,17 @@ declare module 'restructured' { - export type InlineNodeType = 'text' | 'literal' | 'emphasis' | 'strong' + export type InlineNodeType = + | 'text' + | 'literal' + | 'emphasis' + | 'strong' + | 'subscript' + | 'superscript' export type BlockNodeType = | 'document' | 'section' | 'comment' | 'reference' + | 'footnote_reference' | 'title' | 'paragraph' | 'block_quote'