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
|
import * as fs from 'fs';
import { JSDOM } from 'jsdom';
const frontmatter = require('front-matter');
const md = require('markdown-it')();
const { html5Media } = require('markdown-it-html5-media');
md.use(html5Media);
import { dateToPath, dateToString } from './utils';
import { Date, FrontMatterObject, PostApiEntry, Meta } from './interfaces';
export default class Post {
date: Date;
fileTitle: string;
fileContent: string;
post: FrontMatterObject;
constructor(filePath: string) {
let [year, month, day, title] = filePath.split('/').splice(-4, 4);
this.fileTitle = title.substr(0, title.lastIndexOf('.'));
this.date = { year, month, day };
this.fileContent = fs.readFileSync(filePath, 'utf-8');
this.post = frontmatter(this.fileContent);
}
toApi(): PostApiEntry {
const { author, title, additionalMeta } = this.getMeta();
const { description, html } = this.getPostContent();
return {
date: dateToString(this.date),
author,
title,
path: `/kronika/${dateToPath(this.date)}/${this.fileTitle}`,
description,
meta: additionalMeta,
content: html,
};
}
getMeta(): Meta {
const { attributes } = this.post;
const author: string = attributes.author;
if (!author) throw 'Error while parsing the author';
const title: string = attributes.title;
if (!title) throw 'Error while parsing the title';
const additionalMeta = Object.keys(attributes)
.filter((key) => key != 'title' && key != 'author')
.reduce((acc, key) => ({ ...acc, [key]: attributes[key] }), {});
return {
author,
title,
additionalMeta,
};
}
getPostContent() {
const { body } = this.post;
const html = `<div>${md.render(body)}</div>`;
const description = this.getDescription(html);
return {
html,
description,
};
}
getDescription(html: string): string {
const { document } = new JSDOM(`<div>${html}</div>`).window;
const elements = document.getElementsByTagName('p');
const description = elements[1].textContent;
return description || '';
}
}
|