[examples/openspending] - openspending v0.2 (#907)

* [examples/openspending] - openspending v0.2

* [examples/openspending][m] - fix build

* [examples/openspending][xs] - fix build

* [examples/openspending][xs] - add prebuild step

* [examples/openspending][m] - fix requested by demenech

* [examples/openspending][sm] - remove links + fix bug
This commit is contained in:
Luccas Mateus
2023-05-30 20:22:58 -03:00
committed by GitHub
parent cb7d801968
commit 14974edcbf
474 changed files with 25289 additions and 116 deletions

View File

@@ -0,0 +1,111 @@
// This file is a temporary replacement for legacy contentlayer's computeFields + default fields values
import { remark } from "remark";
import stripMarkdown, { Options } from "strip-markdown";
import { defaultConfig as siteConfig } from '@flowershow/core'
// TODO return type
const sluggify = (urlPath: string) => {
return urlPath.replace(/^(.+?\/)*/, "");
};
const computeFields = async ({
frontMatter,
urlPath,
filePath,
source,
}: {
frontMatter: Record<string, any>;
urlPath: string;
filePath: string;
source: string;
}) => {
// Fields with corresponding config options
// TODO see _app.tsx
const showEditLink =
frontMatter.showEditLink ?? siteConfig.showEditLink ?? false;
// TODO take config into accout
const showLinkPreviews =
frontMatter.showLinkPreviews ?? siteConfig.showLinkPreviews ?? false;
const showToc = frontMatter.showToc ?? siteConfig.showToc ?? false;
const showSidebar =
frontMatter.showSidebar ?? siteConfig.showSidebar ?? false;
// Computed fields
// const title = frontMatter.title ?? (await extractTitle(source));
const title = frontMatter.title ?? null;
const description =
frontMatter.description ?? (await extractDescription(source));
const date = frontMatter.date ?? frontMatter.created ?? null;
const layout = (() => {
if (frontMatter.layout) return frontMatter.layout;
if (urlPath.startsWith("blog/")) return "blog";
// if (urlPath.startsWith("docs/")) return "docs";
return "docs"; // TODO default layout from config?
})();
// TODO Temporary, should probably be a column in the database
const slug = sluggify(urlPath);
// TODO take into accout include/exclude fields in config
const isDraft = frontMatter.isDraft ?? false;
return {
...frontMatter,
title,
description,
date,
layout,
slug,
urlPath, // extra for blogs index page; temporary here
isDraft,
showEditLink,
showLinkPreviews,
showToc,
showSidebar,
};
};
const extractTitle = async (source: string) => {
const heading = source.trim().match(/^#\s+(.*)/);
if (heading) {
const title = heading[1]
// replace wikilink with only text value
.replace(/\[\[([\S]*?)]]/, "$1");
const stripTitle = await remark().use(stripMarkdown).process(title);
return stripTitle.toString().trim();
}
return null;
};
const extractDescription = async (source: string) => {
const content = source
// remove commented lines
.replace(/{\/\*.*\*\/}/g, "")
// remove import statements
.replace(
/^import\s*(?:\{\s*[\w\s,\n]+\s*\})?(\s*(\w+))?\s*from\s*("|')[^"]+("|');?$/gm,
""
)
// remove youtube links
.replace(/^(https?:\/\/)?(www\.)?(youtube\.com|youtu\.?be)\/.+$/gm, "")
// replace wikilinks with only text
.replace(/([^!])\[\[(\S*?)\]]/g, "$1$2")
// remove wikilink images
.replace(/!\[[\S]*?]]/g, "");
// remove markdown formatting
const stripped = await remark()
.use(stripMarkdown, {
remove: ["heading", "blockquote", "list", "image", "html", "code"],
} as Options)
.process(content);
if (stripped.value) {
const description: string = stripped.value.toString().slice(0, 200);
return description + "...";
}
return null;
};
export default computeFields;

View File

@@ -0,0 +1,105 @@
import matter from "gray-matter";
import mdxmermaid from "mdx-mermaid";
import { h } from "hastscript";
import remarkCallouts from "@flowershow/remark-callouts";
import remarkEmbed from "@flowershow/remark-embed";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import remarkSmartypants from "remark-smartypants";
import remarkToc from "remark-toc";
import remarkWikiLink from "@flowershow/remark-wiki-link";
import rehypeAutolinkHeadings from "rehype-autolink-headings";
import rehypeKatex from "rehype-katex";
import rehypeSlug from "rehype-slug";
import rehypePrismPlus from "rehype-prism-plus";
import { serialize } from "next-mdx-remote/serialize";
/**
* Parse a markdown or MDX file to an MDX source form + front matter data
*
* @source: the contents of a markdown or mdx file
* @format: used to indicate to next-mdx-remote which format to use (md or mdx)
* @returns: { mdxSource: mdxSource, frontMatter: ...}
*/
const parse = async function (source, format, scope) {
const { content, data, excerpt } = matter(source, {
excerpt: (file, options) => {
// Generate an excerpt for the file
file.excerpt = file.content.split("\n\n")[0];
},
});
const mdxSource = await serialize(
{ value: content, path: format },
{
// Optionally pass remark/rehype plugins
mdxOptions: {
remarkPlugins: [
remarkEmbed,
remarkGfm,
[remarkSmartypants, { quotes: false, dashes: "oldschool" }],
remarkMath,
remarkCallouts,
remarkWikiLink,
[
remarkToc,
{
heading: "Table of contents",
tight: true,
},
],
[mdxmermaid, {}],
],
rehypePlugins: [
rehypeSlug,
[
rehypeAutolinkHeadings,
{
properties: { className: 'heading-link' },
test(element) {
return (
["h2", "h3", "h4", "h5", "h6"].includes(element.tagName) &&
element.properties?.id !== "table-of-contents" &&
element.properties?.className !== "blockquote-heading"
);
},
content() {
return [
h(
"svg",
{
xmlns: "http:www.w3.org/2000/svg",
fill: "#ab2b65",
viewBox: "0 0 20 20",
className: "w-5 h-5",
},
[
h("path", {
fillRule: "evenodd",
clipRule: "evenodd",
d: "M9.493 2.853a.75.75 0 00-1.486-.205L7.545 6H4.198a.75.75 0 000 1.5h3.14l-.69 5H3.302a.75.75 0 000 1.5h3.14l-.435 3.148a.75.75 0 001.486.205L7.955 14h2.986l-.434 3.148a.75.75 0 001.486.205L12.456 14h3.346a.75.75 0 000-1.5h-3.14l.69-5h3.346a.75.75 0 000-1.5h-3.14l.435-3.147a.75.75 0 00-1.486-.205L12.045 6H9.059l.434-3.147zM8.852 7.5l-.69 5h2.986l.69-5H8.852z",
}),
]
),
];
},
},
],
[rehypeKatex, { output: "mathml" }],
[rehypePrismPlus, { ignoreMissing: true }],
],
format,
},
scope,
}
);
return {
mdxSource: mdxSource,
frontMatter: data,
excerpt,
};
};
export default parse;

View File

@@ -0,0 +1,24 @@
import { MarkdownDB } from "@flowershow/markdowndb";
// import config from "./markdowndb.config.js";
// TODO get this path from markdowndb.config.js or something
const dbPath = "markdown.db";
//
// if (!config.dbPath)
// throw new Error("Invalid/Missing path in markdowndb.config.js");
// }
//
// const dbPath = config.dbPath;
// OR
// const dbOptions = config.dbOptions;
const client = new MarkdownDB({
client: "sqlite3",
connection: {
filename: dbPath,
},
});
const clientPromise = client.init();
export default clientPromise;