Skip to content

Commit

Permalink
Remove option and fix renderFile errors on serve
Browse files Browse the repository at this point in the history
  • Loading branch information
vrugtehagel committed Jul 19, 2024
1 parent 53a78e8 commit bfbdb10
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 58 deletions.
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vrugtehagel/eleventy-document-outline",
"version": "0.1.4",
"version": "0.1.5",
"exports": "./mod.ts",
"publish": {
"include": ["src/**", "mod.ts", "README.md"]
Expand Down
37 changes: 7 additions & 30 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import fs from "node:fs/promises";
import { RenderPlugin } from "npm:@11ty/eleventy@^3.0.0-alpha.15";
import * as HTMLParser from "npm:node-html-parser@^6.1";
import type { EleventyDocumentOutlineOptions } from "./options.ts";
import { findHeaders } from "./find-headers.ts";
Expand All @@ -8,27 +6,14 @@ import { renderTemplate } from "./render-template.ts";
/** The Eleventy config object, should be a better type than "any" but alas */
type EleventyConfig = any;

/** We wrap the RenderPlugin with our own function, so Eleventy sees it as a
* different plugin. We also rename the shortcodes so that users are not
* bothered by the addition of the plugin under the hood. */
function RenderPluginForEleventyDocumentOutline(config: EleventyConfig) {
return RenderPlugin(config, {
tagName: null,
tagNameFile: "eleventyDocumentOutlineRender",
accessGlobalData: true,
});
}

/** The main plugin. Add this with `eleventyConfig.addPlugin(…);` Options are
* all optional - see the `EleventyDocumentOutlineOptions` type for more
* information. */
export function EleventyDocumentOutline(
config: EleventyConfig,
options: EleventyDocumentOutlineOptions = {},
) {
/** We need this for the shortcode. If it already exists, then adding it
* again is fine and does nothing. */
config.addPlugin(RenderPluginForEleventyDocumentOutline);
config.versionCheck(">=3.0.0-alpha.15");

const {
headers: defaultSelector = "h1,h2,h3",
Expand All @@ -44,7 +29,6 @@ export function EleventyDocumentOutline(
},
mode: defaultMode = "optin",
slugify = config.getFilter("slugify"),
tmpDir = "tmpDirEleventyDocumentOutline",
} = options;

const memory = new Map<string, {
Expand Down Expand Up @@ -108,8 +92,9 @@ export function EleventyDocumentOutline(
): Promise<string> {
const root = HTMLParser.parse(content);
const { headers } = findHeaders(root, selector, "optin", slugify);
const data = { headers };
return await renderTemplate.call(this, config, template, tmpDir, data);
const { page, eleventy } = this;
const data = { headers, page, eleventy };
return await renderTemplate(template, data);
});

/** If we have shortcodes, then we process HTML files, find UUIDs inside them
Expand All @@ -135,10 +120,10 @@ export function EleventyDocumentOutline(
headers,
markupChanged,
} = findHeaders(root, selector, mode, slugify);
const data = { headers };
const { page, eleventy } = this;
const data = { headers, page, eleventy };
alteredParsedHTML ||= markupChanged;
const rendered = await renderTemplate
.call(this, config, template, tmpDir, data);
const rendered = await renderTemplate(template, data);
replacements.set(uuid, rendered);
}));
let result = alteredParsedHTML ? root.toString() : content;
Expand All @@ -147,12 +132,4 @@ export function EleventyDocumentOutline(
}
return result;
});

/** This may not run if the build fails for some reason or another, but it
* should be okay since we use the same `tmpDir` on subsequent runs. In other
* words, the next successful run will delete the temporary directory
* properly. */
config.events.addListener("eleventy.after", async () => {
await fs.rm(tmpDir, { recursive: true, force: true });
});
}
7 changes: 0 additions & 7 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,4 @@ export type EleventyDocumentOutlineOptions = {
* overwritten with a function here. This option is _not_ available on a
* case-by-case basis. */
slugify?: (input: string) => string;

/** When using the shortcode combined with a template that is not referencing
* a file (which includes the default configuration) a temporary directory is
* needed to write document outline templates to in order for them to be
* processed by Eleventy. By default, `"tmpDirEleventyDocumentOutline"` is
* used, but it is possible to overwrite this using this option. */
tmpDir?: string;
};
25 changes: 5 additions & 20 deletions src/render-template.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,11 @@
import fs from "node:fs/promises";

const templateMap = new Map<{ lang: string; source: string }, string>();
import { RenderPlugin } from "npm:@11ty/eleventy@^3.0.0-alpha.15";

export async function renderTemplate(
this: any,
config: any,
template: string | { lang: string; source: string },
tmpDir: string,
data: { headers: Array<{ id: string; text: string; tag: string }> },
): Promise<string> {
const renderFile = config.getShortcode("eleventyDocumentOutlineRender");
if (typeof template == "string") {
return await renderFile.call(this, template, data);
}
if (!templateMap.has(template)) {
await fs.mkdir(tmpDir, { recursive: true });
const { lang, source } = template;
const uuid = crypto.randomUUID();
const filePath = `${tmpDir}/${uuid}.${lang}`;
await fs.writeFile(filePath, source);
templateMap.set(template, filePath);
}
const path = templateMap.get(template);
return await renderFile.call(this, path, data);
const renderer = typeof template == "string"
? await RenderPlugin.File(template)
: await RenderPlugin.String(template.source, template.lang);
return await renderer(data);
}

0 comments on commit bfbdb10

Please sign in to comment.