-
Notifications
You must be signed in to change notification settings - Fork 3
/
export
95 lines (85 loc) 路 2.77 KB
/
export
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const glob = require("glob");
const { readdirSync, readFileSync } = require('fs')
const { basename } = require('path')
// I have my posts in the `content/codebase` directory
const listPosts = () => {
return readdirSync(`${__dirname}/content/bonjour`)
.map(el => `${__dirname}/content/bonjour/${el}`)
}
const createPost = (title, slug, publishedAt, markdown) => {
return {
"title": title,
"slug": slug,
"mobiledoc": JSON.stringify({
version: '0.3.1',
markups: [],
atoms: [],
cards: [['markdown', {cardName: 'markdown', markdown }]],
sections: [[10, 0]]
}),
"status": "published",
// These dates end up somewhat of an approximation, because
// I would have to extract them from the .md files' metadata
// which is more work and of little use in my case
"published_at": publishedAt,
"created_at": publishedAt,
"updated_at": publishedAt,
}
}
// Extracts post data from the Markdown files used in Hugo
//
// The original Hugo files look somewhat like this:
//
// <example lang="hugo">
// +++
// title = "Hello world"
// slug = "hello-world-url"
// date = "2019-04-16"
// +++
// Post content is here...
// </example>
const createPostDataFromFileContent = (filename, fileContent) => {
console.log(filename)
const contentRegexp = /^---((.|\n)+)---((.|\n)+)$/m
const titleRegexp = /title: "(.+)"/
const dateRegexp = /date: (.+)/
const slugRegexp = /slug: "(.+)"/
const contentMatches = fileContent.match(contentRegexp)
const header = contentMatches[1]
const titleMatches = header.match(titleRegexp)
const slugMatches = header.match(slugRegexp)
const dateMatches = header.match(dateRegexp)
const title = titleMatches[1]
const date = (new Date(dateMatches[1])).getTime()
const markdown = contentMatches[3].trim()
// In my case, the filenames are the same as the slug
const slug = slugMatches[1]
return createPost(
title,
slug,
date,
markdown
)
}
function toPosts(error, md){
postsData = md.map(filename => ({ filename, fileContent: readFileSync(filename).toString() }))
.map(({ filename, fileContent }) => createPostDataFromFileContent(filename, fileContent))
// Prints the posts in JSON format for Ghost, which can be used to debug
// or create a .json file to import into Ghost, like so:
//
// <example lang="shell">
// node hugo-to-ghost.js > ghost.json
// </example>
console.log(JSON.stringify(
{
"meta": {
"exported_on":1408552443891,
"version":"3.1.0",
},
"data": {
"posts": postsData,
},
}
))
}
glob(`${__dirname}/content/bonjour/**/index.md`, toPosts)