Skip to content

Commit 7579fd2

Browse files
committed
Social Image: render definition docs
1 parent 7184f89 commit 7579fd2

File tree

4 files changed

+397
-63
lines changed

4 files changed

+397
-63
lines changed

netlify/edge-functions/common/definition.ts

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,52 @@
1-
type SyntaxSegment = { annotation?: { tag: string }; segment: string };
2-
type DocElement = { annotation?: { tag: string }; segment: string };
1+
type SyntaxSegment = {
2+
annotation?: { tag: string };
3+
segment: string;
4+
};
5+
6+
type DocSpecial =
7+
| { tag: "Source"; contents: Array<SyntaxSegment> }
8+
| { tag: "Link"; contents: Array<SyntaxSegment> }
9+
| { tag: "Example"; contents: Array<SyntaxSegment> }
10+
| { tag: "ExampleBlock"; contents: Array<SyntaxSegment> }
11+
| { tag: "Signature"; contents: Array<Array<SyntaxSegment>> }
12+
| { tag: "SignatureInline"; contents: Array<SyntaxSegment> }
13+
| { tag: "Eval"; contents: [Array<SyntaxSegment>, Array<SyntaxSegment>] }
14+
| {
15+
tag: "EvalInline";
16+
contents: [Array<SyntaxSegment>, Array<SyntaxSegment>];
17+
}
18+
| { tag: "Embed"; contents: Array<SyntaxSegment> }
19+
| { tag: "EmbedInline"; contents: Array<SyntaxSegment> };
20+
21+
type DocElement =
22+
| { tag: "Word"; contents: string }
23+
| { tag: "NamedLink"; contents: [DocElement, DocElement] }
24+
| { tag: "Paragraph"; contents: Array<DocElement> }
25+
| { tag: "Special"; contents: DocSpecial }
26+
| { tag: "Span"; contents: Array<DocElement> }
27+
| { tag: "UntitledSection"; contents: Array<DocElement> }
28+
| { tag: "Section"; contents: [DocElement, Array<DocElement>] }
29+
| { tag: "BulletedList"; contents: Array<DocElement> }
30+
| { tag: "NumberedList"; contents: [Number, Array<DocElement>] }
31+
| { tag: "Code"; contents: Array<DocElement> }
32+
| { tag: "CodeBlock"; contents: [string, DocElement] }
33+
| { tag: "Group"; contents: DocElement }
34+
| { tag: "Join"; contents: Array<DocElement> }
35+
| { tag: "Column"; contents: Array<DocElement> }
36+
| { tag: "Image"; contents: [DocElement, DocElement, DocElement?] }
37+
| { tag: "Folded"; contents: [DocElement, DocElement] }
38+
| { tag: "Callout"; contents: [DocElement | null, DocElement] }
39+
| { tag: "Aside"; contents: DocElement }
40+
| { tag: "Tooltip"; contents: [DocElement, DocElement] }
41+
| { tag: "SectionBreak"; contents: [] }
42+
| { tag: "Blankline"; contents: [] }
43+
| { tag: "Anchor"; contents: [string, DocElement] }
44+
| { tag: "Style"; contents: [string, DocElement] }
45+
| { tag: "Blockqoute"; contents: DocElement }
46+
| { tag: "Italic"; contents: DocElement }
47+
| { tag: "Bold"; contents: DocElement }
48+
| { tag: "Strikethrough"; contents: DocElement }
49+
| { tag: "Table"; contents: Array<Array<DocElement>> };
350

451
type DefinitionSyntax = {
552
contents: Array<SyntaxSegment>;
@@ -11,7 +58,7 @@ type APITerm = {
1158
defnTermTag: string;
1259
signature: Array<SyntaxSegment>;
1360
termDefinition: DefinitionSyntax;
14-
termDocs: Array<DocElement>;
61+
termDocs: Array<[string, string, DocElement]>;
1562
};
1663

1764
type APIType = {
@@ -33,5 +80,6 @@ export {
3380
APITerm,
3481
APIType,
3582
APIDefinitions,
83+
DocSpecial,
3684
DocElement,
3785
};
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
import React from "https://esm.sh/[email protected]";
2+
import { DocSpecial, DocElement } from "../common/definition.ts";
3+
import * as Sizing from "../common/sizing.ts";
4+
import Colors from "../common/colors.ts";
5+
import { intersperse } from "../common/utils.ts";
6+
import { InlineSyntax, Syntax } from "./syntax.tsx";
7+
8+
function Docs(props: { docRoot: DocElement }) {
9+
function renderSectionContent(e: DocElement) {
10+
switch (e.tag) {
11+
case "Span":
12+
return <p style={STYLES.docBlock}>{go(e)}</p>;
13+
case "Paragraph":
14+
return <p style={STYLES.docBlock}>{go(e)}</p>;
15+
default:
16+
return go(e);
17+
}
18+
}
19+
20+
function go(e: DocElement) {
21+
console.log(e.tag);
22+
switch (e.tag) {
23+
case "Special":
24+
const special = e.contents as DocSpecial;
25+
switch (special.tag) {
26+
case "Source":
27+
return (
28+
<div style={STYLES.docCode}>
29+
<Syntax syntax={special.contents} />
30+
</div>
31+
);
32+
case "Link":
33+
return (
34+
<span style={{ ...STYLES.docCode, ...STYLES.docCodeInline }}>
35+
<InlineSyntax syntax={special.contents} />
36+
</span>
37+
);
38+
case "Example":
39+
return (
40+
<span style={{ ...STYLES.docCode, ...STYLES.docCodeInline }}>
41+
<InlineSyntax syntax={special.contents} />
42+
</span>
43+
);
44+
case "ExampleBlock":
45+
return (
46+
<div style={STYLES.docCode}>
47+
<Syntax syntax={special.contents} />
48+
</div>
49+
);
50+
case "EmbedInline":
51+
return (
52+
<span style={{ ...STYLES.docCode, ...STYLES.docCodeInline }}>
53+
<InlineSyntax syntax={special.contents} />
54+
</span>
55+
);
56+
case "Embed":
57+
return (
58+
<div style={STYLES.docCode}>
59+
<Syntax syntax={special.contents} />
60+
</div>
61+
);
62+
case "SignatureInline":
63+
return (
64+
<span style={{ ...STYLES.docCode, ...STYLES.docCodeInline }}>
65+
<InlineSyntax syntax={special.contents} />
66+
</span>
67+
);
68+
69+
/*
70+
| { tag: "Signature"; contents: Array<Array<SyntaxSegment>> }
71+
| { tag: "Eval"; contents: [Array<SyntaxSegment>, Array<SyntaxSegment>] }
72+
| {
73+
tag: "EvalInline";
74+
contents: [Array<SyntaxSegment>, Array<SyntaxSegment>];
75+
}
76+
*/
77+
78+
default:
79+
return <></>;
80+
}
81+
case "NamedLink":
82+
return <a style={STYLES.docLink}>{go(e.contents[0])}</a>;
83+
case "Word":
84+
return <span>{e.contents}</span>;
85+
case "Paragraph":
86+
return (
87+
<span style={STYLES.docInline}>
88+
{intersperse(
89+
(e.contents as Array<DocElement>).map(go),
90+
<span style={STYLES.docSpace}> </span>
91+
)}
92+
</span>
93+
);
94+
case "Span":
95+
return (
96+
<span style={STYLES.docInline}>
97+
{intersperse(
98+
(e.contents as Array<DocElement>).map(go),
99+
<span style={STYLES.docSpace}> </span>
100+
)}
101+
</span>
102+
);
103+
case "UntitledSection":
104+
return (
105+
<section style={STYLES.docBlock}>
106+
{(e.contents as Array<DocElement>).map(renderSectionContent)}
107+
</section>
108+
);
109+
case "Section":
110+
const [title, sectionContent] = e.contents as [
111+
DocElement,
112+
Array<DocElement>
113+
];
114+
115+
return (
116+
<section style={STYLES.docBlock}>
117+
<h1 style={STYLES.docBlock}>{go(title)}</h1>
118+
<div style={STYLES.docBlock}>
119+
{sectionContent.map(renderSectionContent)}
120+
</div>
121+
</section>
122+
);
123+
case "BulletedList":
124+
return (
125+
<ul style={STYLES.docList}>
126+
{(e.contents as Array<DocElement>).map((e) => (
127+
<li style={STYLES.docListItem}>
128+
<span style={STYLES.docListItemBullet}></span> {go(e)}
129+
</li>
130+
))}
131+
</ul>
132+
);
133+
case "NumberedList":
134+
const [start, els] = e.contents as [number, Array<DocElement>];
135+
return (
136+
<ol start={start} style={STYLES.docList}>
137+
{els.map((e, i) => (
138+
<li style={STYLES.docListItem}>
139+
<span style={STYLES.docListItemBullet}>{start + i}</span>{" "}
140+
{go(e)}
141+
</li>
142+
))}
143+
</ol>
144+
);
145+
case "Code":
146+
return (
147+
<code style={{ ...STYLES.docCode, ...STYLES.docCodeInline }}>
148+
{go(e.contents as DocElement)}
149+
</code>
150+
);
151+
case "Join":
152+
return (
153+
<span style={STYLES.docInline}>
154+
{(e.contents as Array<DocElement>).map(go)}
155+
</span>
156+
);
157+
case "Group":
158+
return (
159+
<span style={STYLES.docInline}>{go(e.contents as DocElement)}</span>
160+
);
161+
default:
162+
console.log("default", e.tag);
163+
if (Array.isArray(e.contents) && e.contents.length > 1) {
164+
return (
165+
<span>
166+
{intersperse(
167+
(e.contents as Array<DocElement>).map(go),
168+
<span style={{ width: "4ch" }}> </span>
169+
)}
170+
</span>
171+
);
172+
} else if (e.contents && typeof e.contents !== "string") {
173+
return go(e.contents as DocElement);
174+
} else {
175+
return <></>;
176+
}
177+
}
178+
}
179+
180+
const docs = go(props.docRoot);
181+
182+
return <section style={STYLES.docs}>{docs}</section>;
183+
}
184+
185+
const STYLES = {
186+
docs: {
187+
display: "flex",
188+
flexWrap: "wrap",
189+
flex: 1,
190+
width: "100%",
191+
marginTop: -300,
192+
background: "white",
193+
height: 300,
194+
fontSize: Sizing.toPx(2),
195+
gap: 0,
196+
paddingLeft: Sizing.toPx(3),
197+
paddingRight: Sizing.toPx(3),
198+
},
199+
docBlock: {
200+
display: "flex",
201+
flexWrap: "wrap",
202+
gap: 0,
203+
marginTop: 0,
204+
width: "100%",
205+
},
206+
docLink: {
207+
color: Colors.blue1,
208+
},
209+
docList: {
210+
display: "flex",
211+
flexWrap: "wrap",
212+
gap: Sizing.toPx(0.5),
213+
marginTop: 0,
214+
marginLeft: Sizing.toPx(1),
215+
width: "100%",
216+
},
217+
docListItem: {
218+
display: "flex",
219+
flexWrap: "wrap",
220+
gap: 0,
221+
marginTop: 0,
222+
width: "100%",
223+
listStyleType: "disc",
224+
},
225+
docListItemBullet: {
226+
marginRight: Sizing.toPx(1),
227+
},
228+
docInline: {},
229+
docSpace: {
230+
width: "8ch",
231+
},
232+
docCode: {
233+
fontFamily: "monospace",
234+
background: Colors.gray.lighten55,
235+
borderRadius: Sizing.toPx(0.25),
236+
paddingLeft: Sizing.toPx(0.5),
237+
paddingRight: Sizing.toPx(0.5),
238+
},
239+
docCodeInline: {},
240+
};
241+
242+
export default Docs;

0 commit comments

Comments
 (0)