Parse out frontmatter in markup documents.

This commit is contained in:
Dillon Kearns 2019-08-21 14:07:29 -07:00
parent 9e51a1419b
commit 412d500144
6 changed files with 153 additions and 79 deletions

View File

@ -8,12 +8,8 @@ import String.Interpolate exposing (interpolate)
port writeFile : port writeFile :
{ rawContent : String { watch : Bool
, routes : List String
, imageAssets : String
, watch : Bool
, debug : Bool , debug : Bool
, fileContents : List ( String, String )
} }
-> Cmd msg -> Cmd msg
@ -61,12 +57,6 @@ dropIndexFromLast path =
|> List.reverse |> List.reverse
allRoutes : List String -> List String
allRoutes paths =
paths
|> List.map prerenderRcFormattedPath
pathFor : { entry | path : String } -> String pathFor : { entry | path : String } -> String
pathFor page = pathFor page =
page.path page.path
@ -189,7 +179,7 @@ type alias Flags =
type alias Extras = type alias Extras =
{ content : List Page, markdownContent : List MarkdownContent, images : List String } {}
type alias Page = type alias Page =
@ -211,13 +201,8 @@ init flags cliOptions =
Build -> Build ->
( False, False ) ( False, False )
in in
{ rawContent = { watch = watch
generate flags.content flags.markdownContent
, routes = allRoutes (List.map .path flags.content ++ List.map .path flags.markdownContent)
, imageAssets = imageAssetsFile flags.images
, watch = watch
, debug = debug , debug = debug
, fileContents = generateFileContents flags.markdownContent
} }
|> writeFile |> writeFile
@ -233,23 +218,6 @@ generateFileContents markdownFiles =
) )
imageAssetsFile : List String -> String
imageAssetsFile images =
interpolate """export const imageAssets = {
{0}
};
"""
[ images |> List.map imageAssetEntry |> String.join ",\n " ]
imageAssetEntry : String -> String
imageAssetEntry string =
interpolate """"{0}": require("{1}")"""
[ string |> String.dropLeft 7
, "../../" ++ string
]
main : Program.StatelessProgram Never Extras main : Program.StatelessProgram Never Extras
main = main =
Program.stateless Program.stateless

View File

@ -3,8 +3,30 @@ const fs = require("fs");
const glob = require("glob"); const glob = require("glob");
const matter = require("gray-matter"); const matter = require("gray-matter");
const markupFrontmatterOptions = {
language: "markup",
engines: {
markup: {
parse: function(string) {
console.log("@@@@@@", string);
return string;
},
// example of throwing an error to let users know stringifying is
// not supported (a TOML stringifier might exist, this is just an example)
stringify: function(string) {
return string;
}
}
}
};
function unpackFile(filePath) { function unpackFile(filePath) {
const { content, data } = matter(fs.readFileSync(filePath).toString()); console.log("!!! 1");
const { content, data } = matter(
fs.readFileSync(filePath).toString(),
markupFrontmatterOptions
);
const baseRoute = filePath const baseRoute = filePath
.replace("content/", "") .replace("content/", "")

View File

@ -15,10 +15,9 @@ const imageminMozjpeg = require("imagemin-mozjpeg");
const express = require("express"); const express = require("express");
module.exports = { start, run }; module.exports = { start, run };
function start({ routes, debug, manifestConfig, fileContents }) { function start({ routes, debug, manifestConfig }) {
const config = webpackOptions(false, routes, { const config = webpackOptions(false, routes, {
debug, debug,
fileContents,
manifestConfig manifestConfig
}); });
@ -58,43 +57,39 @@ function start({ routes, debug, manifestConfig, fileContents }) {
// app.use(express.static(__dirname + "/path-to-static-folder")); // app.use(express.static(__dirname + "/path-to-static-folder"));
} }
function run({ routes, fileContents, manifestConfig }, callback) { function run({ routes, manifestConfig }, callback) {
webpack( webpack(webpackOptions(true, routes, { debug: false, manifestConfig })).run(
webpackOptions(true, routes, { debug: false, fileContents, manifestConfig }) (err, stats) => {
).run((err, stats) => { if (err) {
if (err) { console.error(err);
console.error(err); process.exit(1);
process.exit(1); } else {
} else { callback();
callback(); }
}
console.log( console.log(
stats.toString({ stats.toString({
chunks: false, // Makes the build much quieter chunks: false, // Makes the build much quieter
colors: true, // Shows colors in the console colors: true, // Shows colors in the console
// copied from `'minimal'` // copied from `'minimal'`
all: false, all: false,
modules: false, modules: false,
performance: true, performance: true,
timings: true, timings: true,
outputPath: true, outputPath: true,
maxModules: 0, maxModules: 0,
errors: true, errors: true,
warnings: true, warnings: true,
// our additional options // our additional options
moduleTrace: false, moduleTrace: false,
errorDetails: false errorDetails: false
}) })
); );
}); }
);
} }
function webpackOptions( function webpackOptions(production, routes, { debug, manifestConfig }) {
production,
routes,
{ debug, fileContents, manifestConfig }
) {
const common = { const common = {
entry: { hello: "./index.js" }, entry: { hello: "./index.js" },
mode: production ? "production" : "development", mode: production ? "production" : "development",

View File

@ -11,6 +11,7 @@ const runElm = require("./compile-elm.js");
const doCliStuff = require("./generate-elm-stuff.js"); const doCliStuff = require("./generate-elm-stuff.js");
const { elmPagesUiFile } = require("./elm-file-constants.js"); const { elmPagesUiFile } = require("./elm-file-constants.js");
const generateRecords = require("./generate-records.js"); const generateRecords = require("./generate-records.js");
const generateRawContent = require("./generate-raw-content.js");
const contentGlobPath = "content/**/*.emu"; const contentGlobPath = "content/**/*.emu";
@ -21,14 +22,42 @@ function unpackFile(path) {
return { path, contents: fs.readFileSync(path).toString() }; return { path, contents: fs.readFileSync(path).toString() };
} }
const markupFrontmatterOptions = {
language: "markup",
engines: {
markup: {
parse: function(string) {
console.log("@@@@@@", string);
return string;
},
// example of throwing an error to let users know stringifying is
// not supported (a TOML stringifier might exist, this is just an example)
stringify: function(string) {
return string;
}
}
}
};
function unpackMarkup(path) {
console.log("!!! 2");
const separated = matter(
fs.readFileSync(path).toString(),
markupFrontmatterOptions
);
return { path, metadata: separated.matter, body: separated.content };
}
function parseMarkdown(path, fileContents) { function parseMarkdown(path, fileContents) {
const { content, data } = matter(fileContents); console.log("!!! 3");
const { content, data } = matter(fileContents, markupFrontmatterOptions);
return { path, metadata: JSON.stringify(data), body: content }; return { path, metadata: JSON.stringify(data), body: content };
} }
function run() { function run() {
console.log("Running elm-pages..."); console.log("Running elm-pages...");
const content = glob.sync(contentGlobPath, {}).map(unpackFile); const content = glob.sync(contentGlobPath, {}).map(unpackMarkup);
const staticRoutes = generateRecords(); const staticRoutes = generateRecords();
const markdownContent = glob const markdownContent = glob
@ -62,10 +91,12 @@ function run() {
}); });
app.ports.writeFile.subscribe(contents => { app.ports.writeFile.subscribe(contents => {
fs.writeFileSync("./gen/RawContent.elm", contents.rawContent); const rawContent = generateRawContent(markdownContent, content);
fs.writeFileSync("./gen/RawContent.elm", rawContent);
fs.writeFileSync("./gen/PagesNew.elm", elmPagesUiFile(staticRoutes)); fs.writeFileSync("./gen/PagesNew.elm", elmPagesUiFile(staticRoutes));
console.log("elm-pages DONE"); console.log("elm-pages DONE");
doCliStuff(staticRoutes, contents.rawContent, function(manifestConfig) { doCliStuff(staticRoutes, rawContent, function(manifestConfig) {
if (contents.watch) { if (contents.watch) {
startWatchIfNeeded(); startWatchIfNeeded();
if (!devServerRunning) { if (!devServerRunning) {
@ -73,7 +104,6 @@ function run() {
develop.start({ develop.start({
routes: contents.routes, routes: contents.routes,
debug: contents.debug, debug: contents.debug,
fileContents: contents.fileContents,
manifestConfig manifestConfig
}); });
} }
@ -81,7 +111,6 @@ function run() {
develop.run( develop.run(
{ {
routes: contents.routes, routes: contents.routes,
fileContents: contents.fileContents,
manifestConfig manifestConfig
}, },
() => {} () => {}

View File

@ -0,0 +1,37 @@
module.exports = function(markdown, markup) {
return `module RawContent exposing (content)
import Dict exposing (Dict)
content : { markdown : List ( List String, { frontMatter : String, body : Maybe String } ), markup : List ( List String, { frontMatter : String, body : Maybe String } ) }
content =
{ markdown = markdown, markup = markup }
markdown : List ( List String, { frontMatter : String, body : Maybe String } )
markdown =
[ ${markdown.map(toEntry)}
]
markup : List ( List String, { frontMatter : String, body : Maybe String } )
markup =
[ ${markup.map(toEntry)}
]`;
};
function toEntry(entry) {
let fullPath = entry.path
.replace(/(index)?\.[^/.]+$/, "")
.split("/")
.filter(item => item !== "")
.map(fragment => `"${fragment}"`);
fullPath.splice(0, 1);
return `
( [${fullPath.join(", ")}]
, { frontMatter = """${entry.metadata}
""", body = Nothing } )
`;
}

View File

@ -17,11 +17,34 @@ function scan() {
return content; return content;
} }
const markupFrontmatterOptions = {
language: "markup",
engines: {
markup: {
parse: function(string) {
console.log("@@@@@@ 3", string);
return string;
},
// example of throwing an error to let users know stringifying is
// not supported (a TOML stringifier might exist, this is just an example)
stringify: function(string) {
return string;
}
}
}
};
function unpackFile() { function unpackFile() {
return filepath => { return filepath => {
const fullPath = filepath; const fullPath = filepath;
console.log("@$@$@$@ filepath", filepath);
var relative = filepath.slice(dir.length); var relative = filepath.slice(dir.length);
const foundMetadata = matter(fs.readFileSync(fullPath).toString());
const foundMetadata =
path.extname(filepath) === ".emu"
? matter(fs.readFileSync(fullPath).toString(), markupFrontmatterOptions)
: matter(fs.readFileSync(fullPath).toString());
const metadata = { const metadata = {
path: relative, path: relative,