summaryrefslogtreecommitdiffstats
path: root/lib/output/generatePage.js
blob: 090a870d327a17f8830d38483aa7ecd1477fed8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
var path = require('path');

var Promise = require('../utils/promise');
var error = require('../utils/error');
var timing = require('../utils/timing');

var Templating = require('../templating');
var JSONUtils = require('../json');
var createTemplateEngine = require('./createTemplateEngine');
var callPageHook = require('./callPageHook');

/**
 * Prepare and generate HTML for a page
 *
 * @param {Output} output
 * @param {Page} page
 * @return {Promise<Page>}
 */
function generatePage(output, page) {
    var book = output.getBook();
    var engine = createTemplateEngine(output);

    return timing.measure(
        'page.generate',
        Promise(page)
        .then(function(resultPage) {
            var file = resultPage.getFile();
            var filePath = file.getPath();
            var parser = file.getParser();
            var context = JSONUtils.encodeOutputWithPage(output, resultPage);

            if (!parser) {
                return Promise.reject(error.FileNotParsableError({
                    filename: filePath
                }));
            }

            // Call hook "page:before"
            return callPageHook('page:before', output, resultPage)

            // Escape code blocks with raw tags
            .then(function(currentPage) {
                return parser.preparePage(currentPage.getContent());
            })

            // Render templating syntax
            .then(function(content) {
                var absoluteFilePath = path.join(book.getContentRoot(), filePath);
                return Templating.render(engine, absoluteFilePath, content, context);
            })

            .then(function(output) {
                var content = output.getContent();

                return parser.parsePage(content)
                .then(function(result) {
                    return output.setContent(result.content);
                });
            })

            // Post processing for templating syntax
            .then(function(output) {
                return Templating.postRender(engine, output);
            })

            // Return new page
            .then(function(content) {
                return resultPage.set('content', content);
            })

            // Call final hook
            .then(function(currentPage) {
                return callPageHook('page', output, currentPage);
            });
        })
    );
}

module.exports = generatePage;