PHPDocumentationGenerator

đŸ“Ļ DocGenerator

DocGenerator A tool to automatically generate HTML documentation from PHP docblocks
function __construct(string $outputPath = 'docs') { $this->outputPath = rtrim($outputPath, '/'); if (!is_dir($this->outputPath)) { echo "Creating output directory: {$this->outputPath}\n"; if (!mkdir($this->outputPath, 0755, true)) { throw new \Exception("Failed to create output directory: {$this->outputPath}"); }

🔧 createStyleSheet

Create CSS file for documentation styling
function createStyleSheet(): void { $css = <<<CSS body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1000px; margin: 0 auto; padding: 20px; background-color: #f8f9fa; } h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; margin-bottom: 30px; font-size: 2.5em; } h2 { color: #2980b9; margin-top: 40px; padding: 10px; background-color: #ecf0f1; border-radius: 5px; font-size: 1.8em; } h3 { color: #c0392b; margin-top: 25px; font-size: 1.4em; border-left: 4px solid #e74c3c; padding-left: 10px; } .function-description { background-color: white; padding: 15px; border-left: 4px solid #2ecc71; margin: 20px 0; border-radius: 0 5px 5px 0; } .parameter-list { list-style: none; padding: 0; } .parameter-item { background-color: white; padding: 10px 15px; margin: 5px 0; border-radius: 5px; border: 1px solid #ddd; } .parameter-name { color: #2c3e50; font-family: monospace; font-weight: bold; background-color: #f7f9fa; padding: 2px 5px; border-radius: 3px; } .parameter-type { color: #e67e22; font-family: monospace; } .return-info { background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #ddd; margin: 10px 0; } .throws-list { list-style: none; padding: 0; } .throws-item { background-color: #fff5f5; padding: 10px 15px; margin: 5px 0; border-radius: 5px; border: 1px solid #fed7d7; } .throws-type { color: #c53030; font-weight: bold; } .author-list { list-style: none; padding: 0; } .author-item { background-color: #f0fff4; padding: 10px 15px; margin: 5px 0; border-radius: 5px; border: 1px solid #c6f6d5; } .author-type { color: #2f855a; font-weight: bold; } .divider { border: 0; height: 2px; background: linear-gradient(to right, transparent, #718096, transparent); margin: 40px 0; } .navbar { background-color: #2c3e50; color: white; padding: 10px 20px; position: sticky; top: 0; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .navbar a { color: white; text-decoration: none; margin-right: 15px; } .navbar a:hover { text-decoration: underline; } .method-visibility { display: inline-block; padding: 3px 6px; border-radius: 3px; margin-right: 8px; font-size: 0.8em; font-weight: bold; } .public { background-color: #d4edda; color: #155724; } .protected { background-color: #fff3cd; color: #856404; } .private { background-color: #f8d7da; color: #721c24; } #search-input { width: 100%; padding: 10px; margin-bottom: 20px; border: 1px solid #ddd; border-radius: 5px; } .search-highlight { background-color: yellow; } .code-example { background-color: #282c34; color: #abb2bf; padding: 15px; border-radius: 5px; overflow-x: auto; font-family: monospace; margin: 15px 0; } .deprecated { text-decoration: line-through; color: #6c757d; } .since-tag { font-size: 0.8em; color: #6c757d; margin-left: 10px; } .file-group { background-color: #f8f9fa; padding: 10px; margin-bottom: 15px; border-radius: 5px; border-left: 4px solid #3498db; } .file-count { font-weight: bold; color: #2c3e50; margin-left: 5px; } CSS; // Create the CSS file in the output directory file_put_contents("{$this->outputPath}

🔧 createStyleSheet

Create CSS file for documentation styling
function createStyleSheet(): void { $css = <<<CSS body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; line-height: 1.6; color: #333; max-width: 1000px; margin: 0 auto; padding: 20px; background-color: #f8f9fa; } h1 { color: #2c3e50; border-bottom: 3px solid #3498db; padding-bottom: 10px; margin-bottom: 30px; font-size: 2.5em; } h2 { color: #2980b9; margin-top: 40px; padding: 10px; background-color: #ecf0f1; border-radius: 5px; font-size: 1.8em; } h3 { color: #c0392b; margin-top: 25px; font-size: 1.4em; border-left: 4px solid #e74c3c; padding-left: 10px; } .function-description { background-color: white; padding: 15px; border-left: 4px solid #2ecc71; margin: 20px 0; border-radius: 0 5px 5px 0; } .parameter-list { list-style: none; padding: 0; } .parameter-item { background-color: white; padding: 10px 15px; margin: 5px 0; border-radius: 5px; border: 1px solid #ddd; } .parameter-name { color: #2c3e50; font-family: monospace; font-weight: bold; background-color: #f7f9fa; padding: 2px 5px; border-radius: 3px; } .parameter-type { color: #e67e22; font-family: monospace; } .return-info { background-color: white; padding: 15px; border-radius: 5px; border: 1px solid #ddd; margin: 10px 0; } .throws-list { list-style: none; padding: 0; } .throws-item { background-color: #fff5f5; padding: 10px 15px; margin: 5px 0; border-radius: 5px; border: 1px solid #fed7d7; } .throws-type { color: #c53030; font-weight: bold; } .author-list { list-style: none; padding: 0; } .author-item { background-color: #f0fff4; padding: 10px 15px; margin: 5px 0; border-radius: 5px; border: 1px solid #c6f6d5; } .author-type { color: #2f855a; font-weight: bold; } .divider { border: 0; height: 2px; background: linear-gradient(to right, transparent, #718096, transparent); margin: 40px 0; } .navbar { background-color: #2c3e50; color: white; padding: 10px 20px; position: sticky; top: 0; box-shadow: 0 2px 5px rgba(0,0,0,0.1); } .navbar a { color: white; text-decoration: none; margin-right: 15px; } .navbar a:hover { text-decoration: underline; } .method-visibility { display: inline-block; padding: 3px 6px; border-radius: 3px; margin-right: 8px; font-size: 0.8em; font-weight: bold; } .public { background-color: #d4edda; color: #155724; } .protected { background-color: #fff3cd; color: #856404; } .private { background-color: #f8d7da; color: #721c24; } #search-input { width: 100%; padding: 10px; margin-bottom: 20px; border: 1px solid #ddd; border-radius: 5px; } .search-highlight { background-color: yellow; } .code-example { background-color: #282c34; color: #abb2bf; padding: 15px; border-radius: 5px; overflow-x: auto; font-family: monospace; margin: 15px 0; } .deprecated { text-decoration: line-through; color: #6c757d; } .since-tag { font-size: 0.8em; color: #6c757d; margin-left: 10px; } .file-group { background-color: #f8f9fa; padding: 10px; margin-bottom: 15px; border-radius: 5px; border-left: 4px solid #3498db; } .file-count { font-weight: bold; color: #2c3e50; margin-left: 5px; } CSS; // Create the CSS file in the output directory file_put_contents("{$this->outputPath}

🔧 generate

Generate documentation for a specific file or directory
function generate(string $path): void { try { if (is_dir($path)) { $this->processDirectory($path); } else { $this->processFile($path); } $this->generateIndex(); echo "Documentation generated successfully in {$this->outputPath}\n"; echo "Found and documented " . count($this->processedFiles) . " files\n"; // ... (truncated)

âš™ī¸ Parameters

â†Šī¸ Returns

(void)

🔧 processDirectory

Process all PHP files in a directory
function processDirectory(string $dirPath): void { try { if (!is_readable($dirPath)) { throw new \Exception("Directory is not readable: {$dirPath}"); } echo "Starting to process directory: {$dirPath}

âš™ī¸ Parameters

âš ī¸ Throws


🔧 processFile

Process a single PHP file
function processFile(string $filePath): void { try { echo "Reading file: " . basename($filePath) . "\n"; $content = file_get_contents($filePath); if ($content === false) { throw new \Exception("Could not read file {$filePath}"); } $tokens = token_get_all($content); $documentation = []; $currentClass = null; // ... (truncated)

âš™ī¸ Parameters

âš ī¸ Throws


🔧 extractCodeSnippet

Extract a code snippet for an entity
function extractCodeSnippet(array $tokens, int $maxLines): string { $code = ''; $bracketCount = 0; $lineCount = 0; $started = false; $functionFound = false; foreach ($tokens as $token) { // Check for function keyword if (!$functionFound && is_array($token) && $token[0] === T_FUNCTION) { $functionFound = true; $code .= $token[1]; // ... (truncated)

âš™ī¸ Parameters

â†Šī¸ Returns

(string) Formatted code snippet

🔧 parseDocBlock

Parse a doc block comment
function parseDocBlock(string $docBlock): array { $lines = explode("\n", $docBlock); $parsed = [ 'description' => '', 'params' => [], 'return' => null, 'throws' => [], 'author' => [], 'since' => null, 'deprecated' => false, // ... (truncated)

âš™ī¸ Parameters

â†Šī¸ Returns

(array) Parsed documentation

🔧 findEntityInfo

Find information about the entity following a doc block
function findEntityInfo(array $tokens): array { $name = null; $type = null; $visibility = 'public'; // Default visibility $foundVisibility = false; $foundFunction = false; $i = 0; // Skip any whitespace tokens while ($i < count($tokens) && is_array($tokens[$i]) && $tokens[$i][0] === T_WHITESPACE) { $i++; } // ... (truncated)

âš™ī¸ Parameters

â†Šī¸ Returns

(array) Entity info [name, type, visibility]

🔧 saveDocumentation

Save documentation to HTML file
function saveDocumentation(string $sourcePath, array $documentation): void { $filename = basename($sourcePath, '.php'); $html = $this->getFileHeader($filename); $html .= "<div class='navbar'>"; $html .= "<a href='index.html'>Home</a>"; $html .= "<a href='#top'>{$filename}

âš™ī¸ Parameters


🔧 getFileHeader

Get HTML header with metadata and styling
function getFileHeader(string $title = 'PHP Documentation'): string { return <<<HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{$title}

âš™ī¸ Parameters

â†Šī¸ Returns

(string) HTML header content

🔧 getFileHeader

Get HTML header with metadata and styling
function getFileHeader(string $title = 'PHP Documentation'): string { return <<<HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{$title}

âš™ī¸ Parameters

â†Šī¸ Returns

(string) HTML header content

🔧 generateIndex

Generate index file listing all documented files
function generateIndex(): void { $html = $this->getFileHeader('Documentation Index'); $html .= "<div class='navbar'>"; $html .= "<a href='index.html'>Home</a>"; $html .= "</div>"; $html .= "<h1>📚 Documentation Index</h1>\n\n"; // Add search input $html .= "<input type='text' id='search-input' placeholder='Search documentation...'>\n"; $html .= "<script> document.getElementById('search-input').addEventListener('input', function() { const searchTerm = this.value.toLowerCase(); const items = document.querySelectorAll('.parameter-item, .file-group'); items.forEach(function(item) { const text = item.textContent.toLowerCase(); item.style.display = searchTerm === '' || text.includes(searchTerm) ? '' : 'none'; }); }); </script>\n\n"; // Group files by directory $filesByDir = []; foreach ($this->processedFiles as $file) { // ... (truncated)