Skip to content

Commit

Permalink
🔨 assume sources fields are markdown instead of HTML
Browse files Browse the repository at this point in the history
  • Loading branch information
danyx23 committed Sep 19, 2023
1 parent 94ab7e3 commit 0fdc2f8
Show file tree
Hide file tree
Showing 4 changed files with 185 additions and 185 deletions.
64 changes: 30 additions & 34 deletions packages/@ourworldindata/grapher/src/sourcesTab/SourcesTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
Bounds,
DEFAULT_BOUNDS,
MarkdownTextWrap,
linkify,
OwidOrigin,
uniq,
excludeNullish,
Expand All @@ -14,9 +13,6 @@ import { faPencilAlt } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome/index.js"
import { CoreColumn, OwidColumnDef } from "@ourworldindata/core-table"

const formatText = (s: string): string =>
linkify(s).replace(/(?:\r\n|\r|\n)/g, "<br/>")

export interface SourcesTabManager {
adminBaseUrl?: string
columnsWithSources: CoreColumn[]
Expand Down Expand Up @@ -110,11 +106,12 @@ export class SourcesTab extends React.Component<{
// metadata V2 shortDescription
<tr>
<td>Variable description</td>
<td
dangerouslySetInnerHTML={{
__html: formatText(column.description),
}}
/>
<td>
<MarkdownTextWrap
text={column.description}
fontSize={12}
/>
</td>
</tr>
) : null}
{coverage ? (
Expand Down Expand Up @@ -162,35 +159,34 @@ export class SourcesTab extends React.Component<{
source.dataPublishedBy ? (
<tr>
<td>Data published by</td>
<td
dangerouslySetInnerHTML={{
__html: formatText(
source.dataPublishedBy
),
}}
/>
<td>
<MarkdownTextWrap
text={source.dataPublishedBy}
fontSize={12}
/>
</td>
</tr>
) : null}
{source.dataPublisherSource ? (
<tr>
<td>Data publisher's source</td>
<td
dangerouslySetInnerHTML={{
__html: formatText(
source.dataPublisherSource
),
}}
/>
<td>
<MarkdownTextWrap
text={source.dataPublisherSource}
fontSize={12}
/>
</td>
</tr>
) : null}
{source.link ? (
<tr>
<td>Link</td>
<td
dangerouslySetInnerHTML={{
__html: formatText(source.link),
}}
/>
<td>
<MarkdownTextWrap
text={source.link}
fontSize={12}
/>
</td>
</tr>
) : null}
{retrievedDate ? (
Expand All @@ -202,12 +198,12 @@ export class SourcesTab extends React.Component<{
</tbody>
</table>
{source.additionalInfo && (
<p
key={"additionalInfo"}
dangerouslySetInnerHTML={{
__html: formatText(source.additionalInfo),
}}
/>
<p key={"additionalInfo"}>
<MarkdownTextWrap
text={source.additionalInfo}
fontSize={12}
/>
</p>
)}
</div>
)
Expand Down
154 changes: 153 additions & 1 deletion packages/@ourworldindata/utils/src/GdocsUtils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { spansToUnformattedPlainText } from "./Util.js"
import { gdocUrlRegex } from "./GdocsConstants.js"
import { OwidGdocLinkJSON, Span } from "./owidTypes.js"
import { EnrichedBlockText, OwidGdocLinkJSON, Span } from "./owidTypes.js"
import { Url } from "./urls/Url.js"
import urlSlug from "url-slug"
import {
EveryMarkdownNode,
MarkdownRoot,
mdParser,
} from "./MarkdownTextWrap/parser.js"
import { P, match } from "ts-pattern"

export function getLinkType(urlString: string): OwidGdocLinkJSON["linkType"] {
const url = Url.fromURL(urlString)
Expand Down Expand Up @@ -40,3 +46,149 @@ export function getUrlTarget(urlString: string): string {
export function convertHeadingTextToId(headingText: Span[]): string {
return urlSlug(spansToUnformattedPlainText(headingText))
}

const convertMarkdownNodeToSpan = (node: EveryMarkdownNode): Span[] => {
return match(node)
.with(
{
type: "text",
},
(n) => [
{
spanType: "span-simple-text" as const,
text: n.value,
} as Span,
]
)
.with(
{
type: "textSegments",
},
(n) => n.children.flatMap(convertMarkdownNodeToSpan) as Span[]
)
.with(
{
type: "newline",
},
() => [
{
spanType: "span-simple-text" as const,
text: "\n",
} as Span,
]
)
.with(
{
type: "whitespace",
},
() => [
{
spanType: "span-simple-text" as const,
text: " ",
} as Span,
]
)
.with(
{
type: "detailOnDemand",
},
(n) => [
{
spanType: "span-dod" as const,
id: n.term,
children: n.children.flatMap(convertMarkdownNodeToSpan),
} as Span,
]
)
.with(
{
type: "markdownLink",
},
(n) => [
{
spanType: "span-link" as const,
url: n.href,
children: n.children.flatMap(convertMarkdownNodeToSpan),
} as Span,
]
)
.with(
{
type: "plainUrl",
},
(n) => [
{
spanType: "span-link" as const,
url: n.href,
children: [
{
spanType: "span-simple-text" as const,
text: n.href,
},
],
} as Span,
]
)
.with(
{
type: "bold",
},
(n) => [
{
spanType: "span-bold" as const,
children: n.children.flatMap(convertMarkdownNodeToSpan),
} as Span,
]
)
.with(
{
type: P.union("italic", "plainItalic", "italicWithoutBold"),
},
(n) => [
{
spanType: "span-italic" as const,
children: n.children.flatMap(convertMarkdownNodeToSpan),
} as Span,
]
)
.with(
{
type: P.union("bold", "plainBold", "boldWithoutItalic"),
},
(n) => [
{
spanType: "span-bold" as const,
children: n.children.flatMap(convertMarkdownNodeToSpan),
} as Span,
]
)
.exhaustive()
//.otherwise(() => ({ spanType: "span-simple-text" as const, text: "" }))
}

const convertMarkdownNodesToSpans = (nodes: MarkdownRoot) =>
nodes.children.flatMap(convertMarkdownNodeToSpan)

export const markdownToEnrichedTextBlock = (
markdown: string
): EnrichedBlockText => {
const parsedMarkdown = mdParser.markdown.parse(markdown)
if (parsedMarkdown.status) {
const spans = convertMarkdownNodesToSpans(parsedMarkdown.value)
return {
type: "text",
value: spans,
parseErrors: [],
}
} else
return {
type: "text",
value: [],
parseErrors: [
{
message: `Failed to parse markdown - expected ${parsedMarkdown.expected} at ${parsedMarkdown.index}`,
isWarning: false,
},
],
}
}
1 change: 1 addition & 0 deletions packages/@ourworldindata/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ export {
getUrlTarget,
checkIsInternalLink,
convertHeadingTextToId,
markdownToEnrichedTextBlock,
} from "./GdocsUtils.js"

export {
Expand Down
Loading

0 comments on commit 0fdc2f8

Please sign in to comment.