1
2
3
4
5
6
7 package com.varmateo.yawg.commonmark;
8
9 import java.nio.file.Path;
10 import java.util.function.Function;
11
12 import io.vavr.control.Option;
13 import io.vavr.control.Try;
14 import org.commonmark.ext.front.matter.YamlFrontMatterVisitor;
15 import org.commonmark.node.Node;
16 import org.commonmark.parser.Parser;
17 import org.commonmark.renderer.html.HtmlRenderer;
18
19 import com.varmateo.yawg.spi.PageContext;
20 import com.varmateo.yawg.spi.TemplateContext;
21 import com.varmateo.yawg.spi.TemplateContextBuilder;
22 import com.varmateo.yawg.util.FileUtils;
23
24
25
26
27
28 final class CommonMarkTemplateContextFactory {
29
30
31 private static final String KEY_TITLE = "title";
32
33 private final Parser _markdownParser;
34 private final HtmlRenderer _htmlRenderer;
35
36
37
38
39
40 CommonMarkTemplateContextFactory(
41 final Parser markdownParser,
42 final HtmlRenderer htmlRenderer) {
43
44 _markdownParser = markdownParser;
45 _htmlRenderer = htmlRenderer;
46 }
47
48
49
50
51
52 public Try<TemplateContext> build(
53 final Path sourcePath,
54 final Path targetDir,
55 final Path targetPath,
56 final PageContext context) {
57
58 return parse(sourcePath)
59 .map(buildTemplateContext(sourcePath, targetPath, context));
60 }
61
62
63 private Try<Node> parse(final Path sourcePath) {
64
65 return FileUtils.safeReadFrom(sourcePath, _markdownParser::parseReader)
66 .recoverWith(CommonMarkPageBakerException.parseFailureTry(sourcePath));
67 }
68
69
70 private Function<Node, TemplateContext> buildTemplateContext(
71 final Path sourcePath,
72 final Path targetPath,
73 final PageContext context) {
74
75 return (Node document) -> buildTemplateContext(sourcePath, targetPath, context, document);
76 }
77
78
79 private TemplateContext buildTemplateContext(
80 final Path sourcePath,
81 final Path targetPath,
82 final PageContext context,
83 final Node document) {
84
85 final String title = documentTitle(sourcePath, document);
86 final String body = _htmlRenderer.render(document);
87 final String pageUrl = context.dirUrl() + "/" + targetPath.getFileName();
88
89 return TemplateContextBuilder.create()
90 .title(title)
91 .body(body)
92 .pageUrl(pageUrl)
93 .rootRelativeUrl(context.rootRelativeUrl())
94 .pageVars(context.pageVars())
95 .bakeId(context.bakeId())
96 .build();
97 }
98
99
100 private String documentTitle(
101 final Path sourcePath,
102 final Node document) {
103
104 return frontMatterTitle(document)
105 .getOrElse(() -> FileUtils.basename(sourcePath));
106 }
107
108
109 private Option<String> frontMatterTitle(final Node document) {
110
111 final YamlFrontMatterVisitor frontMatterVisitor = new YamlFrontMatterVisitor();
112 document.accept(frontMatterVisitor);
113
114 return Option.of(frontMatterVisitor.getData().get(KEY_TITLE))
115 .filter(xs -> xs.size() > 0)
116 .map(xs -> xs.get(0));
117 }
118
119
120 }