import path from "path" ; import Promise from "../utils/promise" ; import error from "../utils/error" ; import timing from "../utils/timing" ; import Templating from "../templating" ; import JSONUtils from "../json" ; import createTemplateEngine from "./createTemplateEngine" ; import callPageHook from "./callPageHook" ; import { getCache } from "./page-cache" ; import Page from "../models/page" ; param { Output } output param { Page } page return { Promise < Page > } function generatePage ( output , page ) { const book = output . getBook ( ) ; const engine = createTemplateEngine ( output ) ; const cache = getCache ( ) ; return timing . measure ( "page.generate" , Promise ( page ) . then ( ( resultPage ) => { const file = resultPage . getFile ( ) ; const filePath = file . getPath ( ) ; const parser = file . getParser ( ) ; const context = JSONUtils . encodeOutputWithPage ( output , resultPage ) ; if ( ! parser ) { return Promise . reject ( error . FileNotParsableError ( { filename : filePath , } ) ) ; } return ( callPageHook ( "page:before" , output , resultPage ) . then ( ( currentPage ) => { return parser . preparePage ( currentPage . getContent ( ) ) ; } ) . then ( async ( content ) => { const absoluteFilePath = path . join ( book . getContentRoot ( ) , filePath ) ; const pageHash = page . hash ( ) ; const cachedPage = cache . getKey ( pageHash ) ; if ( cachedPage ) { return Page . fromJSON ( output ) ; } try { const output = await Templating . render ( engine , absoluteFilePath , content , context ) ; cache . setKey ( pageHash , Page . toJSON ( output ) ) ; return output ; } catch ( error ) { console . error ( "Template Rendering Error" , error ) ; console . log ( "Template content" , content ) ; throw error ; } } ) . then ( ( output ) => { const content = output . getContent ( ) ; return parser . parsePage ( content ) . then ( ( result ) => { return output . setContent ( result . content ) ; } ) ; } ) . then ( ( output ) => { return Templating . postRender ( engine , output ) ; } ) . then ( ( content ) => { return resultPage . set ( "content" , content ) ; } ) . then ( ( currentPage ) => { return callPageHook ( "page" , output , currentPage ) ; } ) ) ; } ) ) ; } export default generatePage ;