1import { ConfigData, formatterFactory, HtmlValidate, Report, Reporter } from "html-validate"; 2import "lume/types.ts"; 3import { merge } from "lume/core/utils/object.ts"; 4import { log } from "lume/core/utils/log.ts"; 5 6export const defaults: ConfigData = { 7 extends: ["html-validate:recommended", "html-validate:document"], 8 rules: { 9 "doctype-style": "off", 10 "attr-quotes": "off", 11 "no-trailing-whitespace": "off", 12 "void-style": "warn", 13 "require-sri": ["error", { target: "crossorigin" }], 14 }, 15}; 16 17export default function (userOptions?: ConfigData) { 18 const options = merge(defaults, userOptions); 19 const htmlvalidate = new HtmlValidate(options); 20 const format = formatterFactory("text"); 21 22 return (site: Lume.Site) => { 23 site.process([".html"], validatePages); 24 25 async function validatePages(pages: Lume.Page[]) { 26 var reports: Array<Promise<Report>> = []; 27 for (const page of pages) { 28 const report = await htmlvalidate.validateString(page.content as string, page.outputPath); 29 reports.push(report); 30 } 31 const merged: Report | Promise<Report> = Reporter.merge(reports); 32 33 if (merged.valid) { 34 log.info("[validateHTML] Validation successful!"); 35 } 36 37 if (!merged.valid) { 38 log.error("[validateHTML]:\n" + format(merged.results)); 39 } 40 } 41 }; 42}