AllDocblocks.php

<?php

namespace Tlf\Scrawl\Ext\DefaultExt;

/**
 * Extract all docblocks through simple regex. Extract their descriptions & all @tags. Associate these with file & line-number
 *
 * In languages that have full AST support, this may not be as helpful. 
 */
class AllDoblocks extends \Tlf\Scrawl\ExtensionType\DefaultExt {

    protected $regData = [
        'StarStar' =>'/(\/\*\*(.*)\*\/)/ms',
    ];


    /**
     * Find verbs in a source md file
     */
    public function onTemplateFileFound(\Tlf\Scrawl\File $templateFile){
        //not implemeneted & tested yet
        return;
        $this->match('StarStar',$templateFile,$templateFile);
        $this->writeMdFile($templateFile);
    }

    public function matchStarStar($info, $templateFile, $verb, $argListStr){
        var_dump($info['match'][0]);
        // exit;
    }

    /**
     * Execute md verb extension methods & update output-content
     */
    public function matchVerb($info, $templateFile, $verb, $argListStr){
        $file = $templateFile;
        $line = $info['match'][0];
        $parsedArgs = $this->parseArgListString($argListStr);
        $info = [
            'file'=>$file,
            'line'=>$line,
            'verb'=>$verb,
            'argListStr'=>$argListStr,
            'argList' => $parsedArgs,
        ];
        foreach ($this->verbMap[$verb]??[] as $callable){
            // $ret = $callable($verb, $argListStr, $file, $line);
            try {
                $ret = $callable($info, ...$parsedArgs);
            } catch (\ArgumentCountError $e){
                $class = get_class($callable[0]);
                $method = $callable[1];
                echo "\n\n";
                echo "\nCannot call $class->$method() becuase of an argument count error.";

                echo "\n\n";
                echo "Error caused by: \n";
                $info = (array)$info;
                $info['file'] = (array)$info['file'];
                $info['file']['content'] = '--content is removed from var dump for readability--';
                print_r($info);

                echo "\n\n";
                throw $e;
            }
            if ($ret===false)continue;
            $file->content = str_replace($line, $ret, $file->content());
        }
    }

    /**
     * Append the correct md file to the output, to later be written by Scrawl
     */
    public function writeMdFile(\Tlf\Scrawl\File $templateFile){
        $relPath = $templateFile->relPath;
        $ext = '.src.md';
        $len = strlen($ext);
        if (substr($relPath, -$len)==$ext){
            $relPath = substr($relPath,0,-$len).'.md';
        }

        if ($this->scrawl->getConfig('markdown.preserveNewLines')[0]){
            // @TODO add test for markdown.preserveNewLines
            $templateFile->content = str_replace("\n","  \n",$templateFile->content());
        }

        if ($this->scrawl->getConfig('markdown.prependGenNotice')[0]){
            // @TODO give relative path to source file
            $templateFile->content = "<!-- DO NOT EDIT. This file generated from template by Code Scrawl https://tluf.me/code-scrawl/ -->\n".$templateFile->content();
        }
        
        $templateDir = $this->scrawl->getConfig('dir.template')[0];

        $this->scrawl->addOutput('file', $relPath, $templateFile->content());
    }

    /**
     * Parse an arg list string & return it as an array
     *
     * Each arg is trimmed. There is no special handling of any character. Commas may not appear in arguments, as they are argument separators.
     *
     * @param $argListString a string like `arg1, arg2, arg3` where every arg is separated by a comma. 
     *
     */
    public function parseArgListString(string $argListString): array{
        $list = explode(',', $argListString);
        $list = array_map('trim', $list);
        return $list;
    }

}