Skip to content

Commit

Permalink
refactor: remove duplicated code, unify includes.
Browse files Browse the repository at this point in the history
  • Loading branch information
learosema committed Oct 18, 2024
1 parent e02edaf commit b078b36
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 48 deletions.
31 changes: 15 additions & 16 deletions src/css.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import path from 'path';

import { handleTemplateFile } from './transforms/template-data.js';
import { handleIncludes } from './includes.js';

const INCLUDE_REGEX = /@import [\"\']([\w:\/\\\.\-]+?\.css)[\"\'](?:\s*layer\s*\((\w+)\))?;/g;

Expand All @@ -10,21 +8,22 @@ export default (config) => {
config.addExtension('css', {
outputFileExtension: 'css',
compile: async function (inputContent, inputPath) {
let parsed = path.parse(inputPath);

return async (data) => {
const includes = new Map();
const matches = inputContent.matchAll(INCLUDE_REGEX);
for (const [, file, layer] of matches) {
const tpl = await handleTemplateFile(config, data, path.join(parsed.dir, file));
if (layer) {
includes.set(file, tpl ? `@layer ${layer} {\n${tpl.content}\n}` : `@import url("${file}") layer(${layer});`);
continue;
return await handleIncludes(
inputContent, inputPath,
config, data, null, INCLUDE_REGEX,
(context, _, file, layer) => {
const include = context.includes.get(file);
if (!include || !include.content) {
return `@import url("${file}")${layer ?` layer(${layer});`:``};`;
}
if (! layer) {
return include.content;
}
return `@layer ${layer} {\n${tpl.content}\n}`;
}
includes.set(file, tpl ? tpl.content : `@import url("${file}");`);
}
return inputContent.replace(INCLUDE_REGEX, (_, file) => includes.get(file))
};
);
}
},
});
};
25 changes: 6 additions & 19 deletions src/html.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import path from 'path';
import { handleTemplateFile } from './transforms/template-data.js';
import { handleIncludes } from './includes.js';

const INCLUDE_REGEX = /<html-include[\s\r\n]*src="([\w\-\.]+?)"[\s\r\n]*\/?>/g;

Expand All @@ -9,24 +8,12 @@ export default (config) => {
config.addExtension('html', {
outputFileExtension: 'html',
compile: async function (inputContent, inputPath) {

let parsed = path.parse(inputPath);

return async (data) => {
const includes = new Map();
let content = inputContent;
const matches = Array.from(content.matchAll(INCLUDE_REGEX));
if (matches.length > 0) {
for (const [, file] of matches) {
const include = await handleTemplateFile(config, data, path.join(config.dir.includes, file));
includes.set(file, include ? include.content : `<!-- html-include src="${file}" -->`);
}
content = content.replace(INCLUDE_REGEX, (_, file) => {
return includes.get(file)
});
}
return content;
};
return await handleIncludes(
inputContent, inputPath,
config, data, config.dir.includes,
INCLUDE_REGEX);
}
},
});
};
47 changes: 47 additions & 0 deletions src/includes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import path from 'node:path';
import { handleTemplateFile } from './transforms/template-data.js';

/**
* Language-agnostic include method to handle includes in sissi
* @param {string} inputContent the content
* @param {string} inputPath the full path to the file processed
* @param {SissiConfig} config the configuration
* @param {any} data the data object
* @param {string} includePath the include path to be used. If nullish, it's relative to the inputPath
* @param {Regexp} regex the regular expression to match include directives
* @param {(context, ...args: string[]) => string} replaceFunction the callback function of the string.replace
* @returns {string} the contents with the includes resolved
*/
export async function handleIncludes(
content, inputPath, config, data, includePath, regex, replaceFunction) {
const includes = new Map();
let parsed = path.parse(inputPath);
const matches = Array.from(content.matchAll(regex));
for (const [, file] of matches) {
if (includes.has(file)) {
continue;
}
const _dependants = data?._dependants instanceof Array ? data._dependants.slice(0) : [inputPath];
const includeFile = path.join(includePath ?? parsed.dir, file);
if (_dependants.includes(includeFile)) {
console.warn(`Skipping Circular include detected in ${inputPath}: ${includeFile}`);
continue;
}
_dependants.push(file);
const include = await handleTemplateFile(config, {_dependants, ...(data ?? {})}, includeFile);
includes.set(file, include);
}

const defaultReplaceFunction = (context, _, file) => {
return context.includes.get(file)?.content ?? `<!-- missing include: ${file} -->`;
};

const replaceContext = {
inputPath,
includes,
};

return content.replace(regex,
(...args) => (replaceFunction ?? defaultReplaceFunction)(replaceContext, ...args)
);
}
18 changes: 5 additions & 13 deletions src/md.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import path from 'path';

import { handleTemplateFile } from './transforms/template-data.js';
import { handleIncludes } from './includes.js';
import { markdown } from './transforms/markdown.js';

const INCLUDE_REGEX = /<html-include[\s\r\n]*src="([\w\.]+)"[\s\r\n]*\/?>/g;
Expand All @@ -13,16 +11,10 @@ export default (config) => {
compile: async function (inputContent, inputPath) {

return async (data) => {
const includes = new Map();
const content = markdown(inputContent);
const matches = content.matchAll(INCLUDE_REGEX);
for (const [, file] of matches) {
const include = await handleTemplateFile(config, data, path.join(config.dir.includes, file));
includes.set(file, include ? include.content : `<!-- html-include src="${file}" -->`);
}
return content.replace(INCLUDE_REGEX, (_, file) => {
return includes.get(file)
});
return await handleIncludes(
markdown(inputContent), inputPath,
config, data, config.dir.includes,
INCLUDE_REGEX);
};
},
});
Expand Down

0 comments on commit b078b36

Please sign in to comment.