Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding include tag/shortcode to include markdown files #194

Open
errogaht opened this issue Jun 7, 2017 · 1 comment
Open

Adding include tag/shortcode to include markdown files #194

errogaht opened this issue Jun 7, 2017 · 1 comment

Comments

@errogaht
Copy link

errogaht commented Jun 7, 2017

Hello! im using couscous to generate docs and it will be great to use something like this
{% include ../parts/api-rules.md %} so i want to change content of partial and cous cous will update all html with this partial

@NHuebner1983
Copy link

NHuebner1983 commented Apr 19, 2018

Hi there.

Ready to get this working?

Skip all of this riffraff and scroll down to get to the PHP code.

Your original MD files will remain intact

Your original *.md files will NOT be overwritten with the included file. Instead, Couscous includes these files into memory, so the update I made edits the contents before it goes into Memory, parsing these Short Tags and including your requested file.

Folder path for includes

Your includes should be in the folder relative to your current *.md file. Optionally if you provide a / leading slash, it acts as an absolute path and should prevent using the relative path. This may be broken/vary between windows/linux, I would stick to relative paths.

Include syntax

[include('includes/request/subscribers.mdd')] You can use ' or ", they should automatically unwrap to pull out the include path.

Example Markdown using Includes

The extension for my includes is .mdd so the files are not parsed by Couscous and turned into HTML. These file extension can be anything you want as long as they are not ending in .md

# My Markdown is hot now.

**Check out this cool stuff below.**

# Subscribers REQUEST json
[include('includes/request/subscribers.mdd')]

# Subscribers RESPONSE json
[include('includes/response/subscribers.mdd')]

Nested includes

Since this code performs a "while" statement on content while it's being replaced, it should automatically handle nested includes (such as an included file containing an include to another file).

Replace file contents with PHP below

src/Module/Markdown/Step/LoadMarkdownFiles.php

<?php

namespace Couscous\Module\Markdown\Step;

use Couscous\Model\Project;
use Couscous\Module\Markdown\Model\MarkdownFile;
use Couscous\Step;
use Symfony\Component\Finder\SplFileInfo;

/**
 * Loads Markdown files in memory.
 *
 * @author Matthieu Napoli <[email protected]>
 */
class LoadMarkdownFiles implements Step
{
    public function __invoke(Project $project)
    {
        $files = $project->sourceFiles();
        $files->name('*.md');

        foreach ($files as $file) {
            /** @var SplFileInfo $file */
            $content = $this->importIncludes(file_get_contents($file->getPathname()), $file->getPath());

            $project->addFile(new MarkdownFile($file->getRelativePathname(), $content));
        }

        $project->watchlist->watchFiles($files);
    }

    private function importIncludes($content, $base_path)
    {
        $open  = '[include(';
        $close = ')]';

        if ( ! strstr($content, $open) || ! strstr($content, $close) )
        {
            return $content;
        }

        while ( strstr($content, $open) && strstr($content, $close) )
        {
            $statement    = substr($content, strpos($content, $open));
            $statement    = trim(substr($statement, 0, strpos($statement, $close) + strlen($close)));
            $file_include = substr($statement, strpos($statement, '(') + 1);
            $file_include = substr($file_include, 0, strpos($file_include, $close));
            $file_include = $this->unwrap($file_include, ["'", '"']);

            if ( substr($file_include, 0, 1) != '/' )
            {
                $file_include = $base_path . '/' . $file_include;
            }

            $file_contents = "# File Not Found: {$file_include}";

            if ( is_file($file_include) )
            {
                $file_contents = file_get_contents($file_include);
            }

            $content = str_replace($statement, $file_contents, $content);
        }

        return $content;
    }

    private function unwrap($str, $encapsulated = [])
    {
        $str          = trim($str);
        $encapsulated = ! is_array($encapsulated) ? [$encapsulated] : $encapsulated;

        foreach ( $encapsulated as $unwrap )
        {
            if ( substr($str, 0, 1) == $unwrap )
            {
                $str = substr($str, 1);
                $str = $this->unwrap($str, $encapsulated);
            }
            if ( substr($str, -1) == $unwrap )
            {
                $str = substr($str, 0, -1);
                $str = $this->unwrap($str, $encapsulated);
            }
        }

        return $str;
    }

}

Recompile Couscous from Source

Run this command in a Linux command prompt:

bin/compile

You will run it from a directory that looks like this:

image

How to get source installed

Go to the main page on this repo - perform a git clone on the repository. When you get it cloned, you should see folder like the one I showed you. You will need to run composer install (if you don't have composer, apt-get install composer should do the trick on an ubuntu/debian environment).

I hope some of this helps. If you can get the PHP file updated, recompile the couscous.phar file using the bin/compile command, you can then have a couscous.phar capable of including using shortcodes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants