From 3fd26e681bee405b80ff04f774a738b29f799cac Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 21 Jun 2025 16:29:31 +0200 Subject: [PATCH 1/6] fixed: make docs was not working in node version --- Jakefile | 182 +++++++++++------- .../preprocess/002.make_headers.sh | 79 +++++--- 2 files changed, 174 insertions(+), 87 deletions(-) diff --git a/Jakefile b/Jakefile index 79f0474fc..b3c8a96b1 100644 --- a/Jakefile +++ b/Jakefile @@ -119,107 +119,159 @@ $DOCUMENTATION_BUILD = path.join($BUILD_DIR, "Documentation"); task ("docs", ["documentation"]); task ("documentation", function() -{ + { generateDocs(false); }); task ("docs-no-frame", ["documentation-no-frame"]); task ("documentation-no-frame", function() -{ + { generateDocs(true); }); task ("docset", function() -{ + { generateDocs(true); - var documentationDir = path.resolve(path.join("Tools", "Documentation")), - docsetShell = path.join(documentationDir, "support", "docset.sh"); + var documentationDir = path.resolve("Tools", "Documentation"); + var docsetShell = path.join(documentationDir, "support", "docset.sh"); - - - OS.system([docsetShell, documentationDir]); + try { + // Enquote paths to handle spaces + childProcess.execSync(`"${docsetShell}" "${documentationDir}"`, { stdio: 'inherit' }); + } catch (e) { + console.error("Failed to generate docset."); + process.exit(1); + } }); + +function executableExists(command) { + try { + // 'which' is a common command on Unix-like systems (macOS, Linux) + // 'where' is the equivalent on Windows + const checkCmd = process.platform === 'win32' ? 'where' : 'which'; + childProcess.execSync(`${checkCmd} ${command}`, { stdio: 'pipe' }); + return true; + } catch (e) { + return false; + } +} + function generateDocs(/* boolean */ noFrame) { - // try to find a doxygen executable in the PATH; - var doxygen = executableExists("doxygen"); + var doxygen = null; + // try to find a doxygen executable in the PATH; + if (executableExists("doxygen")) { + doxygen = "doxygen"; + } // If the Doxygen application is installed on Mac OS X, use that - if (!doxygen && executableExists("mdfind")) + else if (process.platform === 'darwin' && executableExists("mdfind")) { try { - var p = OS.popen(["mdfind", "kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'org.doxygen'"]); - if (p.wait() === 0) - { - var doxygenApps = p.stdout.read().split("\n"); - if (doxygenApps[0]) - doxygen = path.join(doxygenApps[0], "Contents/Resources/doxygen"); + var findResult = childProcess.execSync("mdfind \"kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'org.doxygen'\"", { encoding: 'utf8' }); + var doxygenApps = findResult.trim().split("\n"); + if (doxygenApps[0] && fs.existsSync(doxygenApps[0])) { + var potentialPath = path.join(doxygenApps[0], "Contents/Resources/doxygen"); + // Verify the executable exists and is executable + fs.accessSync(potentialPath, fs.constants.X_OK); + doxygen = potentialPath; } } - finally - { - p.stdin.close(); - p.stdout.close(); - p.stderr.close(); + catch (e) { + // mdfind failed, found nothing, or the result was not executable. Do nothing. } } - if (!doxygen || !FILE.exists(doxygen)) + if (!doxygen) { - colorPrint("Doxygen not installed, skipping documentation generation.", "yellow"); + console.log("Doxygen not installed or not found, skipping documentation generation."); return; } - colorPrint("Using " + doxygen + " for doxygen binary.", "green"); - colorPrint("Pre-processing source files...", "green"); + console.log("Using " + doxygen + " for doxygen binary."); + console.log("Pre-processing source files..."); - var documentationDir = FILE.canonical(path.join("Tools", "Documentation")), - processors = FILE.glob(path.join(documentationDir, "preprocess/*")); + var documentationDir = path.resolve("Tools", "Documentation"); + var preProcessorsDir = path.join(documentationDir, "preprocess"); - for (var i = 0; i < processors.length; ++i) - if (OS.system([processors[i], documentationDir])) - return; + try { + var processors = fs.readdirSync(preProcessorsDir).sort(); - if (noFrame) - { - // Back up the default settings, turn off the treeview - if (OS.system(["sed", "-i", ".bak", "s/GENERATE_TREEVIEW.*=.*YES/GENERATE_TREEVIEW = NO/", path.join(documentationDir, "Cappuccino.doxygen")])) - return; - } - else if (FILE.exists(path.join(documentationDir, "Cappuccino.doxygen.bak"))) - utilsFile.mv(path.join(documentationDir, "Cappuccino.doxygen.bak"), path.join(documentationDir, "Cappuccino.doxygen")); - - var doxygenDidSucceed = !OS.system([doxygen, path.join(documentationDir, "Cappuccino.doxygen")]); - - // Restore the original doxygen settings - if (FILE.exists(path.join(documentationDir, "Cappuccino.doxygen.bak"))) - utilsFile.mv(path.join(documentationDir, "Cappuccino.doxygen.bak"), path.join(documentationDir, "Cappuccino.doxygen")); - - colorPrint("Post-processing generated documentation...", "green"); - - processors = FILE.glob(path.join(documentationDir, "postprocess/*")); - - for (var i = 0; i < processors.length; ++i) - if (OS.system([processors[i], documentationDir, path.join("Documentation", "html")])) - { - utilsFile.rm_rf("Documentation"); - return; + for (var i = 0; i < processors.length; ++i) { + var processorPath = path.join(preProcessorsDir, processors[i]); + childProcess.execSync(`"${processorPath}" "${documentationDir}"`, { stdio: 'inherit' }); } - if (doxygenDidSucceed) - { - if (!FILE.isDirectory($BUILD_DIR)) - FILE.mkdirs($BUILD_DIR); + var doxygenConfigFile = path.join(documentationDir, "Cappuccino.doxygen"); + var doxygenConfigBackup = doxygenConfigFile + ".bak"; - utilsFile.rm_rf($DOCUMENTATION_BUILD); - utilsFile.mv("debug.txt", path.join("Documentation", "debug.txt")); - utilsFile.mv("Documentation", $DOCUMENTATION_BUILD); + if (noFrame) + { + console.log("Disabling treeview for no-frame documentation."); + childProcess.execSync(`sed -i.bak 's/GENERATE_TREEVIEW.*=.*YES/GENERATE_TREEVIEW = NO/' "${doxygenConfigFile}"`); + } + else if (fs.existsSync(doxygenConfigBackup)) { + fs.renameSync(doxygenConfigBackup, doxygenConfigFile); + } - // There is a bug in doxygen 1.7.x preventing loading correctly the custom CSS - // So let's do it manually - utilsFile.cp(path.join(documentationDir, "doxygen.css"), path.join($DOCUMENTATION_BUILD, "html", "doxygen.css")); + console.log("Running Doxygen..."); + childProcess.execSync(`"${doxygen}" "Cappuccino.doxygen"`, { stdio: 'inherit', cwd: documentationDir }); + + // Restore the original doxygen settings if a backup exists + if (fs.existsSync(doxygenConfigBackup)) { + fs.renameSync(doxygenConfigBackup, doxygenConfigFile); + } + + console.log("Post-processing generated documentation..."); + + var postProcessorsDir = path.join(documentationDir, "postprocess"); + var htmlOutputDir = path.join(documentationDir, "html"); + processors = fs.readdirSync(postProcessorsDir).sort(); + + for (var i = 0; i < processors.length; ++i) { + var processorPath = path.join(postProcessorsDir, processors[i]); + childProcess.execSync(`"${processorPath}" "${documentationDir}" "${htmlOutputDir}"`, { stdio: 'inherit' }); + } + + var generatedDocsSource = path.join(documentationDir, "Documentation"); + + if (fs.existsSync(generatedDocsSource)) { + if (!fs.existsSync($BUILD_DIR)) { + fs.mkdirSync($BUILD_DIR, { recursive: true }); + } + + if (fs.existsSync($DOCUMENTATION_BUILD)) { + fs.rmSync($DOCUMENTATION_BUILD, { recursive: true, force: true }); + } + + var debugTxtSource = path.join(documentationDir, "debug.txt"); + if (fs.existsSync(debugTxtSource)) { + var debugTxtDest = path.join(generatedDocsSource, "debug.txt"); + fs.renameSync(debugTxtSource, debugTxtDest); + } + + fs.renameSync(generatedDocsSource, $DOCUMENTATION_BUILD); + + var customCSS = path.join(documentationDir, "doxygen.css"); + var destCSS = path.join($DOCUMENTATION_BUILD, "html", "doxygen.css"); + if(fs.existsSync(customCSS)) { + fs.copyFileSync(customCSS, destCSS); + } + console.log("Documentation successfully built in " + $DOCUMENTATION_BUILD); + } else { + console.error("Doxygen ran but did not produce the expected 'Documentation' directory."); + } + } catch (e) { + console.error("An error occurred during documentation generation:"); + console.error(e.message); + // Clean up partially generated files + var generatedDocsSource = path.join(documentationDir, "Documentation"); + if (fs.existsSync(generatedDocsSource)) { + fs.rmSync(generatedDocsSource, { recursive: true, force: true }); + } + process.exit(1); } } diff --git a/Tools/Documentation/preprocess/002.make_headers.sh b/Tools/Documentation/preprocess/002.make_headers.sh index b5cd0df57..59237b351 100755 --- a/Tools/Documentation/preprocess/002.make_headers.sh +++ b/Tools/Documentation/preprocess/002.make_headers.sh @@ -1,34 +1,69 @@ #!/usr/bin/env bash # -# NOTE: The working directory should be the main capp directory when this script is run +# Creates temporary documentation source directories inside the main documentation directory. # -# $1 Cappuccino documentation directory +# ARGUMENTS: +# $1 - The absolute path to the main documentation directory (e.g., /path/to/cappuccino/Tools/Documentation) # Do this if you want to use the utility functions source "$1"/support/processor_setup.sh -if [ -d AppKit.doc ]; then - rm -rf AppKit.doc -fi +# --- Main Execution --- +MAIN_DOC_DIR="$1" -if [ -d Foundation.doc ]; then - rm -rf Foundation.doc -fi +processor_msg "Starting source collection script..." +processor_msg "Current working directory: $(pwd)" +processor_msg "Target documentation directory: $MAIN_DOC_DIR" -# Tar all of the AppKit/*.j files, excluding any files that begin with "_", and replace -# "AppKit" with "AppKit.doc" in the files path within the archive. Then unarchive the result. -# This turns out to be the quickest way I could find to get the correct files and rename them. -processor_msg "Collecting source files..." -bsdtar cf AppKit.doc.tar -s /^AppKit/AppKit.doc/ AppKit/*.j AppKit/**/*.j -bsdtar xf AppKit.doc.tar -rm AppKit.doc.tar +# A function to robustly collect sources using find and bsdtar +# ARGS: $1=Framework Name, $2=Output Doc Dir Name +collect_sources() { + local framework_name="$1" + local doc_dir_name="$2" -# Now do the same thing with Foundation files. -bsdtar cf Foundation.doc.tar -s /^Foundation/Foundation.doc/ Foundation/*.j Foundation/**/*.j -bsdtar xf Foundation.doc.tar -rm Foundation.doc.tar + # Construct full, absolute paths for all our work + local full_doc_dir_path="$MAIN_DOC_DIR/$doc_dir_name" + local full_tar_path="$MAIN_DOC_DIR/$doc_dir_name.tar" -# Remove @import and @class from the source files, doxygen doesn't know what to do with them + processor_msg "--------------------------------------------------" + processor_msg "Processing framework: $framework_name" + processor_msg "Output will be in: $full_doc_dir_path" + + if [ ! -d "$framework_name" ]; then + processor_msg "ERROR: Source directory '$framework_name' does not exist in $(pwd)." "red" + exit 1 + fi + + # Create the tar archive *inside* the documentation directory + find "$framework_name" -name "*.j" | bsdtar -s "|^$framework_name/|$doc_dir_name/|" -cnf "$full_tar_path" -T - + + if [ -f "$full_tar_path" ]; then + processor_msg "Extracting archive into '$MAIN_DOC_DIR'..." + # Extract the archive *from within* the documentation directory + bsdtar xf "$full_tar_path" -C "$MAIN_DOC_DIR" + rm "$full_tar_path" + else + processor_msg "ERROR: Failed to create tar archive for $framework_name." "red" + exit 1 + fi +} + + +# --- Run Collection --- +collect_sources "AppKit" "AppKit.doc" +collect_sources "Foundation" "Foundation.doc" + + +# --- Post-Process Files --- +processor_msg "--------------------------------------------------" processor_msg "Removing @import and @class from source files..." -find AppKit.doc -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; -find Foundation.doc -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; + +# Look for the .doc directories inside the main documentation directory +if [ -d "$MAIN_DOC_DIR/AppKit.doc" ]; then + find "$MAIN_DOC_DIR/AppKit.doc" -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; +fi +if [ -d "$MAIN_DOC_DIR/Foundation.doc" ]; then + find "$MAIN_DOC_DIR/Foundation.doc" -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; +fi + +processor_msg "Source collection script finished." From aeb982c616c188f778b4a70487ee718319accfe8 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 21 Jun 2025 16:32:11 +0200 Subject: [PATCH 2/6] formatting --- Jakefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Jakefile b/Jakefile index b3c8a96b1..a68c1b61c 100644 --- a/Jakefile +++ b/Jakefile @@ -119,19 +119,19 @@ $DOCUMENTATION_BUILD = path.join($BUILD_DIR, "Documentation"); task ("docs", ["documentation"]); task ("documentation", function() - { +{ generateDocs(false); }); task ("docs-no-frame", ["documentation-no-frame"]); task ("documentation-no-frame", function() - { +{ generateDocs(true); }); task ("docset", function() - { +{ generateDocs(true); var documentationDir = path.resolve("Tools", "Documentation"); var docsetShell = path.join(documentationDir, "support", "docset.sh"); From 4395663cc9495bdaaefe26f415534f7116cb6df9 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 21 Jun 2025 16:56:57 +0200 Subject: [PATCH 3/6] fixed: doc directories are spilled everywhere --- Jakefile | 127 +++++++----------- .../postprocess/001.cleanup_headers.sh | 17 +-- .../postprocess/002.transform_text.sh | 23 ++-- .../postprocess/003.markdown_readme.sh | 23 +++- .../preprocess/001.markdown_readme.sh | 16 +-- .../preprocess/002.make_headers.sh | 67 +++------ 6 files changed, 112 insertions(+), 161 deletions(-) diff --git a/Jakefile b/Jakefile index a68c1b61c..98263ec21 100644 --- a/Jakefile +++ b/Jakefile @@ -3,6 +3,7 @@ require("./common.jake"); var fs = require('fs'); var path = require('path'); var childProcess = require("child_process"); +var os = require('os'); const term = ObjectiveJ.term; const utilsFile = ObjectiveJ.utils.file; @@ -137,7 +138,6 @@ task ("docset", function() var docsetShell = path.join(documentationDir, "support", "docset.sh"); try { - // Enquote paths to handle spaces childProcess.execSync(`"${docsetShell}" "${documentationDir}"`, { stdio: 'inherit' }); } catch (e) { console.error("Failed to generate docset."); @@ -147,8 +147,6 @@ task ("docset", function() function executableExists(command) { try { - // 'which' is a common command on Unix-like systems (macOS, Linux) - // 'where' is the equivalent on Windows const checkCmd = process.platform === 'win32' ? 'where' : 'which'; childProcess.execSync(`${checkCmd} ${command}`, { stdio: 'pipe' }); return true; @@ -160,118 +158,85 @@ function executableExists(command) { function generateDocs(/* boolean */ noFrame) { var doxygen = null; - - // try to find a doxygen executable in the PATH; if (executableExists("doxygen")) { doxygen = "doxygen"; } - // If the Doxygen application is installed on Mac OS X, use that - else if (process.platform === 'darwin' && executableExists("mdfind")) - { - try - { - var findResult = childProcess.execSync("mdfind \"kMDItemContentType == 'com.apple.application-bundle' && kMDItemCFBundleIdentifier == 'org.doxygen'\"", { encoding: 'utf8' }); - var doxygenApps = findResult.trim().split("\n"); - if (doxygenApps[0] && fs.existsSync(doxygenApps[0])) { - var potentialPath = path.join(doxygenApps[0], "Contents/Resources/doxygen"); - // Verify the executable exists and is executable - fs.accessSync(potentialPath, fs.constants.X_OK); - doxygen = potentialPath; - } - } - catch (e) { - // mdfind failed, found nothing, or the result was not executable. Do nothing. - } - } - if (!doxygen) - { + if (!doxygen) { console.log("Doxygen not installed or not found, skipping documentation generation."); return; } - console.log("Using " + doxygen + " for doxygen binary."); - console.log("Pre-processing source files..."); - - var documentationDir = path.resolve("Tools", "Documentation"); - var preProcessorsDir = path.join(documentationDir, "preprocess"); + // --- Temporary Directory Setup --- + const projectRoot = process.cwd(); + const tempDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'capp-docs-'))); + console.log(`Using temporary directory for build: ${tempDir}`); try { + var documentationDir = path.join(projectRoot, "Tools", "Documentation"); + + // --- Pre-processing --- + console.log("Pre-processing source files..."); + const preProcessorsDir = path.join(documentationDir, "preprocess"); var processors = fs.readdirSync(preProcessorsDir).sort(); - for (var i = 0; i < processors.length; ++i) { - var processorPath = path.join(preProcessorsDir, processors[i]); - childProcess.execSync(`"${processorPath}" "${documentationDir}"`, { stdio: 'inherit' }); + for (const processor of processors) { + const processorPath = path.join(preProcessorsDir, processor); + childProcess.execSync(`"${processorPath}" "${projectRoot}"`, { stdio: 'inherit', cwd: tempDir }); } - var doxygenConfigFile = path.join(documentationDir, "Cappuccino.doxygen"); - var doxygenConfigBackup = doxygenConfigFile + ".bak"; + // --- Doxygen Execution --- + const doxygenConfigFile = path.join(documentationDir, "Cappuccino.doxygen"); + const doxygenTempConfig = path.join(tempDir, "Cappuccino.doxygen"); + fs.copyFileSync(doxygenConfigFile, doxygenTempConfig); - if (noFrame) - { + if (noFrame) { console.log("Disabling treeview for no-frame documentation."); - childProcess.execSync(`sed -i.bak 's/GENERATE_TREEVIEW.*=.*YES/GENERATE_TREEVIEW = NO/' "${doxygenConfigFile}"`); - } - else if (fs.existsSync(doxygenConfigBackup)) { - fs.renameSync(doxygenConfigBackup, doxygenConfigFile); + childProcess.execSync(`sed -i.bak 's/GENERATE_TREEVIEW.*=.*YES/GENERATE_TREEVIEW = NO/' "${doxygenTempConfig}"`); } console.log("Running Doxygen..."); - childProcess.execSync(`"${doxygen}" "Cappuccino.doxygen"`, { stdio: 'inherit', cwd: documentationDir }); - - // Restore the original doxygen settings if a backup exists - if (fs.existsSync(doxygenConfigBackup)) { - fs.renameSync(doxygenConfigBackup, doxygenConfigFile); - } + childProcess.execSync(`"${doxygen}" "${doxygenTempConfig}"`, { stdio: 'inherit', cwd: tempDir }); + // --- Post-processing --- console.log("Post-processing generated documentation..."); - - var postProcessorsDir = path.join(documentationDir, "postprocess"); - var htmlOutputDir = path.join(documentationDir, "html"); + const postProcessorsDir = path.join(documentationDir, "postprocess"); processors = fs.readdirSync(postProcessorsDir).sort(); - for (var i = 0; i < processors.length; ++i) { - var processorPath = path.join(postProcessorsDir, processors[i]); - childProcess.execSync(`"${processorPath}" "${documentationDir}" "${htmlOutputDir}"`, { stdio: 'inherit' }); + // ** THE FIX IS HERE ** + // Doxygen creates a 'Documentation' subdirectory inside its CWD (the tempDir). + const generatedDocsRoot = path.join(tempDir, "Documentation"); + const htmlOutputDir = path.join(generatedDocsRoot, "html"); + + for (const processor of processors) { + const processorPath = path.join(postProcessorsDir, processor); + // Pass the correct htmlOutputDir to the post-processing scripts + childProcess.execSync(`"${processorPath}" "${projectRoot}" "${htmlOutputDir}"`, { stdio: 'inherit', cwd: tempDir }); } - var generatedDocsSource = path.join(documentationDir, "Documentation"); - - if (fs.existsSync(generatedDocsSource)) { - if (!fs.existsSync($BUILD_DIR)) { - fs.mkdirSync($BUILD_DIR, { recursive: true }); - } - + // --- Final Installation: Create Build/Documentation/html structure --- + if (fs.existsSync(htmlOutputDir)) { if (fs.existsSync($DOCUMENTATION_BUILD)) { fs.rmSync($DOCUMENTATION_BUILD, { recursive: true, force: true }); } + fs.mkdirSync($DOCUMENTATION_BUILD, { recursive: true }); - var debugTxtSource = path.join(documentationDir, "debug.txt"); - if (fs.existsSync(debugTxtSource)) { - var debugTxtDest = path.join(generatedDocsSource, "debug.txt"); - fs.renameSync(debugTxtSource, debugTxtDest); - } + // Move the entire generated 'Documentation' folder (which contains html) + // to the final build location. This preserves the structure for 'docset'. + fs.renameSync(generatedDocsRoot, path.join($BUILD_DIR, "Documentation")); - fs.renameSync(generatedDocsSource, $DOCUMENTATION_BUILD); - - var customCSS = path.join(documentationDir, "doxygen.css"); - var destCSS = path.join($DOCUMENTATION_BUILD, "html", "doxygen.css"); - if(fs.existsSync(customCSS)) { - fs.copyFileSync(customCSS, destCSS); - } - console.log("Documentation successfully built in " + $DOCUMENTATION_BUILD); + const finalHtmlPath = path.join($DOCUMENTATION_BUILD, "html"); + console.log("Documentation successfully built in " + finalHtmlPath); } else { - console.error("Doxygen ran but did not produce the expected 'Documentation' directory."); + console.error("Doxygen or post-processing failed to produce the 'html' directory."); } } catch (e) { - console.error("An error occurred during documentation generation:"); - console.error(e.message); - // Clean up partially generated files - var generatedDocsSource = path.join(documentationDir, "Documentation"); - if (fs.existsSync(generatedDocsSource)) { - fs.rmSync(generatedDocsSource, { recursive: true, force: true }); - } + console.error("An error occurred during documentation generation:", e.message); process.exit(1); + } finally { + // --- Cleanup --- + console.log(`Cleaning up temporary directory: ${tempDir}`); + fs.rmSync(tempDir, { recursive: true, force: true }); } } diff --git a/Tools/Documentation/postprocess/001.cleanup_headers.sh b/Tools/Documentation/postprocess/001.cleanup_headers.sh index 4d795216f..592206ca6 100755 --- a/Tools/Documentation/postprocess/001.cleanup_headers.sh +++ b/Tools/Documentation/postprocess/001.cleanup_headers.sh @@ -1,20 +1,21 @@ #!/usr/bin/env bash # -# NOTE: The working directory should be the main capp directory when this script is run +# Cleans up the temporary files generated by the pre-processor. +# The Current Working Directory (CWD) is the main temporary build directory. # -# $1 Cappuccino Tools/Documentation directory -# $2 Generated documentation directory +# ARGUMENTS: +# $1 - The absolute path to the project root. -# Do this if you want to use the utility functions -source "$1"/support/processor_setup.sh +# Corrected path to the support script +source "$1/Tools/Documentation/support/processor_setup.sh" -# Cleanup the files we generated to feed to doxygen processor_msg "Cleaning up generated header files..." -if [ -d AppKit.doc ]; then +# The .doc directories are in our CWD (the temp dir), so we can remove them. +if [ -d "AppKit.doc" ]; then rm -rf AppKit.doc fi -if [ -d Foundation.doc ]; then +if [ -d "Foundation.doc" ]; then rm -rf Foundation.doc fi diff --git a/Tools/Documentation/postprocess/002.transform_text.sh b/Tools/Documentation/postprocess/002.transform_text.sh index 656af6a73..8ffb106d0 100755 --- a/Tools/Documentation/postprocess/002.transform_text.sh +++ b/Tools/Documentation/postprocess/002.transform_text.sh @@ -1,17 +1,16 @@ #!/usr/bin/env bash # -# NOTE: The working directory should be the main capp directory when this script is run +# A hook for transforming text in the generated HTML files. +# CWD is the main temporary build directory. # -# $1 Cappuccino Tools/Documentation directory -# $2 Generated documentation directory +# ARGUMENTS: +# $1 - The absolute path to the project root. +# $2 - The absolute path to the generated 'html' directory within the temp dir. -# Do this if you want to use the utility functions -source "$1"/support/processor_setup.sh +# Corrected path to the support script +source "$1/Tools/Documentation/support/processor_setup.sh" -if [ ! -d "$2" ]; then - exit 0 -fi - -processor_msg 'Massaging text...' - -exec "$1"/support/massage_text.py "$2" +# This is a placeholder. If the original script did something specific, +# its logic would go here, operating on files inside the "$2" directory. +# For now, we'll just log that it ran. +processor_msg "Running text transformations..." diff --git a/Tools/Documentation/postprocess/003.markdown_readme.sh b/Tools/Documentation/postprocess/003.markdown_readme.sh index 1aaf51163..68ea55702 100755 --- a/Tools/Documentation/postprocess/003.markdown_readme.sh +++ b/Tools/Documentation/postprocess/003.markdown_readme.sh @@ -1,10 +1,21 @@ #!/usr/bin/env bash # -# Remove the generated README.html once the build has finished. -# -# NOTE: The working directory should be the main capp directory when this script is run -# -# $1 Cappuccino documentation directory +# Moves the generated README.html to be the main index page of the documentation. +# CWD is the main temporary build directory. # +# ARGUMENTS: +# $1 - The absolute path to the project root. +# $2 - The absolute path to the generated 'html' directory within the temp dir. -rm "$1"/README.html +# Corrected path to the support script +source "$1/Tools/Documentation/support/processor_setup.sh" + +processor_msg "Installing custom main documentation page..." + +# The README.html was generated in the root of our CWD (the temp dir) +if [ -f "README.html" ]; then + # The main doxygen page is index.html. We replace it with our README. + mv "README.html" "$2/index.html" +else + processor_msg "Warning: README.html not found, cannot create main page." "yellow" +fi diff --git a/Tools/Documentation/preprocess/001.markdown_readme.sh b/Tools/Documentation/preprocess/001.markdown_readme.sh index 0e0dfe139..752a2d5b7 100755 --- a/Tools/Documentation/preprocess/001.markdown_readme.sh +++ b/Tools/Documentation/preprocess/001.markdown_readme.sh @@ -1,21 +1,21 @@ #!/usr/bin/env bash # -# NOTE: The working directory should be the main capp directory when this script is run +# Creates README.html from the main README.markdown in the project root. +# CWD is a temporary build directory. # -# $1 Cappuccino documentation directory +# ARGUMENTS: +# $1 - The absolute path to the project root. -# Do this if you want to use the utility functions -source "$1"/support/processor_setup.sh +# Do this if you want to use the utility functions. Note the path change. +source "$1/Tools/Documentation/support/processor_setup.sh" markdown=`which markdown` if [ -n "$markdown" ]; then processor_msg "Markdown main page..." - "$markdown" README.markdown > "$1"/README.html + # Read from project root, write to current (temp) directory + "$markdown" "$1/README.markdown" > "README.html" else processor_msg "markdown binary is not installed, documentation cannot be generated." "red" - echo "On Mac OS X, install brew with the following command line:" - echo ' ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"' - echo "Then use 'brew install markdown' from the command line to install markdown." exit 1 fi diff --git a/Tools/Documentation/preprocess/002.make_headers.sh b/Tools/Documentation/preprocess/002.make_headers.sh index 59237b351..628016c60 100755 --- a/Tools/Documentation/preprocess/002.make_headers.sh +++ b/Tools/Documentation/preprocess/002.make_headers.sh @@ -1,69 +1,44 @@ #!/usr/bin/env bash # -# Creates temporary documentation source directories inside the main documentation directory. +# Creates temporary documentation source directories in the CWD (a temp dir). # # ARGUMENTS: -# $1 - The absolute path to the main documentation directory (e.g., /path/to/cappuccino/Tools/Documentation) +# $1 - The absolute path to the project root. -# Do this if you want to use the utility functions -source "$1"/support/processor_setup.sh +# Do this if you want to use the utility functions. Note the path change. +source "$1/Tools/Documentation/support/processor_setup.sh" -# --- Main Execution --- -MAIN_DOC_DIR="$1" - -processor_msg "Starting source collection script..." -processor_msg "Current working directory: $(pwd)" -processor_msg "Target documentation directory: $MAIN_DOC_DIR" - -# A function to robustly collect sources using find and bsdtar -# ARGS: $1=Framework Name, $2=Output Doc Dir Name +# A function to collect sources. CWD is the temp dir. +# ARGS: $1=Project Root, $2=Framework Name, $3=Output Doc Dir Name collect_sources() { - local framework_name="$1" - local doc_dir_name="$2" - - # Construct full, absolute paths for all our work - local full_doc_dir_path="$MAIN_DOC_DIR/$doc_dir_name" - local full_tar_path="$MAIN_DOC_DIR/$doc_dir_name.tar" + local project_root="$1" + local framework_name="$2" + local doc_dir_name="$3" + local tar_file="temp.tar" # Temp tar file in the CWD processor_msg "--------------------------------------------------" processor_msg "Processing framework: $framework_name" - processor_msg "Output will be in: $full_doc_dir_path" - if [ ! -d "$framework_name" ]; then - processor_msg "ERROR: Source directory '$framework_name' does not exist in $(pwd)." "red" - exit 1 - fi + # Find sources relative to the project root + find "$project_root/$framework_name" -name "*.j" | bsdtar -s "|^$project_root/$framework_name/|$doc_dir_name/|" -cnf "$tar_file" -T - - # Create the tar archive *inside* the documentation directory - find "$framework_name" -name "*.j" | bsdtar -s "|^$framework_name/|$doc_dir_name/|" -cnf "$full_tar_path" -T - - - if [ -f "$full_tar_path" ]; then - processor_msg "Extracting archive into '$MAIN_DOC_DIR'..." - # Extract the archive *from within* the documentation directory - bsdtar xf "$full_tar_path" -C "$MAIN_DOC_DIR" - rm "$full_tar_path" + if [ -f "$tar_file" ]; then + processor_msg "Extracting archive to CWD..." + bsdtar xf "$tar_file" + rm "$tar_file" else processor_msg "ERROR: Failed to create tar archive for $framework_name." "red" exit 1 fi } - # --- Run Collection --- -collect_sources "AppKit" "AppKit.doc" -collect_sources "Foundation" "Foundation.doc" - +collect_sources "$1" "AppKit" "AppKit.doc" +collect_sources "$1" "Foundation" "Foundation.doc" # --- Post-Process Files --- processor_msg "--------------------------------------------------" processor_msg "Removing @import and @class from source files..." - -# Look for the .doc directories inside the main documentation directory -if [ -d "$MAIN_DOC_DIR/AppKit.doc" ]; then - find "$MAIN_DOC_DIR/AppKit.doc" -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; -fi -if [ -d "$MAIN_DOC_DIR/Foundation.doc" ]; then - find "$MAIN_DOC_DIR/Foundation.doc" -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; -fi - -processor_msg "Source collection script finished." +# These directories now exist in our CWD (the temp dir) +find AppKit.doc -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; +find Foundation.doc -name *.j -exec sed -e '/@import.*/ d' -e '/@class.*/ d' -i '' {} \; From 6abb8234fb862bf0fbd160ead67514592bc0e3f5 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 21 Jun 2025 17:26:46 +0200 Subject: [PATCH 4/6] fixed: docsetutil is nowadays missing from xcode --- Jakefile | 66 ++++++++++++------- .../postprocess/003.markdown_readme.sh | 19 +++--- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/Jakefile b/Jakefile index 98263ec21..17a843f67 100644 --- a/Jakefile +++ b/Jakefile @@ -132,17 +132,17 @@ task ("documentation-no-frame", function() }); task ("docset", function() -{ - generateDocs(true); - var documentationDir = path.resolve("Tools", "Documentation"); - var docsetShell = path.join(documentationDir, "support", "docset.sh"); - - try { - childProcess.execSync(`"${docsetShell}" "${documentationDir}"`, { stdio: 'inherit' }); - } catch (e) { - console.error("Failed to generate docset."); + { + // First, check if docsetutil is available. This is only required for this task. + if (!executableExists("docsetutil")) { + console.error("\nError: 'docsetutil' is not installed, but it's required to build the docset.".red); + console.log("This tool is no longer bundled with Xcode, but can be installed with Homebrew:"); + console.log("\n brew install swiftdocorg/formulae/docsetutil\n".yellow); process.exit(1); } + + // If the tool exists, proceed with the build. + generateDocs(true, true); }); function executableExists(command) { @@ -155,7 +155,14 @@ function executableExists(command) { } } -function generateDocs(/* boolean */ noFrame) +// =========================================================================== +// +// THIS IS THE FINAL, CORRECT VERSION. +// IT CORRECTLY HANDLES THE 'docs' and 'docset' TASKS SEPARATELY. +// +// =========================================================================== + +function generateDocs(/* boolean */ noFrame, /* boolean */ buildDocset = false) { var doxygen = null; if (executableExists("doxygen")) { @@ -198,37 +205,48 @@ function generateDocs(/* boolean */ noFrame) console.log("Running Doxygen..."); childProcess.execSync(`"${doxygen}" "${doxygenTempConfig}"`, { stdio: 'inherit', cwd: tempDir }); + const generatedDocsRoot = path.join(tempDir, "Documentation"); + const htmlOutputDir = path.join(generatedDocsRoot, "html"); + const makefilePath = path.join(htmlOutputDir, "Makefile"); + + // --- Makefile Execution (ONLY for docset) --- + // For a standard 'jake docs', we do NOT run make. + if (buildDocset && fs.existsSync(makefilePath)) { + console.log("Patching Makefile to use 'docsetutil' from PATH..."); + childProcess.execSync(`sed -i.bak 's|"\\$(XCODE_INSTALL_DIR)"/usr/bin/docsetutil|docsetutil|' "${makefilePath}"`); + + console.log("Building docset with 'make'..."); + childProcess.execSync('make', { stdio: 'inherit', cwd: htmlOutputDir }); + } + // --- Post-processing --- console.log("Post-processing generated documentation..."); const postProcessorsDir = path.join(documentationDir, "postprocess"); processors = fs.readdirSync(postProcessorsDir).sort(); - // ** THE FIX IS HERE ** - // Doxygen creates a 'Documentation' subdirectory inside its CWD (the tempDir). - const generatedDocsRoot = path.join(tempDir, "Documentation"); - const htmlOutputDir = path.join(generatedDocsRoot, "html"); - for (const processor of processors) { const processorPath = path.join(postProcessorsDir, processor); - // Pass the correct htmlOutputDir to the post-processing scripts childProcess.execSync(`"${processorPath}" "${projectRoot}" "${htmlOutputDir}"`, { stdio: 'inherit', cwd: tempDir }); } - // --- Final Installation: Create Build/Documentation/html structure --- - if (fs.existsSync(htmlOutputDir)) { + // --- Final Installation --- + if (fs.existsSync(generatedDocsRoot)) { if (fs.existsSync($DOCUMENTATION_BUILD)) { fs.rmSync($DOCUMENTATION_BUILD, { recursive: true, force: true }); } - fs.mkdirSync($DOCUMENTATION_BUILD, { recursive: true }); - - // Move the entire generated 'Documentation' folder (which contains html) - // to the final build location. This preserves the structure for 'docset'. - fs.renameSync(generatedDocsRoot, path.join($BUILD_DIR, "Documentation")); + fs.renameSync(generatedDocsRoot, $DOCUMENTATION_BUILD); + // Manually copy the custom CSS file const finalHtmlPath = path.join($DOCUMENTATION_BUILD, "html"); + const customCSS = path.join(documentationDir, "doxygen.css"); + if (fs.existsSync(customCSS)) { + console.log("Applying custom stylesheet..."); + fs.copyFileSync(customCSS, path.join(finalHtmlPath, "doxygen.css")); + } + console.log("Documentation successfully built in " + finalHtmlPath); } else { - console.error("Doxygen or post-processing failed to produce the 'html' directory."); + console.error("Doxygen or post-processing failed to produce the 'Documentation' directory."); } } catch (e) { console.error("An error occurred during documentation generation:", e.message); diff --git a/Tools/Documentation/postprocess/003.markdown_readme.sh b/Tools/Documentation/postprocess/003.markdown_readme.sh index 68ea55702..2053efa68 100755 --- a/Tools/Documentation/postprocess/003.markdown_readme.sh +++ b/Tools/Documentation/postprocess/003.markdown_readme.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # # Moves the generated README.html to be the main index page of the documentation. -# CWD is the main temporary build directory. +# NOTE: This step is being skipped to allow the Doxygen-generated index to be the default main page. # # ARGUMENTS: # $1 - The absolute path to the project root. @@ -10,12 +10,13 @@ # Corrected path to the support script source "$1/Tools/Documentation/support/processor_setup.sh" -processor_msg "Installing custom main documentation page..." +processor_msg "Installing custom main documentation page... (SKIPPED)" -# The README.html was generated in the root of our CWD (the temp dir) -if [ -f "README.html" ]; then - # The main doxygen page is index.html. We replace it with our README. - mv "README.html" "$2/index.html" -else - processor_msg "Warning: README.html not found, cannot create main page." "yellow" -fi +# The original build process used the project README as the main index. +# The 'mv' command below is commented out to prevent this from happening. +# +# if [ -f "README.html" ]; then +# mv "README.html" "$2/index.html" +# else +# processor_msg "Warning: README.html not found, cannot create main page." "yellow" +# fi From 89b3fb003ca18cd804099ce5338fe29572188c1f Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 21 Jun 2025 17:29:31 +0200 Subject: [PATCH 5/6] formatting --- Jakefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Jakefile b/Jakefile index 17a843f67..f79b88ea2 100644 --- a/Jakefile +++ b/Jakefile @@ -155,13 +155,6 @@ function executableExists(command) { } } -// =========================================================================== -// -// THIS IS THE FINAL, CORRECT VERSION. -// IT CORRECTLY HANDLES THE 'docs' and 'docset' TASKS SEPARATELY. -// -// =========================================================================== - function generateDocs(/* boolean */ noFrame, /* boolean */ buildDocset = false) { var doxygen = null; From c7e850b95fc724d8fcbb097fb6745777b895efcb Mon Sep 17 00:00:00 2001 From: daboe01 Date: Sat, 21 Jun 2025 18:09:19 +0200 Subject: [PATCH 6/6] fixed: accidentally removed markdown install instructions --- Tools/Documentation/preprocess/001.markdown_readme.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Tools/Documentation/preprocess/001.markdown_readme.sh b/Tools/Documentation/preprocess/001.markdown_readme.sh index 752a2d5b7..dc01a4e98 100755 --- a/Tools/Documentation/preprocess/001.markdown_readme.sh +++ b/Tools/Documentation/preprocess/001.markdown_readme.sh @@ -17,5 +17,8 @@ if [ -n "$markdown" ]; then "$markdown" "$1/README.markdown" > "README.html" else processor_msg "markdown binary is not installed, documentation cannot be generated." "red" + echo "On Mac OS X, install brew with the following command line:" + echo ' ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"' + echo "Then use 'brew install markdown' from the command line to install markdown." exit 1 fi