Skip to content

Commit

Permalink
Social Image: render definition docs
Browse files Browse the repository at this point in the history
  • Loading branch information
hojberg committed Jun 21, 2024
1 parent 7184f89 commit 168c425
Show file tree
Hide file tree
Showing 4 changed files with 318 additions and 63 deletions.
27 changes: 24 additions & 3 deletions netlify/edge-functions/common/definition.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
type SyntaxSegment = { annotation?: { tag: string }; segment: string };
type DocElement = { annotation?: { tag: string }; segment: string };
type SyntaxSegment = {
annotation?: { tag: string };
segment: string;
};

type DocSpecial = { tag: "Link"; contents: Array<SyntaxSegment> };

type DocElement =
| { tag: "Word"; contents: string }
| { tag: "NamedLink"; contents: [DocElement, DocElement] }
| { tag: "Paragraph"; contents: Array<DocElement> }
| { tag: "Special"; contents: DocSpecial }
| { tag: "Span"; contents: Array<DocElement> }
| { tag: "UntitledSection"; contents: Array<DocElement> }
| { tag: "Section"; contents: [DocElement, Array<DocElement>] }
| { tag: "BulletedList"; contents: Array<DocElement> }
| { tag: "NumberedList"; contents: [Number, Array<DocElement>] }
| { tag: "Code"; contents: Array<DocElement> }
| { tag: "CodeBlock"; contents: [string, DocElement] }
| { tag: "Group"; contents: DocElement }
| { tag: "Join"; contents: Array<DocElement> }
| { tag: string; contents: Array<DocElement> | DocElement };

type DefinitionSyntax = {
contents: Array<SyntaxSegment>;
Expand All @@ -11,7 +31,7 @@ type APITerm = {
defnTermTag: string;
signature: Array<SyntaxSegment>;
termDefinition: DefinitionSyntax;
termDocs: Array<DocElement>;
termDocs: Array<[string, string, DocElement]>;
};

type APIType = {
Expand All @@ -33,5 +53,6 @@ export {
APITerm,
APIType,
APIDefinitions,
DocSpecial,
DocElement,
};
190 changes: 190 additions & 0 deletions netlify/edge-functions/social-image-helpers/docs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import React from "https://esm.sh/[email protected]";
import { DocSpecial, DocElement } from "../common/definition.ts";
import * as Sizing from "../common/sizing.ts";
import Colors from "../common/colors.ts";
import { intersperse } from "../common/utils.ts";
import { InlineSyntax } from "./syntax.tsx";

function Docs(props: { docRoot: DocElement }) {
function renderSectionContent(e: DocElement) {
switch (e.tag) {
case "Span":
return <p style={STYLES.docBlock}>{go(e)}</p>;
case "Paragraph":
return <p style={STYLES.docBlock}>{go(e)}</p>;
default:
return go(e);
}
}

function go(e: DocElement) {
console.log(e.tag);
switch (e.tag) {
case "Special":
const special = e.contents as DocSpecial;
switch (special.tag) {
case "Link":
return (
<span style={{ ...STYLES.docCode, ...STYLES.docCodeInline }}>
<InlineSyntax syntax={special.contents} />
</span>
);
}
case "NamedLink":
return <a style={STYLES.docLink}>{go(e.contents[0])}</a>;
case "Word":
return <span>{e.contents}</span>;
case "Paragraph":
return (
<span style={STYLES.docInline}>
{intersperse(
(e.contents as Array<DocElement>).map(go),
<span style={STYLES.docSpace}> </span>
)}
</span>
);
case "Span":
return (
<span style={STYLES.docInline}>
{intersperse(
(e.contents as Array<DocElement>).map(go),
<span style={STYLES.docSpace}> </span>
)}
</span>
);
case "UntitledSection":
return (
<section style={STYLES.docBlock}>
{(e.contents as Array<DocElement>).map(renderSectionContent)}
</section>
);
case "Section":
const [title, sectionContent] = e.contents as [
DocElement,
Array<DocElement>
];

return (
<section style={STYLES.docBlock}>
<h1 style={STYLES.docBlock}>{go(title)}</h1>
<div style={STYLES.docBlock}>
{sectionContent.map(renderSectionContent)}
</div>
</section>
);
case "BulletedList":
return (
<ul style={STYLES.docList}>
{(e.contents as Array<DocElement>).map((e) => (
<li style={STYLES.docListItem}>
<span style={STYLES.docListItemBullet}></span> {go(e)}
</li>
))}
</ul>
);
case "NumberedList":
const [start, els] = e.contents as [number, Array<DocElement>];
return (
<ol start={start} style={STYLES.docList}>
{els.map((e, i) => (
<li style={STYLES.docListItem}>
<span style={STYLES.docListItemBullet}>{start + i}</span>{" "}
{go(e)}
</li>
))}
</ol>
);
case "Code":
return (
<code style={{ ...STYLES.docCode, ...STYLES.docCodeInline }}>
{go(e.contents as DocElement)}
</code>
);
case "Join":
<span style={STYLES.docInline}>
{(e.contents as Array<DocElement>).map(go)}
</span>;
case "Group":
<span style={STYLES.docInline}>{go(e.contents as DocElement)}</span>;
default:
console.log("default", e.tag);
if (Array.isArray(e.contents) && e.contents.length > 1) {
return (
<span>
{intersperse(
(e.contents as Array<DocElement>).map(go),
<span style={{ width: "4ch" }}> </span>
)}
</span>
);
} else if (e.contents && typeof e.contents !== "string") {
return go(e.contents as DocElement);
} else {
return <></>;
}
}
}

const docs = go(props.docRoot);

return <section style={STYLES.docs}>{docs}</section>;
}

const STYLES = {
docs: {
display: "flex",
flexWrap: "wrap",
flex: 1,
width: "100%",
marginTop: -300,
background: "white",
height: 300,
fontSize: Sizing.toPx(2),
gap: 0,
paddingLeft: Sizing.toPx(3),
paddingRight: Sizing.toPx(3),
},
docBlock: {
display: "flex",
flexWrap: "wrap",
gap: 0,
marginTop: 0,
width: "100%",
},
docLink: {
color: Colors.blue1,
},
docList: {
display: "flex",
flexWrap: "wrap",
gap: Sizing.toPx(0.5),
marginTop: 0,
marginLeft: Sizing.toPx(1),
width: "100%",
},
docListItem: {
display: "flex",
flexWrap: "wrap",
gap: 0,
marginTop: 0,
width: "100%",
listStyleType: "disc",
},
docListItemBullet: {
marginRight: Sizing.toPx(1),
},
docInline: {},
docSpace: {
width: "8ch",
},
docCode: {
fontFamily: "monospace",
background: Colors.gray.lighten55,
borderRadius: Sizing.toPx(0.25),
paddingLeft: Sizing.toPx(0.5),
paddingRight: Sizing.toPx(0.5),
},
docCodeInline: {},
};

export default Docs;
Original file line number Diff line number Diff line change
@@ -1,32 +1,18 @@
import React from "https://esm.sh/[email protected]";
import { ShareAPI, SyntaxSegment } from "../common/share-api.ts";
import { ShareAPI } from "../common/share-api.ts";
import { DocSpecial, SyntaxSegment, DocElement } from "../common/definition.ts";
import Docs from "./docs.tsx";
import { Syntax } from "./syntax.tsx";
import { defaultSocialImage } from "./social-content.tsx";
import * as Sizing from "../common/sizing.ts";
import { Icon, IconType } from "./icon.tsx";
import Colors from "../common/colors.ts";
import SocialImageWithSheet from "./social-image-with-sheet.tsx";
import SocialImageWithLargeSheet from "./social-image-with-large-sheet.tsx";
import Sheet from "./sheet.tsx";
import { titleize, hash } from "../common/utils.ts";
import Tag from "./tag.tsx";

function Syntax(props: { syntax: Array<SyntaxSegment> }) {
const segments = props.syntax.map((seg) => {
const annotationStyle = STYLES[seg.annotation?.tag] || {};
const style = {
...STYLES.segment,
...annotationStyle,
};
return <span style={style}>{seg.segment}</span>;
});

return (
<pre style={STYLES.syntax}>
<code>{segments}</code>
<span style={STYLES.syntaxFade}></span>
</pre>
);
}

async function projectDefinitionSocialImage(
handle: string,
projectSlug: string,
Expand Down Expand Up @@ -66,6 +52,7 @@ async function projectDefinitionSocialImage(
category: raw.defnTermeTag,
signature: raw.signature,
definition: raw.termDefinition,
docs: raw.termDocs,
};
}
} else {
Expand All @@ -77,6 +64,7 @@ async function projectDefinitionSocialImage(
name: raw.bestTypeName,
category: raw.defnTypeTag,
definition: raw.typeDefinition,
docs: raw.typeDocs,
};
}
}
Expand Down Expand Up @@ -149,15 +137,23 @@ async function projectDefinitionSocialImage(
topRowRight = [];
}

const docs =
definition.docs[0] && definition.docs[0][2] ? (
<Docs docRoot={definition.docs[0][2]} />
) : null;

const Wrapper = docs ? SocialImageWithLargeSheet : SocialImageWithSheet;

return (
<SocialImageWithSheet>
<Wrapper>
<Sheet
title={definition.name}
topRowLeft={[projectRef, branchRef_]}
topRowRight={topRowRight}
bottomRowLeft={syntax}
/>
</SocialImageWithSheet>
{docs}
</Wrapper>
);
}

Expand All @@ -184,45 +180,6 @@ const STYLES = {
flexDirection: "column",
gap: Sizing.toPx(0.5),
},
syntax: {
position: "relative",
margin: 0,
padding: 0,
fontSize: Sizing.toPx(2),
lineHeight: 1.2,
width: "100%",
},
syntaxFade: {
position: "absolute",
top: -10,
right: `-${Sizing.toPx(2.5)}px`,
bottom: -10,
width: 400,
height: Sizing.toPx(4),
background: `linear-gradient(to right, rgba(255, 255, 255, 0), ${Colors.gray.lighten100}, ${Colors.gray.lighten100})`,
},
segment: {
color: Colors.gray.base,
fontFamily: "FiraCode",
},
DataTypeKeyword: {
color: Colors.gray.lighten30,
},
TypeAscriptionColon: {
color: Colors.gray.lighten30,
},
DataTypeModifier: {
color: Colors.gray.lighten30,
},
TypeOperator: {
color: Colors.gray.lighten30,
},
AbilityBraces: {
color: Colors.gray.lighten30,
},
DelimiterChar: {
color: Colors.gray.lighten30,
},
};

export default projectDefinitionSocialImage;
Loading

0 comments on commit 168c425

Please sign in to comment.