mirror of
				https://github.com/kevinveenbirkenbach/computer-playbook.git
				synced 2025-11-03 19:58:14 +00:00 
			
		
		
		
	Implemented -v parameter
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,4 +1,5 @@
 | 
				
			|||||||
site.retry
 | 
					site.retry
 | 
				
			||||||
*__pycache__
 | 
					*__pycache__
 | 
				
			||||||
docs/*
 | 
					docs/*
 | 
				
			||||||
venv
 | 
					venv
 | 
				
			||||||
 | 
					*.log
 | 
				
			||||||
							
								
								
									
										10
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,12 +1,12 @@
 | 
				
			|||||||
.PHONY: install deinstall refresh
 | 
					.PHONY: install deinstall refresh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
install:
 | 
					install:
 | 
				
			||||||
	$(MAKE) -C sphinx html
 | 
						$(MAKE) -C sphinx html $(MAKEFLAGS)
 | 
				
			||||||
	$(MAKE) -C sphinx install
 | 
						$(MAKE) -C sphinx install $(MAKEFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
deinstall:
 | 
					deinstall:
 | 
				
			||||||
	$(MAKE) -C sphinx clean
 | 
						$(MAKE) -C sphinx clean $(MAKEFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
refresh:
 | 
					refresh:
 | 
				
			||||||
	$(MAKE) -C sphinx clean
 | 
						$(MAKE) -C sphinx clean $(MAKEFLAGS)
 | 
				
			||||||
	$(MAKE) -C sphinx html
 | 
						$(MAKE) -C sphinx html $(MAKEFLAGS)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,4 +22,9 @@ This command cleans the previous build and generates the updated documentation.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#### On Server
 | 
					#### On Server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
In your inventory file, enable the **Sphinx** role. When activated, the documentation will be automatically generated and deployed under the **docs** subdomain of your CyMaIS instance. This ensures your documentation is always current and easily accessible 🔄🌐.
 | 
					
 | 
				
			||||||
 | 
					### Debug
 | 
				
			||||||
 | 
					To debug and produce an .log execute:
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					pkgmgr shell cymais -c "make refresh SPHINXOPTS='-v -c .' 2>&1 | tee debug.log"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
@@ -1,12 +1,14 @@
 | 
				
			|||||||
# Configuration file for the Sphinx documentation builder.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# For the full list of built-in configuration values, see the documentation:
 | 
					 | 
				
			||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# -- Project information -----------------------------------------------------
 | 
					 | 
				
			||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Check if a verbose flag is present in the command line arguments.
 | 
				
			||||||
 | 
					if any(arg in sys.argv for arg in ["-v", "--verbose"]):
 | 
				
			||||||
 | 
					    logging_level = logging.DEBUG
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    logging_level = logging.INFO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logging.basicConfig(level=logging_level)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
sys.path.insert(0, os.path.abspath('.'))
 | 
					sys.path.insert(0, os.path.abspath('.'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,32 +17,20 @@ copyright = '2025, Kevin Veen-Birkenbach'
 | 
				
			|||||||
author = 'Kevin Veen-Birkenbach'
 | 
					author = 'Kevin Veen-Birkenbach'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# -- General configuration ---------------------------------------------------
 | 
					# -- General configuration ---------------------------------------------------
 | 
				
			||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
templates_path = ['templates']
 | 
					templates_path = ['templates']
 | 
				
			||||||
exclude_patterns = ['docs', 'venv', 'venv/**']
 | 
					exclude_patterns = ['docs', 'venv', 'venv/**']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# -- Options for HTML output -------------------------------------------------
 | 
					# -- Options for HTML output -------------------------------------------------
 | 
				
			||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
html_theme = 'sphinxawesome_theme'
 | 
					html_theme = 'sphinxawesome_theme'
 | 
				
			||||||
html_static_path = ['static']
 | 
					html_static_path = ['static']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
html_sidebars = {
 | 
					html_sidebars = {
 | 
				
			||||||
    '**': [
 | 
					    '**': [
 | 
				
			||||||
        #'globaltoc.html',
 | 
					 | 
				
			||||||
        # 'relations.html',
 | 
					 | 
				
			||||||
        # 'sourcelink.html',
 | 
					 | 
				
			||||||
        'structure.html',  # Include your custom template
 | 
					        'structure.html',  # Include your custom template
 | 
				
			||||||
        # 'searchbox.html',
 | 
					 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
html_theme_options = {
 | 
					html_theme_options = {
 | 
				
			||||||
    # 'fixed_sidebar': True,
 | 
					 | 
				
			||||||
    "show_prev_next": False,
 | 
					    "show_prev_next": False,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -73,6 +63,3 @@ def setup(app):
 | 
				
			|||||||
        if directive is not None:
 | 
					        if directive is not None:
 | 
				
			||||||
            directive.optional_arguments = 10
 | 
					            directive.optional_arguments = 10
 | 
				
			||||||
    return {'version': '1.0', 'parallel_read_safe': True}
 | 
					    return {'version': '1.0', 'parallel_read_safe': True}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,17 +1,68 @@
 | 
				
			|||||||
import os
 | 
					import os
 | 
				
			||||||
from sphinx.util import logging
 | 
					import sys
 | 
				
			||||||
 | 
					import logging as std_logging  # Use the standard logging module
 | 
				
			||||||
 | 
					from sphinx.util import logging  # Sphinx logging is used elsewhere if needed
 | 
				
			||||||
from docutils.parsers.rst import Directive
 | 
					from docutils.parsers.rst import Directive
 | 
				
			||||||
from .nav_utils import natural_sort_key, extract_headings_from_file, group_headings, sort_tree, MAX_HEADING_LEVEL, DEFAULT_MAX_NAV_DEPTH
 | 
					from .nav_utils import natural_sort_key, extract_headings_from_file, group_headings, sort_tree, MAX_HEADING_LEVEL, DEFAULT_MAX_NAV_DEPTH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger = logging.getLogger(__name__)
 | 
					# Use standard logging to set the level based on command-line args.
 | 
				
			||||||
 | 
					logger = std_logging.getLogger(__name__)
 | 
				
			||||||
 | 
					if any(arg in sys.argv for arg in ["-v", "--verbose"]):
 | 
				
			||||||
 | 
					    logger.setLevel(std_logging.DEBUG)
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    logger.setLevel(std_logging.INFO)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEFAULT_MAX_NAV_DEPTH = 4
 | 
					DEFAULT_MAX_NAV_DEPTH = 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def postprocess_current(nodes, current_file, current_anchor):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Recursively process the tree nodes in post-order.
 | 
				
			||||||
 | 
					    If a node or any child node matches the current file and anchor,
 | 
				
			||||||
 | 
					    mark that node as current.
 | 
				
			||||||
 | 
					    Returns True if the current subtree contains a current node.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    found_in_subtree = False
 | 
				
			||||||
 | 
					    for node in nodes:
 | 
				
			||||||
 | 
					        # Process children first (post-order)
 | 
				
			||||||
 | 
					        child_found = False
 | 
				
			||||||
 | 
					        if 'children' in node and node['children']:
 | 
				
			||||||
 | 
					            child_found = postprocess_current(node['children'], current_file, current_anchor)
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Get the file and anchor for the current node, trimming trailing slashes and whitespace.
 | 
				
			||||||
 | 
					        node_file = node.get('link', '').rstrip('/')
 | 
				
			||||||
 | 
					        node_anchor = node.get('anchor', '').strip()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Debug: output the current node's values and the comparison values.
 | 
				
			||||||
 | 
					        logger.debug("Checking node: text=%s, link=%s, anchor=%s", 
 | 
				
			||||||
 | 
					                     node.get('text', ''),
 | 
				
			||||||
 | 
					                     node_file,
 | 
				
			||||||
 | 
					                     node_anchor)
 | 
				
			||||||
 | 
					        logger.debug("Comparing with current_file=%s, current_anchor=%s", 
 | 
				
			||||||
 | 
					                     current_file.rstrip('/'),
 | 
				
			||||||
 | 
					                     current_anchor.strip())
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Mark node as current if it exactly matches the current file and anchor.
 | 
				
			||||||
 | 
					        if node_file == current_file.rstrip('/') and node_anchor == current_anchor.strip():
 | 
				
			||||||
 | 
					            node['current'] = True
 | 
				
			||||||
 | 
					            logger.debug("Node '%s' marked as current (exact match).", node.get('text', ''))
 | 
				
			||||||
 | 
					            found = True
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            node['current'] = child_found
 | 
				
			||||||
 | 
					            if child_found:
 | 
				
			||||||
 | 
					                logger.debug("Node '%s' marked as current (child match).", node.get('text', ''))
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if node['current']:
 | 
				
			||||||
 | 
					            found_in_subtree = True
 | 
				
			||||||
 | 
					    return found_in_subtree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def add_local_file_headings(app, pagename, templatename, context, doctree):
 | 
					def add_local_file_headings(app, pagename, templatename, context, doctree):
 | 
				
			||||||
 | 
					    logger.debug("add_local_file_headings called with pagename: %s", pagename)
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    srcdir = app.srcdir
 | 
					    srcdir = app.srcdir
 | 
				
			||||||
    directory = os.path.dirname(pagename)
 | 
					    directory = os.path.dirname(pagename)
 | 
				
			||||||
    abs_dir = os.path.join(srcdir, directory)
 | 
					    abs_dir = os.path.join(srcdir, directory)
 | 
				
			||||||
    if not os.path.isdir(abs_dir):
 | 
					    if not os.path.isdir(abs_dir):
 | 
				
			||||||
        logger.warning(f"Directory {abs_dir} not found for page {pagename}.")
 | 
					        logger.warning("Directory %s not found for page %s.", abs_dir, pagename)
 | 
				
			||||||
        context['local_md_headings'] = []
 | 
					        context['local_md_headings'] = []
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,6 +92,25 @@ def add_local_file_headings(app, pagename, templatename, context, doctree):
 | 
				
			|||||||
            })
 | 
					            })
 | 
				
			||||||
    tree = group_headings(file_items)
 | 
					    tree = group_headings(file_items)
 | 
				
			||||||
    sort_tree(tree)
 | 
					    sort_tree(tree)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logger.debug("Generated tree: %s", tree)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Determine current file and anchor.
 | 
				
			||||||
 | 
					    # This implementation assumes that if an anchor is present, it is appended to pagename as "#anchor".
 | 
				
			||||||
 | 
					    if '#' in pagename:
 | 
				
			||||||
 | 
					        current_file, current_anchor = pagename.split('#', 1)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        current_file, current_anchor = pagename, ''
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    logger.debug("Current file: %s, Current anchor: %s", current_file, current_anchor)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Postprocess the tree: bubble up the 'current' flag from children to parents.
 | 
				
			||||||
 | 
					    if current_anchor:
 | 
				
			||||||
 | 
					        postprocess_current(tree, current_file, current_anchor)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        logger.debug("No anchor provided; skipping current marking.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logger.debug("Final tree after postprocessing: %s", tree)
 | 
				
			||||||
    context['local_md_headings'] = tree
 | 
					    context['local_md_headings'] = tree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup(app):
 | 
					def setup(app):
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user