I am trying to do the following with PHP…
- Read a directory
- Find all .md and .markdown files
- Read the first 2 lines of these Markdown files.
- If a
Title: Title for the fileis found on line 1 then add it to the array - If a
Description: Short descriptionis found on line 2 then add it to the array - If a Sub-directory is found, repeat steps 1-5 on them
- Should now have a nice list/array
- Print this list/array to screen to show up like this….
Directory 1 Name
<a href="LINK TO MARKDOWN FILE 1"> TITLE from line 1 of Markdown FILE 1</a> <br>
Description from Markdown FILE 1 line 2
<a href="LINK TO MARKDOWN FILE 2"> TITLE from line 1 of Markdown FILE 1</a> <br>
Description from Markdown FILE 2 line 2
<a href="LINK TO MARKDOWN FILE 3"> TITLE from line 1 of Markdown FILE 1</a> <br>
Description from Markdown FILE 3 line 2
Directory 2 Name
<a href="LINK TO MARKDOWN FILE 1"> TITLE from line 1 of Markdown FILE 1</a> <br>
Description from Markdown FILE 1 line 2
<a href="LINK TO MARKDOWN FILE 2"> TITLE from line 1 of Markdown FILE 1</a> <br>
Description from Markdown FILE 2 line 2
<a href="LINK TO MARKDOWN FILE 3"> TITLE from line 1 of Markdown FILE 1</a> <br>
Description from Markdown FILE 3 line 2
etc..........
Code so far
function getFilesFromDir($dir)
{
$files = array();
//scan directory passsed into function
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
// If file is .md or .markdown continue
if (preg_match('/\.(md|markdown)$/', $file)) {
// Grab first 2 lines of Markdown file
$content = file($dir . '/' . $file);
$title = $content[0];
$description = $content[1];
// If first 2 lines of Markdown file have a
// "Title: file title" and "Description: file description" lines we then
// add these key/value pairs to the array for meta data
// Match Title line
$pattern = '/^(Title|Description):(.+)/';
if (preg_match($pattern, $title, $matched)) {
$title = trim($matched[2]);
}
// match Description line
if (preg_match($pattern, $description, $matched)) {
$description = trim($matched[2]);
}
// Add .m and .markdown files and folder path to array
// Add captured Title and Description to array as well
$files[$dir][] = array("filepath" => $dir . '/' . $file,
"title" => $title,
"description" => $description
);
}
}
closedir($handle);
}
return $files;
}
Usage
$dir = 'mdfiles';
$fileArray = getFilesFromDir($dir);
Help needed
So far the code just needs to add the ability to do what it does on sub-directories and the way that it matches the first 2 lines of code and then runs the regex 2 times, can probably be done differently?
I would think there is a better way so that the REGEX I have to match the Title and Description can be run just once?
Can someone help me modify to make this code detect and run on sub-directories as well as improve the way it reads the first 2 lines of a markdown file to get the title and description if they exist?
Also need help printing the array to screen to make it not only just show the dat, I know how to do that but has to break the files up to show the Folder name at the top of each set like in my demo output above.
I appreciate any help
To recursively iterate over files, the
RecursiveDirectoryIteratoris quite handy (related: PHP recursive directory path). It already offers an easy access toFileSystemObjectas well which looks useful in your case as you want to obtain the files content.Additionally it’s possible to run one regular expression to parse the first two lines of the file, as patterns get cached when you execute them more often, it should be fine. One pattern has the benefit that the code is more structured, but the downside that the pattern is more complex. Configuration could look like this:
Just in case the markdown files are actually UTF-8 encoded, I added the
u-modifier (PCRE8).The processing part of the code is then using a recursive directory iterator over
$path, skips files not matching$fileFilterand then parses the first two lines of each file (if a file is at least readable and has at least one line) and stores it into a directory based hashtable/array$result:What’s left is the output. As the hashtable is pre-ordered by the directory hash, it’s fairly straight forward by first iterating over the directories and then over the files within: