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 6// HTML Validation Plugin, by dish 7// version 1.0.1 8 9export const defaults: ConfigData = { 10 extends: ["html-validate:recommended", "html-validate:document"], 11 rules: { 12 "doctype-style": "off", 13 "attr-quotes": "off", 14 "no-trailing-whitespace": "off", 15 "void-style": "warn", 16 "require-sri": ["off", { target: "crossorigin" }], 17 }, 18}; 19 20export default function (userOptions?: ConfigData) { 21 const options = merge(defaults, userOptions); 22 const htmlvalidate = new HtmlValidate(options); 23 const format = formatterFactory("text"); 24 25 return (site: Lume.Site) => { 26 site.process([".html"], validatePages); 27 28 async function validatePages(pages: Lume.Page[]) { 29 let reports: Array<Report> = []; 30 for (const page of pages) { 31 const report = await htmlvalidate.validateString(page.content as string, page.outputPath); 32 reports.push(report); 33 } 34 const merged: Report | Promise<Report> = Reporter.merge(reports); 35 // Clear the reports table to ensure we don't get duplicates 36 reports = []; 37 38 if (merged.valid) { 39 log.info("[validateHTML] Validation successful!"); 40 } 41 42 if (!merged.valid) { 43 log.error("[validateHTML]:\n" + format(merged.results)); 44 } 45 } 46 }; 47}