diff --git a/src/command/render/pandoc.ts b/src/command/render/pandoc.ts index fcb8a47f0a3..0228ea34483 100644 --- a/src/command/render/pandoc.ts +++ b/src/command/render/pandoc.ts @@ -201,7 +201,6 @@ import { MarkdownPipelineHandler, } from "../../core/markdown-pipeline.ts"; import { getEnv } from "../../../package/src/util/utils.ts"; -import { canonicalizeTitlePostprocessor } from "../../format/html/format-html-title.ts"; import { BrandFontBunny, BrandFontFile, @@ -439,11 +438,6 @@ export async function runPandoc( // record postprocessors postprocessors.push(...(extras.postprocessors || [])); - // Fix H1 title inconsistency - if (isHtmlFileOutput(options.format.pandoc)) { - htmlPostprocessors.push(canonicalizeTitlePostprocessor); - } - // add a keep-source post processor if we need one if ( options.format?.render[kKeepSource] || formatHasCodeTools(options.format) diff --git a/src/project/types/website/website.ts b/src/project/types/website/website.ts index 1d562d619b6..c5248dd64ae 100644 --- a/src/project/types/website/website.ts +++ b/src/project/types/website/website.ts @@ -89,7 +89,7 @@ import { projectDraftMode } from "./website-utils.ts"; import { kFieldCategories } from "./listing/website-listing-shared.ts"; import { pandocNativeStr } from "../../../core/pandoc/codegen.ts"; import { asArray } from "../../../core/array.ts"; -import { InternalError } from "../../../core/lib/error.ts"; +import { canonicalizeTitlePostprocessor } from "../../../format/html/format-html-title.ts"; export const kSiteTemplateDefault = "default"; export const kSiteTemplateBlog = "blog"; @@ -140,214 +140,213 @@ export const websiteProjectType: ProjectType = { format: Format, services: RenderServices, ): Promise => { - if (isHtmlFileOutput(format.pandoc)) { - // navigation extras for bootstrap enabled formats - const extras = formatHasBootstrap(format) - ? await websiteNavigationExtras( - project, - source, - flags, - format, - services.temp, - ) - : await websiteNoThemeExtras( - project, - source, - flags, - format, - services.temp, - ); + if (!isHtmlFileOutput(format.pandoc)) { + return Promise.resolve({}); + } - // add some title related variables - extras.pandoc = extras.pandoc || {}; - extras.metadata = extras.metadata || {}; - extras.metadataOverride = extras.metadataOverride || {}; + // navigation extras for bootstrap enabled formats + const extras = formatHasBootstrap(format) + ? await websiteNavigationExtras( + project, + source, + flags, + format, + services.temp, + ) + : await websiteNoThemeExtras( + project, + source, + flags, + format, + services.temp, + ); - // Resolve any giscus information - resolveFormatForGiscus(project, format); + // add some title related variables + extras.pandoc = extras.pandoc || {}; + extras.metadata = extras.metadata || {}; + extras.metadataOverride = extras.metadataOverride || {}; - // title prefix if the project has a title and this isn't the home page - const title = websiteTitle(project.config); - if (title) { - extras.pandoc = { - [kTitlePrefix]: title, - }; - } + // Resolve any giscus information + resolveFormatForGiscus(project, format); - // dependency for favicon if we have one - const favicon = websiteConfigString(kSiteFavicon, project.config); - if (favicon) { - const offset = projectOffset(project, source); - extras.html = extras.html || {}; - extras.html.dependencies = extras.html.dependencies || []; - extras.html.dependencies.push({ - name: kSiteFavicon, - links: [{ - rel: "icon", - href: offset + "/" + favicon, - type: contentType(favicon), - }], - }); - } + // title prefix if the project has a title and this isn't the home page + const title = websiteTitle(project.config); + if (title) { + extras.pandoc = { + [kTitlePrefix]: title, + }; + } - // pagetitle for home page if it has no title + // dependency for favicon if we have one + const favicon = websiteConfigString(kSiteFavicon, project.config); + if (favicon) { const offset = projectOffset(project, source); - const [_dir, stem] = dirAndStem(source); - const home = stem === "index" && offset === "."; - if ( - home && !format.metadata[kTitle] && !format.metadata[kPageTitle] && - title - ) { - extras.metadata[kPageTitle] = title; - } + extras.html = extras.html || {}; + extras.html.dependencies = extras.html.dependencies || []; + extras.html.dependencies.push({ + name: kSiteFavicon, + links: [{ + rel: "icon", + href: offset + "/" + favicon, + type: contentType(favicon), + }], + }); + } - // categories metadata needs to be escaped from Markdown processing to - // avoid +smart applying to it. Categories are expected to be non markdown. - // So we provide an override to ensure they are not processed. - if (format.metadata[kFieldCategories]) { - extras.metadataOverride[kFieldCategories] = asArray( - format.metadata[kFieldCategories], - ).map( - (category) => { - const strCategory: string = typeof category === "string" - ? category - : category.toString(); - return pandocNativeStr(strCategory).mappedString().value; - }, - ); - } + // pagetitle for home page if it has no title + const offset = projectOffset(project, source); + const [_dir, stem] = dirAndStem(source); + const home = stem === "index" && offset === "."; + if ( + home && !format.metadata[kTitle] && !format.metadata[kPageTitle] && + title + ) { + extras.metadata[kPageTitle] = title; + } - // html metadata - extras.html = extras.html || {}; - extras.html[kHtmlPostprocessors] = extras.html[kHtmlPostprocessors] || []; - extras.html[kHtmlFinalizers] = extras.html[kHtmlFinalizers] || []; - extras.html[kMarkdownAfterBody] = extras.html[kMarkdownAfterBody] || []; - extras.html[kHtmlPostprocessors]?.push(...[ - htmlResourceResolverPostprocessor( - source, - project, - projectExtensionPathResolver( - project.config?.project[kProjectLibDir] || "", - project.dir, - ), - ), - ]); - extras.html[kHtmlPostprocessors].unshift(websiteDraftPostProcessor); + // categories metadata needs to be escaped from Markdown processing to + // avoid +smart applying to it. Categories are expected to be non markdown. + // So we provide an override to ensure they are not processed. + if (format.metadata[kFieldCategories]) { + extras.metadataOverride[kFieldCategories] = asArray( + format.metadata[kFieldCategories], + ).map( + (category) => { + const strCategory: string = typeof category === "string" + ? category + : category.toString(); + return pandocNativeStr(strCategory).mappedString().value; + }, + ); + } - // listings extras - const hasBootstrap = formatHasBootstrap(format); + // html metadata + extras.html = extras.html || {}; + extras.html[kHtmlPostprocessors] = extras.html[kHtmlPostprocessors] || []; + extras.html[kHtmlFinalizers] = extras.html[kHtmlFinalizers] || []; + extras.html[kMarkdownAfterBody] = extras.html[kMarkdownAfterBody] || []; - const htmlListingDependencies = await listingHtmlDependencies( + extras.html[kHtmlPostprocessors].push(...[ + htmlResourceResolverPostprocessor( source, project, - format, - services.temp, - extras, - ); - if (htmlListingDependencies) { - const listingPostProcessor = - htmlListingDependencies[kHtmlPostprocessors]; - if (listingPostProcessor) { - // Process listings early so if we inject content div, navigation and other - // elements will wrap around - extras.html[kHtmlPostprocessors]?.unshift(listingPostProcessor); - } + projectExtensionPathResolver( + project.config?.project[kProjectLibDir] || "", + project.dir, + ), + ), + ]); + // add postprocessors that needs to be before other extras.html + extras.html[kHtmlPostprocessors].unshift( + websiteDraftPostProcessor, + // Fix H1 title inconsistency + canonicalizeTitlePostprocessor, + ); - const listingAfterBody = htmlListingDependencies[kMarkdownAfterBody]; - if (listingAfterBody) { - extras.html[kMarkdownAfterBody]?.push(listingAfterBody); - } - extras[kIncludeInHeader] = extras[kIncludeInHeader] || []; - extras[kIncludeInHeader]!.push( - ...htmlListingDependencies[kIncludeInHeader], - ); - extras.html[kSassBundles] = extras.html[kSassBundles] || []; - extras.html[kSassBundles]!.push( - ...htmlListingDependencies[kSassBundles], - ); + // listings extras + const hasBootstrap = formatHasBootstrap(format); - extras.html[kDependencies] = extras.html[kDependencies] || []; - extras.html[kDependencies]?.push( - ...htmlListingDependencies[kDependencies], - ); + const htmlListingDependencies = await listingHtmlDependencies( + source, + project, + format, + services.temp, + extras, + ); + if (htmlListingDependencies) { + const listingPostProcessor = htmlListingDependencies[kHtmlPostprocessors]; + if (listingPostProcessor) { + // Process listings early so if we inject content div, navigation and other + // elements will wrap around + extras.html[kHtmlPostprocessors]?.unshift(listingPostProcessor); } - if (hasBootstrap) { - // about extras - const aboutDependencies = await aboutHtmlDependencies( - source, - project, - format, - services.temp, - extras, - ); - if (aboutDependencies) { - const aboutPostProcessor = aboutDependencies[kHtmlPostprocessors]; - if (aboutPostProcessor) { - extras.html[kHtmlPostprocessors]?.push(aboutPostProcessor); - } - - extras.html[kSassBundles] = extras.html[kSassBundles] || []; - extras.html[kSassBundles]!.push( - ...aboutDependencies[kSassBundles], - ); - extras.html[kMarkdownAfterBody] = extras.html[kMarkdownAfterBody] || - []; - extras.html[kMarkdownAfterBody]!.push( - ...aboutDependencies[kMarkdownAfterBody], - ); - } + const listingAfterBody = htmlListingDependencies[kMarkdownAfterBody]; + if (listingAfterBody) { + extras.html[kMarkdownAfterBody]?.push(listingAfterBody); } - - // metadata html dependencies - const htmlMetadataDependencies = metadataHtmlDependencies( - source, - project, - format, - extras, - ); - extras.html[kHtmlPostprocessors]?.push( - htmlMetadataDependencies[kHtmlPostprocessors], + extras[kIncludeInHeader] = extras[kIncludeInHeader] || []; + extras[kIncludeInHeader]!.push( + ...htmlListingDependencies[kIncludeInHeader], ); - extras.html[kMarkdownAfterBody]?.push( - htmlMetadataDependencies[kMarkdownAfterBody], + extras.html[kSassBundles] = extras.html[kSassBundles] || []; + extras.html[kSassBundles]!.push( + ...htmlListingDependencies[kSassBundles], ); - // Add html analytics extras, if any - const analyticsDependency = websiteAnalyticsScriptFile( - project, - services.temp, + extras.html[kDependencies] = extras.html[kDependencies] || []; + extras.html[kDependencies]?.push( + ...htmlListingDependencies[kDependencies], ); - if (analyticsDependency) { - extras[kIncludeInHeader] = extras[kIncludeInHeader] || []; - extras[kIncludeInHeader]?.push(analyticsDependency); - } - const cookieDep = cookieConsentDependencies( + } + + if (hasBootstrap) { + // about extras + const aboutDependencies = await aboutHtmlDependencies( + source, project, format, services.temp, + extras, ); - if (cookieDep) { - // Inline script - extras[kIncludeInHeader] = extras[kIncludeInHeader] || []; - extras[kIncludeInHeader]?.push( - cookieDep.scriptFile, + if (aboutDependencies) { + const aboutPostProcessor = aboutDependencies[kHtmlPostprocessors]; + if (aboutPostProcessor) { + extras.html[kHtmlPostprocessors]?.push(aboutPostProcessor); + } + + extras.html[kSassBundles] = extras.html[kSassBundles] || []; + extras.html[kSassBundles]!.push( + ...aboutDependencies[kSassBundles], + ); + extras.html[kMarkdownAfterBody].push( + ...aboutDependencies[kMarkdownAfterBody], ); + } + } - // dependency - extras.html = extras.html || {}; - extras.html[kDependencies] = extras.html[kDependencies] || []; - extras.html[kDependencies]?.push(cookieDep.dependency); + // metadata html dependencies + const htmlMetadataDependencies = metadataHtmlDependencies( + source, + project, + format, + extras, + ); + extras.html[kHtmlPostprocessors].push( + htmlMetadataDependencies[kHtmlPostprocessors], + ); + extras.html[kMarkdownAfterBody].push( + htmlMetadataDependencies[kMarkdownAfterBody], + ); - extras.html[kHtmlPostprocessors] = extras.html[kHtmlPostprocessors] || - []; - extras.html[kHtmlPostprocessors]?.push(cookieDep.htmlPostProcessor); - } + // Add html analytics extras, if any + const analyticsDependency = websiteAnalyticsScriptFile( + project, + services.temp, + ); + if (analyticsDependency) { + extras[kIncludeInHeader] = extras[kIncludeInHeader] || []; + extras[kIncludeInHeader]?.push(analyticsDependency); + } + const cookieDep = cookieConsentDependencies( + project, + format, + services.temp, + ); + if (cookieDep) { + // Inline script + extras[kIncludeInHeader] = extras[kIncludeInHeader] || []; + extras[kIncludeInHeader]?.push( + cookieDep.scriptFile, + ); - return Promise.resolve(extras); - } else { - return Promise.resolve({}); + // dependency + extras.html[kDependencies] = extras.html[kDependencies] || []; + extras.html[kDependencies].push(cookieDep.dependency); + extras.html[kHtmlPostprocessors].push(cookieDep.htmlPostProcessor); } + + return Promise.resolve(extras); }, postRender: async (