Last active
December 21, 2019 12:28
-
-
Save treffynnon/5b2dd82ec5a93ed7dcf2 to your computer and use it in GitHub Desktop.
Pelican to Hugo reStructuredText post converter (Python static site generator to Go static site generator)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Requires pandoc to be installed and in your path | |
* | |
* It will look for .rst files in __DIR__/content/* where it will expect to find | |
* category folders. Inside these category folders your posts should be available. | |
* | |
* So | |
* | |
* - content | |
* - Computing | |
* - functional-php.rst | |
* - new-pc.rst | |
* - Misc | |
* - moving-house.rst | |
* - death-defying-stunts.rst | |
*/ | |
// Path to the folder containing rst documents you want to convert | |
$content_path = __DIR__ . '/content'; | |
// Output path where the posts will be saved to as markdown | |
$output_path = __DIR__ . '/hugo'; | |
function map_directory($path, $func) { | |
$results = []; | |
$d = dir($path); | |
while (false !== ($entry = $d->read())) { | |
if ('.' !== $entry && '..' !== $entry) { | |
$results[] = $func($entry, $d); | |
} | |
} | |
$d->close(); | |
return $results; | |
} | |
map_directory($content_path, function($entry, $d) { | |
$dir = $d->path . "/$entry"; | |
if (is_dir($dir)) { | |
parse_posts($dir, $entry); | |
} | |
}); | |
function parse_posts($path, $category) { | |
map_directory($path, function($entry, $d) { | |
$item = $d->path . "/$entry"; | |
if (is_file($item) && false !== strstr($entry, '.rst')) { | |
echo "$entry\n"; | |
$out_file = __DIR__ . '/hugo/' . str_replace('.rst', '.md', $entry); | |
$f = file_get_contents($item); | |
$f = mutate_file($f); | |
file_put_contents($out_file, $f); | |
} | |
}); | |
} | |
function mutate_file($f) { | |
$matches = []; | |
// add opening YAML front matter indicator | |
$f = "---\n" . $f; | |
// Change the rst title into a YAML key and value | |
$f = preg_replace('/^(---\n+)(.+)\n[#^~\-=_+\'`]+/', '\1' . "\n:title: " . '\2', $f); | |
// find the last rst key value pair and insert closing YAML front | |
// matter indicator immediately after it | |
if (preg_match_all('/^:([\w\d]+): +(.*) *$/m', $f, $matches)) { | |
$last_key = end($matches[1]); | |
$f = preg_replace('/^(:' . preg_quote($last_key) . ':.*)$/m', '\1' . "\n---\n", $f); | |
} | |
// convert all the rst key value pairs into YAML key value pairs | |
$f = preg_replace_callback('/^:([\w\d]+): +(.*) *$/m', function($matches) { | |
$out = ''; | |
if ($matches[2]) { | |
switch ($matches[1]) { | |
case 'date': | |
$date = strtotime($matches[2]); | |
$out = 'date: "' . date('Y-m-d\TH:i:s\Z', $date) . '"'; | |
break; | |
case 'tags': | |
case 'categories': | |
$cats = explode(',', $matches[2]); | |
$cats = array_map(function($item) { | |
$tag = str_replace('.', '', trim($item)); | |
return ' - "' . addslashes($tag) . '"'; | |
}, $cats); | |
$out = "{$matches[1]}:\n" . implode("\n", $cats); | |
break; | |
case 'category': | |
$out = "categories:\n - " . '"' . addslashes($matches[2]) . '"'; | |
break; | |
default: | |
$out = "{$matches[1]}: " . '"' . addslashes($matches[2]) . '"'; | |
break; | |
} | |
} | |
return $out; | |
}, $f); | |
$split = preg_split('/^---$/m', $f); | |
// remove empty lines | |
$split[1] = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $split[1]); | |
$content = $split[2]; | |
$pipes_map = array( | |
0 => array('pipe', 'r'), | |
1 => array('pipe', 'w'), | |
); | |
$arguments = array( | |
'--smart', | |
'-f rst', | |
'-t markdown_github', | |
); | |
$exec_string = 'pandoc ' . implode(' ', $arguments); | |
$proc_res = proc_open($exec_string, $pipes_map, $pipes); | |
if (!is_resource($proc_res)) { | |
return 'Could not process the file with pandoc.'; | |
} | |
fwrite($pipes[0], $content); | |
fclose($pipes[0]); | |
$markdown = stream_get_contents($pipes[1]); | |
$split[2] = "\n\n" . $markdown; | |
$f = implode('---', $split); | |
return $f; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment