Skip to content

Instantly share code, notes, and snippets.

@qmacro
Last active December 24, 2018 08:41
Show Gist options
  • Save qmacro/47abb6f9f7479c9b5e625a8e9615b0d1 to your computer and use it in GitHub Desktop.
Save qmacro/47abb6f9f7479c9b5e625a8e9615b0d1 to your computer and use it in GitHub Desktop.
/**
* From previous conversions from WordPress to Ghost, I have a lot of posts
* with links to other posts, where the link is actually incorrect. The
* incorrect links are missing the day (dd) part of the URL.
*
* This script is a quick and dirty way of fixing them, in-place:
* 1) read all the posts, and work out a slug-to-anchor mapping
* 2) go through all the posts, using regexes to find incorrect links
* and replace them with the correct ones, referencing the mapping
* from the first step.
*
* DJ Adams, Dec 2018
*/
const fs = require('fs')
const postsDirectory = '/home/qmacro/local/projects/website/_posts/'
/**
* Read the directory of posts, and create a map of filenames, where
* the properties are the slugs and the values are how we need to make
* the links to those files in the markdown
*/
const files = fs.readdirSync(postsDirectory).reduce((a, x) => {
// filenames look like this: yyyy-mm-dd-some-title-as-slug.markdown
const parts = x.match(/^(\d{4}-\d{2}-\d{2})-(.+)\.markdown$/)
// construct map entry, slug = yyyy/mm/dd/slug
a[parts[2]] = [parts[1].split(/-/).join("/"),parts[2]].join("/")
return a
}, {})
/**
* This function to be called from replace function below
* p1 is the first parentheses-captured value in the replace's regex
* and represents the slug
*/
const replacer = function(_, p1) {
return files[p1]
}
/**
* Fix the markdown anchors to other local posts, for a given file
*/
function fixFile(filename) {
fs.readFile(postsDirectory + filename, 'utf8', function(err, data) {
if (err) return console.log(err)
// Replace any existing, incorrect anchor references, they will look
// like this: (/yyyy/mm/some-title-as-slug). Capture the slug on match.
// Use zero-width lookbehind and lookahead assertions to ensure a proper match.
var result = data.replace(/(?<=\(\/)20\d\d\/\d\d\/([^\/]+)(?=\/\))/g, replacer)
// If there have been replacements, write the updated file contents
if (result != data) {
console.log("Fixed " + filename)
fs.writeFile(postsDirectory + filename, result, 'utf8', function(err) {
if (err) return console.log(err)
})
}
})
}
fs.readdirSync(postsDirectory).forEach((x) => fixFile(x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment