Skip to content

Instantly share code, notes, and snippets.

@bzerangue
Last active July 24, 2020 17:39
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bzerangue/4967324 to your computer and use it in GitHub Desktop.
Save bzerangue/4967324 to your computer and use it in GitHub Desktop.
Recursively search through a directory (and it's children directories) to find Markdown files and convert the list of files and their content and into an XML document. Dependent on PHP-Markdown and YAML Front Matter for PHP (https://github.com/Blaxus/YAML-FrontMatter)
<?php
#
# INSPIRATION FROM Nick Dunn (in the Symphony CMS forum)
# "Convert a Directory of Markdown Text Files for Dynamic XML Datasource Use"
# http://getsymphony.com/discuss/thread/60701/#position-2
#
# AND FROM Stack Overflow
# http://stackoverflow.com/questions/8545010/php-reading-first-2-lines-of-file-into-variable-and-cylce-through-subfolders/8545451#8545451
#
#
# configuration
#
$path = '.';
$fileFilter = '~\.(md|markdown)$~';
$pattern = '~^(?:Title: (.*))?(?:(?:\r\n|\n)(?:Description: (.*)))?~u';
#
# main
#
# init result array (the nice one)
$result = array();
# recursive iterator for files
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::KEY_AS_PATHNAME | FilesystemIterator::CURRENT_AS_FILEINFO),
RecursiveIteratorIterator::SELF_FIRST);
foreach($iterator as $path => $info)
{
# filter out files that don't match
if (!preg_match($fileFilter, $path)) continue;
# get first two lines
try
{
for
(
$maxLines = 2,
$lines = '',
$file = $info->openFile()
;
!$file->eof() && $maxLines--
;
$lines .= $file->fgets()
);
$lines = rtrim($lines, "\n");
if (!strlen($lines)) # skip empty files
continue;
}
catch (RuntimeException $e)
{
continue; # files which are not readable are skipped.
}
# parse md file
$r = preg_match($pattern, $lines, $matches);
if (FALSE === $r)
{
throw new Exception('Regular expression failed.');
}
list(, $title, $description) = $matches + array('', '', '');
# grow result array
$result[dirname($path)][] = array($path, $title, $description);
}
#
# output
#
// adding Content Type
header("Content-type: text/xml");
// create a new XML document
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
include_once('includes/lib/frontmatter.php');
include_once('includes/lib/markdown.php');
//$dirCounter = 0;
$currentdate = date("Y-m-d");
$currenttime = date("H:i");
$r = $doc->createElement('data');
$doc-> appendChild($r);
$r->setAttribute("date-created", $currentdate );
$r->setAttribute("time-created", $currenttime );
foreach ($result as $name => $dirs)
{
$directoryname = $doc->createElement('directory');
$r->appendChild($directoryname);
$directoryname->setAttribute("name", basename($name) );
$directoryname->setAttribute("path", $name );
foreach ($dirs as $entry)
{
list($path, $title, $description) = $entry;
$page = new FrontMatter($path);
$text = file_get_contents($path);
// fetching markdown content and appending as XML
$fragment = $doc->createDocumentFragment();
$fragment->appendXML(Markdown($page->fetch('content')));
$fileentry = $doc->createElement('file');
$directoryname->appendChild($fileentry);
$fileentry->setAttribute("path", $path);
$fileentry->setAttribute("name", basename($path));
$meta = $doc->createElement('meta');
$fileentry->appendChild($meta);
// 'title' and 'uri' are YAML Front Matter keys
// NOTE: entered in here statically right now
// would like for this dynamically createElement() based on
// whatever keys it is given in the YAML Front Matter
$metatitle = $doc->createElement('title');
$metatitle->appendChild( $doc->createTextNode( $page->fetch('title') ) );
$meta->appendChild($metatitle);
$metauri = $doc->createElement('uri');
$metauri->appendChild( $doc->createTextNode( $page->fetch('uri') ) );
$meta->appendChild($metauri);
$contentoutput = $doc->createElement('content');
$contentoutput->appendChild($fragment);
$fileentry->appendChild($contentoutput);
}
}
// get completed xml document
$xml_string = $doc->saveXML();
echo $xml_string;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment