Skip to content

Commit c9a7e62

Browse files
committed
Refactor compiler pipeline WIP
1 parent fd4b08b commit c9a7e62

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+590
-255
lines changed

src/compiler2/drivers/fs/index.js

+47-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ const exploreDirectory = async (currentPath, depth = 0) => {
2121
const baseProperties = {
2222
name: fileName,
2323
path: relative(rootPath, accumulatedPath),
24-
stats: { birthtime },
24+
stats: {
25+
/* Because JSON driver can't easily parse date from string
26+
* let contentTree not know about dates for now */
27+
birthtime: birthtime.toString()
28+
},
2529
depth,
2630
}
2731
if (await isDirectory(accumulatedPath)) {
@@ -33,6 +37,7 @@ const exploreDirectory = async (currentPath, depth = 0) => {
3337
const extension = extname(fileName)
3438
const fileProperties = {
3539
...baseProperties,
40+
name: fileName.replace(new RegExp(extension + '$'), ''),
3641
extension,
3742
}
3843
if (isTextFile(extension)) {
@@ -56,6 +61,8 @@ const frontMatter = require('front-matter')
5661
const _ = require('lodash')
5762
const Driver = require('../../lib/Driver')
5863
const { ContentTree, ContentTreeEntry } = require('../../lib/ContentTree')
64+
65+
/*
5966
const ContentParsers = require('../../lib/Parsers')
6067
6168
class FileSystemEntry extends ContentTreeEntry {
@@ -105,6 +112,7 @@ class FolderEntry extends FileSystemEntry {
105112
this.setChildren(entry.children)
106113
}
107114
}
115+
*/
108116

109117
class FileSystemDriver extends Driver {
110118
constructor() {
@@ -128,40 +136,73 @@ class FileSystemDriver extends Driver {
128136
data: obj
129137
}
130138
}
139+
131140
if (typeof obj === 'string') {
132141
return {
133142
type: 'string',
134143
data: obj
135144
}
136145
}
146+
137147
if (typeof obj === 'boolean') {
138148
return {
139149
type: 'boolean',
140150
data: obj
141151
}
142152
}
153+
154+
/* Because JSON driver can't easily parse date from string
155+
* let contentTree not know about dates for now
156+
if (obj instanceof Date) {
157+
return {
158+
type: 'date',
159+
data: obj
160+
}
161+
}
162+
*/
163+
143164
if (Array.isArray(obj)) {
144165
return {
145166
type: 'array',
146-
data: obj.map(this.deepTokenize),
167+
data: obj.map(o => this.deepTokenize(o)),
147168
}
148169
}
149170

150171
return {
151172
type: 'object',
152173
data: Object.keys(obj).reduce((result, key) => {
174+
// omit children from data
153175
if (key === 'children') {
154176
return result
155177
}
178+
// tokenize all other keys
156179
return {
157180
...result,
158181
[key]: this.deepTokenize(obj[key])
159182
}
160183
}, {}),
161-
subTree: (obj.children || []).map(this.deepTokenize)
184+
subTree: (obj.children || []).map(c => this.deepTokenize(c))
162185
}
163186
}
164187

188+
mapExtensionToFormat(extension) {
189+
if (!extension) {
190+
return 'unformatted'
191+
}
192+
return {
193+
'.txt': 'plaintext',
194+
'.text': 'plaintext',
195+
'.md': 'markdown',
196+
'.markdown': 'markdown',
197+
'.html': 'hypertext',
198+
'.htm': 'hypertext',
199+
'.hbs': 'handlebars',
200+
'.handlebars': 'handlebars',
201+
'.json': 'json',
202+
'.yml': 'yml',
203+
}[extension] || 'unknown'
204+
}
205+
165206
tokenize(fileSystemTree) {
166207
return fileSystemTree.reduce((entries, entry) => {
167208
const maybeFrontMatter = (
@@ -173,6 +214,7 @@ class FileSystemDriver extends Driver {
173214
const contentNode = this.deepTokenize({
174215
...entry,
175216
...maybeFrontMatter,
217+
format: this.mapExtensionToFormat(entry.extension)
176218
})
177219

178220
return [
@@ -182,3 +224,5 @@ class FileSystemDriver extends Driver {
182224
}, [])
183225
}
184226
}
227+
228+
module.exports = FileSystemDriver

src/compiler2/enhancers/dates.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const _ = require('lodash')
2+
const Dictionary = require('../../dictionary')
3+
const { decorate } = require('../../decorations')
4+
5+
const withDates = async (entry) => {
6+
if (!entry.publishDatePrototype) {
7+
return entry
8+
}
9+
const locale = Dictionary.getLocale()
10+
const decoratedEntry = await decorate('publishDate', entry)
11+
const publishDate = new Date(decoratedEntry.publishDatePrototype.value)
12+
return {
13+
..._.omit(entry, 'publishDatePrototype'),
14+
publishDate,
15+
publishDateUTC: publishDate.toUTCString(),
16+
publishDateFull: publishDate.toLocaleString(locale, { dateStyle: 'full' }),
17+
publishDateLong: publishDate.toLocaleString(locale, { dateStyle: 'long' }),
18+
publishDateMedium: publishDate.toLocaleString(locale, { dateStyle: 'medium' }),
19+
publishDateShort: publishDate.toLocaleString(locale, { dateStyle: 'short' })
20+
}
21+
}
22+
23+
module.exports = withDates

src/compiler2/enhancers/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const withDates = require('./dates')
2+
3+
module.exports = {
4+
withDates
5+
}

src/compiler2/enhancers/mentions.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const _ = require('lodash')
2+
const { pipe } = require('../../../../../helpers')
3+
4+
const attachMentionedEntries = (allEntries) => (entry) => {
5+
const mention = (contentModelEntry) => ({
6+
title: contentModelEntry.title || contentModelEntry.name,
7+
permalink: contentModelEntry.permalink,
8+
// category: contentModelEntry.category
9+
})
10+
11+
const otherEntries = allEntries.filter(otherEntry => {
12+
return otherEntry.permalink !== entry.permalink
13+
})
14+
15+
const entriesMentioned = otherEntries
16+
.filter(otherEntry => entry.mentions.includes(otherEntry.permalink))
17+
.map(mention)
18+
19+
const entriesMentionedBy = otherEntries
20+
.filter(otherEntry => otherEntry.mentions.includes(entry.permalink))
21+
.map(mention)
22+
23+
return {
24+
..._.omit(entry, 'mentions'),
25+
links: {
26+
...(entry.links || {}),
27+
mentionedTo: entriesMentioned,
28+
mentionedBy: entriesMentionedBy
29+
}
30+
}
31+
}
32+
33+
module.exports = (contentModel) => {
34+
const attacher = attachMentionedEntries([
35+
contentModel.homepage,
36+
...contentModel.subpages,
37+
...(contentModel.blog?.posts || []),
38+
...(contentModel.blog?.categories || [])
39+
])
40+
return {
41+
...contentModel,
42+
homepage: attacher(contentModel.homepage),
43+
subpages: contentModel.subpages.map(attacher),
44+
...(contentModel.blog && {
45+
blog: {
46+
...contentModel.blog,
47+
posts: contentModel.posts.map(attacher),
48+
categories: contentModel.categories.map(attacher)
49+
}
50+
}),
51+
}
52+
}

src/compiler2/index.js

+7-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ const Settings = require('../settings')
22
const Debug = require('../debug')
33
const { contentRoot } = require('../helpers')
44
const FileSystemDriver = require('./drivers/fs')
5-
const RootOntology = require('./ontologies/root')
5+
const Ontologies = require('./ontologies')
6+
const Renderer = require('./renderer')
67

78
const getContentRoot = async () => {
89
const { rootDirectory, contentDirectory } = Settings.getSettings()
@@ -13,20 +14,22 @@ const getContentRoot = async () => {
1314

1415
const compile = async () => {
1516
Debug.timeStart('compiler')
17+
const { rootContentModel } = Settings.getSettings()
1618
const contentRootPath = await getContentRoot()
1719
const fileSystem = new FileSystemDriver()
1820
const {
1921
fileSystemTree,
2022
contentTree
2123
} = await fileSystem.parse(contentRootPath)
24+
console.log('settings.rootContentModel', rootContentModel)
25+
const RootOntology = Ontologies.get(rootContentModel)
2226
const root = new RootOntology(contentTree)
23-
console.log('root ontology model', root.model())
24-
// await root.render()
27+
await root.render(Renderer)
2528
Debug.timeEnd('compiler')
2629
return {
2730
fileSystemTree,
2831
contentTree,
29-
contentModel: await root.model()
32+
contentModel: root.contentModel
3033
}
3134
}
3235

src/compiler2/lib/ContentTree.js

+7-100
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,20 @@
11
const assert = require('assert')
22

33
class ContentTree {
4-
constructor() {}
4+
constructor(tree) {
5+
this.tree = tree
6+
}
57
}
68

79
class ContentTreeEntry {
8-
constructor({ name, pathway, timestamp, content, children }) {
9-
this.name = assert(typeof name === 'string') || name
10-
this.pathway = assert(pathway instanceof Array) || pathway
11-
this.timestamp = assert(Number.isInteger(timestamp)) || timestamp
12-
this.content = assert(!content || typeof content ==='string') || content
13-
this.children = assert(!children || children instanceof Array) || children
10+
constructor({ type, data, subTree }) {
11+
this.type = assert(typeof type === 'string') || type
12+
this.data = assert(data instanceof Array) || data
13+
this.subTree = assert(Number.isInteger(subTree)) || subTree
1414
}
1515
}
1616

1717
module.exports = {
1818
ContentTree,
1919
ContentTreeEntry,
2020
}
21-
22-
const postsJSON = [
23-
{
24-
"type": "text",
25-
"title": "Olay ve Olasılık",
26-
"cover": "/turkce/olay-ve-olasilik/sorgular.jpg",
27-
"media": "",
28-
"summary": "<h3>Ağaç sorguları</h3>\n<p>Ağaçlarda kendimizi görebiliriz. Sınırsız şekillerde dallar her göz için farklı kesişir.\nAkla basit gelen bir dizi genetik kuralın sonucu olarak bu ağaçlar bizi farklı düşlere koyar.\n",
29-
"tags": [
30-
{
31-
"tag": "deneme",
32-
"slug": "deneme",
33-
"permalink": "/tags/deneme"
34-
}
35-
],
36-
"date": "2022-12-31, 00:43",
37-
"coverAlt": "Ağaçlar olasılıklarını dallarıyla olaya döker",
38-
"coverShape": "roundTop",
39-
"coverPosition": "center bottom",
40-
"musiclist": [
41-
"Boards of Canada - Sunshine Recorder",
42-
"Massive Attack - Pray for Rain",
43-
"Massive Attack - I Against I",
44-
"Duman - Dibine Kadar"
45-
],
46-
"slug": "olay-ve-olasilik",
47-
"permalink": "/turkce/olay-ve-olasilik",
48-
"category": {
49-
"name": "Türkçe",
50-
"permalink": "/turkce"
51-
},
52-
"path": "Türkçe/Olay ve Olasılık/post.md",
53-
"handle": "Türkçe/Olay ve Olasılık",
54-
"foldered": true,
55-
"localAssets": [
56-
{
57-
"name": "ben.jpg",
58-
"path": "Türkçe/Olay ve Olasılık/ben.jpg",
59-
"depth": 2,
60-
"extension": ".jpg",
61-
"isFolder": false,
62-
"type": "localAsset"
63-
},
64-
{
65-
"name": "sorgular.jpg",
66-
"path": "Türkçe/Olay ve Olasılık/sorgular.jpg",
67-
"depth": 2,
68-
"extension": ".jpg",
69-
"isFolder": false,
70-
"type": "localAsset"
71-
}
72-
],
73-
"publishDate": "2022-12-30T21:43:00.000Z",
74-
"publishDateUTC": "Fri, 30 Dec 2022 21:43:00 GMT",
75-
"publishDateFull": "Saturday, December 31, 2022",
76-
"publishDateLong": "December 31, 2022",
77-
"publishDateMedium": "Dec 31, 2022",
78-
"publishDateShort": "12/31/22",
79-
"links": {
80-
"previousPost": {
81-
"title": "Herhangi bir text post",
82-
"permalink": "/turkce/herhangi-bir-text-post.html"
83-
},
84-
"relevantPosts": [],
85-
"mentionedTo": [],
86-
"mentionedBy": []
87-
}
88-
}
89-
]
90-
91-
const linksJSON = [
92-
{
93-
"url": "https://www.smashingmagazine.com/2018/04/best-practices-grid-layout",
94-
"title": "Best Practices With CSS Grid Layout",
95-
"tags": [
96-
"css",
97-
"grid",
98-
"frontend"
99-
],
100-
"datePublished": 1532221014000
101-
},
102-
{
103-
"url": "https://www.wikiwand.com/en/Emergence",
104-
"title": "Emergence",
105-
"tags": [
106-
"philosophy",
107-
"science",
108-
"art",
109-
"wiki"
110-
],
111-
"datePublished": 1532255602000
112-
}
113-
]

src/compiler2/lib/Driver.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
export default class Driver {
1+
class Driver {
22
constructor() {}
33
parse() {}
44
}
5+
6+
module.exports = Driver

0 commit comments

Comments
 (0)