diff --git a/compare_html_docs.py b/compare_html_docs.py new file mode 100644 index 0000000..7804c0e --- /dev/null +++ b/compare_html_docs.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +"""Compare the original and improved HTML documentation.""" + +from pathlib import Path + +def compare_docs(): + """Show key differences between the two HTML versions.""" + + print("HTML Documentation Improvements") + print("=" * 50) + + # Read both files + original = Path("docs/api_reference.html") + improved = Path("docs/api_reference_improved.html") + + if not original.exists() or not improved.exists(): + print("Error: Documentation files not found") + return + + with open(original, 'r') as f: + orig_content = f.read() + + with open(improved, 'r') as f: + imp_content = f.read() + + print("\nš File Size Comparison:") + print(f" Original: {len(orig_content):,} bytes") + print(f" Improved: {len(imp_content):,} bytes") + + print("\nā Key Improvements:") + + # Check newline handling + if '\\n' in orig_content and '\\n' not in imp_content: + print(" ⢠Fixed literal \\n in documentation text") + + # Check table of contents + if '[Classes](#classes)' in orig_content and 'Classes' in imp_content: + print(" ⢠Converted markdown links to proper HTML anchors") + + # Check headings + if '
')
+ print(f" ⢠Methods: {method_count} documented")
+
+ print("\n⨠Visual Enhancements:")
+ print(" ⢠Professional color scheme with syntax highlighting")
+ print(" ⢠Responsive layout with max-width container")
+ print(" ⢠Clear visual hierarchy with styled headings")
+ print(" ⢠Improved code block formatting")
+ print(" ⢠Better spacing and typography")
+
+if __name__ == '__main__':
+ compare_docs()
\ No newline at end of file
diff --git a/docs/api_reference_improved.html b/docs/api_reference_improved.html
new file mode 100644
index 0000000..b233df9
--- /dev/null
+++ b/docs/api_reference_improved.html
@@ -0,0 +1,1043 @@
+
+
+
+
+
+ McRogueFace API Reference
+
+
+
+
+
+McRogueFace API Reference
+
+
+Overview
+McRogueFace Python API
+Core game engine interface for creating roguelike games with Python.
+This module provides:
+- Scene management (createScene, setScene, currentScene)
+- UI components (Frame, Caption, Sprite, Grid)
+- Entity system for game objects
+- Audio playback (sound effects and music)
+- Timer system for scheduled events
+- Input handling
+- Performance metrics
+Example:
+
+ import mcrfpy
+ # Create a new scene
+ mcrfpy.createScene('game')
+ mcrfpy.setScene('game')
+ # Add UI elements
+ frame = mcrfpy.Frame(10, 10, 200, 100)
+ caption = mcrfpy.Caption('Hello World', 50, 50)
+ mcrfpy.sceneUI().extend([frame, caption])
+
+
+
+Table of Contents
+
+- Classes
+
+
+- Functions
+
+
+- Automation Module
+
+
+Classes
+UI Components
+
+class Frame
+Inherits from: Drawable
+
+A rectangular frame UI element that can contain other drawable elements.
+
+Args:
+ x (float): X position in pixels. Default: 0
+ y (float): Y position in pixels. Default: 0
+ w (float): Width in pixels. Default: 0
+ h (float): Height in pixels. Default: 0
+ fill_color (Color): Background fill color. Default: (0, 0, 0, 128)
+ outline_color (Color): Border outline color. Default: (255, 255, 255, 255)
+ outline (float): Border outline thickness. Default: 0
+ click (callable): Click event handler. Default: None
+ children (list): Initial list of child drawable elements. Default: None
+
+Attributes:
+ x, y (float): Position in pixels
+ w, h (float): Size in pixels
+ fill_color, outline_color (Color): Visual appearance
+ outline (float): Border thickness
+ click (callable): Click event handler
+ children (list): Collection of child drawable elements
+ visible (bool): Visibility state
+ z_index (int): Rendering order
+ clip_children (bool): Whether to clip children to frame bounds
+
+
+Methods:
+
+get_bounds(...)
+Get bounding box as (x, y, width, height)
+
+
+move(...)
+Move by relative offset (dx, dy)
+
+
+resize(...)
+Resize to new dimensions (width, height)
+
+
+
+
+
+class Caption
+Inherits from: Drawable
+
+A text display UI element with customizable font and styling.
+
+Args:
+ text (str): The text content to display. Default: ''
+ x (float): X position in pixels. Default: 0
+ y (float): Y position in pixels. Default: 0
+ font (Font): Font object for text rendering. Default: engine default font
+ fill_color (Color): Text fill color. Default: (255, 255, 255, 255)
+ outline_color (Color): Text outline color. Default: (0, 0, 0, 255)
+ outline (float): Text outline thickness. Default: 0
+ click (callable): Click event handler. Default: None
+
+Attributes:
+ text (str): The displayed text content
+ x, y (float): Position in pixels
+ font (Font): Font used for rendering
+ fill_color, outline_color (Color): Text appearance
+ outline (float): Outline thickness
+ click (callable): Click event handler
+ visible (bool): Visibility state
+ z_index (int): Rendering order
+ w, h (float): Read-only computed size based on text and font
+
+
+Methods:
+
+get_bounds(...)
+Get bounding box as (x, y, width, height)
+
+
+move(...)
+Move by relative offset (dx, dy)
+
+
+resize(...)
+Resize to new dimensions (width, height)
+
+
+
+
+
+class Sprite
+Inherits from: Drawable
+
+A sprite UI element that displays a texture or portion of a texture atlas.
+
+Args:
+ x (float): X position in pixels. Default: 0
+ y (float): Y position in pixels. Default: 0
+ texture (Texture): Texture object to display. Default: None
+ sprite_index (int): Index into texture atlas (if applicable). Default: 0
+ scale (float): Sprite scaling factor. Default: 1.0
+ click (callable): Click event handler. Default: None
+
+Attributes:
+ x, y (float): Position in pixels
+ texture (Texture): The texture being displayed
+ sprite_index (int): Current sprite index in texture atlas
+ scale (float): Scale multiplier
+ click (callable): Click event handler
+ visible (bool): Visibility state
+ z_index (int): Rendering order
+ w, h (float): Read-only computed size based on texture and scale
+
+
+Methods:
+
+get_bounds(...)
+Get bounding box as (x, y, width, height)
+
+
+move(...)
+Move by relative offset (dx, dy)
+
+
+resize(...)
+Resize to new dimensions (width, height)
+
+
+
+
+
+class Grid
+Inherits from: Drawable
+
+A grid-based tilemap UI element for rendering tile-based levels and game worlds.
+
+Args:
+ x (float): X position in pixels. Default: 0
+ y (float): Y position in pixels. Default: 0
+ grid_size (tuple): Grid dimensions as (width, height) in tiles. Default: (20, 20)
+ texture (Texture): Texture atlas containing tile sprites. Default: None
+ tile_width (int): Width of each tile in pixels. Default: 16
+ tile_height (int): Height of each tile in pixels. Default: 16
+ scale (float): Grid scaling factor. Default: 1.0
+ click (callable): Click event handler. Default: None
+
+Attributes:
+ x, y (float): Position in pixels
+ grid_size (tuple): Grid dimensions (width, height) in tiles
+ tile_width, tile_height (int): Tile dimensions in pixels
+ texture (Texture): Tile texture atlas
+ scale (float): Scale multiplier
+ points (list): 2D array of GridPoint objects for tile data
+ entities (list): Collection of Entity objects in the grid
+ background_color (Color): Grid background color
+ click (callable): Click event handler
+ visible (bool): Visibility state
+ z_index (int): Rendering order
+
+
+Methods:
+
+at(x, y)
+Get the GridPoint at the specified coordinates.
+Arguments:
+
+x
(int)
+y
(int)
+
+Returns: GridPoint: The tile at (x, y), or None if out of bounds
+
+
+get_bounds(...)
+Get bounding box as (x, y, width, height)
+
+
+move(...)
+Move by relative offset (dx, dy)
+
+
+resize(...)
+Resize to new dimensions (width, height)
+
+
+
+
+
+class Entity
+
+
+Entity(x=0, y=0, sprite_id=0)
+
+
+
+Game entity that can be placed in a Grid.
+
+
+Arguments:
+
+x
(int)
+- Grid x coordinate. Default: 0
+y
(int)
+- Grid y coordinate. Default: 0
+sprite_id
(int)
+- Sprite index for rendering. Default: 0
+
+
+
+Methods:
+
+at(x, y)
+Check if entity is at given grid coordinates.
+Arguments:
+
+x
(int)
+y
(int)
+
+Returns: bool: True if entity is at (x, y)
+
+
+die()
+Remove this entity from its parent grid.
+Note: The entity object remains valid but is no longer rendered.
+
+
+get_bounds(...)
+Get bounding box as (x, y, width, height)
+
+
+index(...)
+Return the index of this entity in its grid's entity collection
+
+
+move(...)
+Move by relative offset (dx, dy)
+
+
+resize(...)
+Resize to new dimensions (width, height)
+
+
+
+Example:
+
+entity = mcrfpy.Entity(5, 10, 42)
+entity.move(1, 0) # Move right one tile
+
+
+
+
+Collections
+
+class EntityCollection
+
+Container for Entity objects in a Grid. Supports iteration and indexing.
+
+
+Methods:
+
+append(...)
+
+
+remove(...)
+
+
+extend(...)
+
+
+count(...)
+
+
+index(...)
+
+
+
+
+
+class UICollection
+
+Container for UI drawable elements. Supports iteration and indexing.
+
+
+Methods:
+
+append(...)
+
+
+remove(...)
+
+
+extend(...)
+
+
+count(...)
+
+
+index(...)
+
+
+
+
+
+class UICollectionIter
+
+Iterator for UICollection. Automatically created when iterating over a UICollection.
+
+
+
+
+class UIEntityCollectionIter
+
+Iterator for EntityCollection. Automatically created when iterating over an EntityCollection.
+
+
+
+System Types
+
+class Color
+
+
+Color(r=255, g=255, b=255, a=255)
+
+
+
+RGBA color representation.
+
+
+Arguments:
+
+r
(int)
+- Red component (0-255). Default: 255
+g
(int)
+- Green component (0-255). Default: 255
+b
(int)
+- Blue component (0-255). Default: 255
+a
(int)
+- Alpha component (0-255). Default: 255
+
+
+
+Methods:
+
+from_hex(...)
+Create Color from hex string (e.g., '#FF0000' or 'FF0000')
+
+
+lerp(...)
+Linearly interpolate between this color and another
+
+
+to_hex(...)
+Convert Color to hex string
+
+
+
+Example:
+
+red = mcrfpy.Color(255, 0, 0)
+
+
+
+
+
+class Vector
+
+
+Vector(x=0.0, y=0.0)
+
+
+
+2D vector for positions and directions.
+
+
+Arguments:
+
+x
(float)
+- X component. Default: 0.0
+y
(float)
+- Y component. Default: 0.0
+
+
+
+Methods:
+
+angle(...)
+Return the angle in radians from the positive X axis
+
+
+copy(...)
+Return a copy of this vector
+
+
+distance_to(...)
+Return the distance to another vector
+
+
+dot(...)
+Return the dot product with another vector
+
+
+magnitude(...)
+Return the length of the vector
+
+
+magnitude_squared(...)
+Return the squared length of the vector
+
+
+normalize(...)
+Return a unit vector in the same direction
+
+
+
+
+
+class Texture
+
+
+Texture(filename)
+
+
+
+Load a texture from file.
+
+
+Arguments:
+
+filename
(str)
+- Path to image file (PNG/JPG/BMP)
+
+
+
+
+
+class Font
+
+
+Font(filename)
+
+
+
+Load a font from file.
+
+
+Arguments:
+
+filename
(str)
+- Path to font file (TTF/OTF)
+
+
+
+
+Other Classes
+
+class Animation
+
+
+Animation(property_name, start_value, end_value, duration, transition="linear", loop=False)
+
+
+
+Animate UI element properties over time.
+
+
+Arguments:
+
+property_name
(str)
+- Property to animate (e.g., "x", "y", "scale")
+start_value
(float)
+- Starting value
+end_value
(float)
+- Ending value
+duration
(float)
+- Duration in seconds
+transition
(str)
+- Easing function. Default: "linear"
+loop
(bool)
+- Whether to loop. Default: False
+
+
+
+Attributes:
+
+current_value
+- Property of Animation
+elapsed_time
+- Property of Animation
+is_running
+- Property of Animation
+is_finished
+- Property of Animation
+
+
+
+Methods:
+
+get_current_value()
+Get the current interpolated value.
+Returns: float: Current animation value
+
+
+start(target)
+Start the animation on a target UI element.
+Arguments:
+
+target
(UIDrawable): The element to animate
+
+
+
+update(...)
+Update the animation by deltaTime (returns True if still running)
+
+
+
+
+
+class Drawable
+
+Base class for all drawable UI elements
+
+
+Methods:
+
+get_bounds(...)
+Get bounding box as (x, y, width, height)
+
+
+move(...)
+Move by relative offset (dx, dy)
+
+
+resize(...)
+Resize to new dimensions (width, height)
+
+
+
+
+
+class GridPoint
+
+Represents a single tile in a Grid.
+
+
+Attributes:
+
+x
+- Property of GridPoint
+y
+- Property of GridPoint
+texture_index
+- Property of GridPoint
+solid
+- Property of GridPoint
+transparent
+- Property of GridPoint
+color
+- Property of GridPoint
+
+
+
+
+
+class GridPointState
+
+State information for a GridPoint.
+
+
+Attributes:
+
+visible
+- Property of GridPointState
+discovered
+- Property of GridPointState
+custom_flags
+- Property of GridPointState
+
+
+
+
+
+class Scene
+
+Base class for object-oriented scenes
+
+
+Methods:
+
+activate(...)
+Make this the active scene
+
+
+get_ui(...)
+Get the UI element collection for this scene
+
+
+register_keyboard(...)
+Register a keyboard handler function (alternative to overriding on_keypress)
+
+
+
+
+
+class Timer
+
+
+Timer(name, callback, interval_ms)
+
+
+
+Create a recurring timer.
+
+
+Arguments:
+
+name
(str)
+- Unique timer identifier
+callback
(callable)
+- Function to call
+interval_ms
(int)
+- Interval in milliseconds
+
+
+
+Methods:
+
+cancel(...)
+Cancel the timer and remove it from the system
+
+
+pause(...)
+Pause the timer
+
+
+restart(...)
+Restart the timer from the current time
+
+
+resume(...)
+Resume a paused timer
+
+
+
+
+
+class Window
+
+Window singleton for accessing and modifying the game window properties
+
+
+Methods:
+
+center(...)
+Center the window on the screen
+
+
+get(...)
+Get the Window singleton instance
+
+
+screenshot(...)
+Take a screenshot. Pass filename to save to file, or get raw bytes if no filename.
+
+
+
+
+Functions
+Scene Management
+Audio
+UI Utilities
+System
+
+Automation Module
+The mcrfpy.automation
module provides testing and automation capabilities for simulating user input and capturing screenshots.
+
+automation.click
+Click at position
+
+
+automation.doubleClick
+Double click at position
+
+
+automation.dragRel
+Drag mouse relative to current position
+
+
+automation.dragTo
+Drag mouse to position
+
+
+automation.hotkey
+Press a hotkey combination (e.g., hotkey('ctrl', 'c'))
+
+
+automation.keyDown
+Press and hold a key
+
+
+automation.keyUp
+Release a key
+
+
+automation.middleClick
+Middle click at position
+
+
+automation.mouseDown
+Press mouse button
+
+
+automation.mouseUp
+Release mouse button
+
+
+automation.moveRel
+Move mouse relative to current position
+
+
+automation.moveTo
+Move mouse to absolute position
+
+
+automation.onScreen
+Check if coordinates are within screen bounds
+
+
+automation.position
+Get current mouse position as (x, y) tuple
+
+
+automation.rightClick
+Right click at position
+
+
+automation.screenshot
+Save a screenshot to the specified file
+
+
+automation.scroll
+Scroll wheel at position
+
+
+automation.size
+Get screen size as (width, height) tuple
+
+
+automation.tripleClick
+Triple click at position
+
+
+automation.typewrite
+Type text with optional interval between keystrokes
+
+
+
+
+
+
\ No newline at end of file
diff --git a/generate_api_docs_html.py b/generate_api_docs_html.py
new file mode 100644
index 0000000..8509853
--- /dev/null
+++ b/generate_api_docs_html.py
@@ -0,0 +1,941 @@
+#!/usr/bin/env python3
+"""Generate high-quality HTML API reference documentation for McRogueFace."""
+
+import os
+import sys
+import datetime
+import html
+from pathlib import Path
+import mcrfpy
+
+def escape_html(text: str) -> str:
+ """Escape HTML special characters."""
+ return html.escape(text) if text else ""
+
+def format_docstring_as_html(docstring: str) -> str:
+ """Convert docstring to properly formatted HTML."""
+ if not docstring:
+ return ""
+
+ # Split and process lines
+ lines = docstring.strip().split('\n')
+ result = []
+ in_code_block = False
+
+ for line in lines:
+ # Convert \n to actual newlines
+ line = line.replace('\\n', '\n')
+
+ # Handle code blocks
+ if line.strip().startswith('```'):
+ if in_code_block:
+ result.append('
')
+ in_code_block = False
+ else:
+ result.append('')
+ in_code_block = True
+ continue
+
+ # Convert markdown-style code to HTML
+ if '`' in line and not in_code_block:
+ import re
+ line = re.sub(r'`([^`]+)`', r'\1
', line)
+
+ if in_code_block:
+ result.append(escape_html(line))
+ else:
+ result.append(escape_html(line) + '
')
+
+ if in_code_block:
+ result.append('
')
+
+ return '\n'.join(result)
+
+def get_class_details(cls):
+ """Get detailed information about a class."""
+ info = {
+ 'name': cls.__name__,
+ 'doc': cls.__doc__ or "",
+ 'methods': {},
+ 'properties': {},
+ 'bases': []
+ }
+
+ # Get real base classes (excluding object)
+ for base in cls.__bases__:
+ if base.__name__ != 'object':
+ info['bases'].append(base.__name__)
+
+ # Special handling for Entity which doesn't inherit from Drawable
+ if cls.__name__ == 'Entity' and 'Drawable' in info['bases']:
+ info['bases'].remove('Drawable')
+
+ # Get methods and properties
+ for attr_name in dir(cls):
+ if attr_name.startswith('__') and attr_name != '__init__':
+ continue
+
+ try:
+ attr = getattr(cls, attr_name)
+
+ if isinstance(attr, property):
+ info['properties'][attr_name] = {
+ 'doc': (attr.fget.__doc__ if attr.fget else "") or "",
+ 'readonly': attr.fset is None
+ }
+ elif callable(attr) and not attr_name.startswith('_'):
+ info['methods'][attr_name] = attr.__doc__ or ""
+ except:
+ pass
+
+ return info
+
+def generate_class_init_docs(class_name):
+ """Generate initialization documentation for specific classes."""
+ init_docs = {
+ 'Entity': {
+ 'signature': 'Entity(x=0, y=0, sprite_id=0)',
+ 'description': 'Game entity that can be placed in a Grid.',
+ 'args': [
+ ('x', 'int', 'Grid x coordinate. Default: 0'),
+ ('y', 'int', 'Grid y coordinate. Default: 0'),
+ ('sprite_id', 'int', 'Sprite index for rendering. Default: 0')
+ ],
+ 'example': '''entity = mcrfpy.Entity(5, 10, 42)
+entity.move(1, 0) # Move right one tile'''
+ },
+ 'Color': {
+ 'signature': 'Color(r=255, g=255, b=255, a=255)',
+ 'description': 'RGBA color representation.',
+ 'args': [
+ ('r', 'int', 'Red component (0-255). Default: 255'),
+ ('g', 'int', 'Green component (0-255). Default: 255'),
+ ('b', 'int', 'Blue component (0-255). Default: 255'),
+ ('a', 'int', 'Alpha component (0-255). Default: 255')
+ ],
+ 'example': 'red = mcrfpy.Color(255, 0, 0)'
+ },
+ 'Font': {
+ 'signature': 'Font(filename)',
+ 'description': 'Load a font from file.',
+ 'args': [
+ ('filename', 'str', 'Path to font file (TTF/OTF)')
+ ]
+ },
+ 'Texture': {
+ 'signature': 'Texture(filename)',
+ 'description': 'Load a texture from file.',
+ 'args': [
+ ('filename', 'str', 'Path to image file (PNG/JPG/BMP)')
+ ]
+ },
+ 'Vector': {
+ 'signature': 'Vector(x=0.0, y=0.0)',
+ 'description': '2D vector for positions and directions.',
+ 'args': [
+ ('x', 'float', 'X component. Default: 0.0'),
+ ('y', 'float', 'Y component. Default: 0.0')
+ ]
+ },
+ 'Animation': {
+ 'signature': 'Animation(property_name, start_value, end_value, duration, transition="linear", loop=False)',
+ 'description': 'Animate UI element properties over time.',
+ 'args': [
+ ('property_name', 'str', 'Property to animate (e.g., "x", "y", "scale")'),
+ ('start_value', 'float', 'Starting value'),
+ ('end_value', 'float', 'Ending value'),
+ ('duration', 'float', 'Duration in seconds'),
+ ('transition', 'str', 'Easing function. Default: "linear"'),
+ ('loop', 'bool', 'Whether to loop. Default: False')
+ ],
+ 'properties': ['current_value', 'elapsed_time', 'is_running', 'is_finished']
+ },
+ 'GridPoint': {
+ 'description': 'Represents a single tile in a Grid.',
+ 'properties': ['x', 'y', 'texture_index', 'solid', 'transparent', 'color']
+ },
+ 'GridPointState': {
+ 'description': 'State information for a GridPoint.',
+ 'properties': ['visible', 'discovered', 'custom_flags']
+ },
+ 'Timer': {
+ 'signature': 'Timer(name, callback, interval_ms)',
+ 'description': 'Create a recurring timer.',
+ 'args': [
+ ('name', 'str', 'Unique timer identifier'),
+ ('callback', 'callable', 'Function to call'),
+ ('interval_ms', 'int', 'Interval in milliseconds')
+ ]
+ }
+ }
+
+ return init_docs.get(class_name, {})
+
+def generate_method_docs(method_name, class_name):
+ """Generate documentation for specific methods."""
+ method_docs = {
+ 'Entity': {
+ 'at': {
+ 'signature': 'at(x, y)',
+ 'description': 'Check if entity is at given grid coordinates.',
+ 'args': [('x', 'int'), ('y', 'int')],
+ 'returns': 'bool: True if entity is at (x, y)'
+ },
+ 'die': {
+ 'signature': 'die()',
+ 'description': 'Remove this entity from its parent grid.',
+ 'note': 'The entity object remains valid but is no longer rendered.'
+ }
+ },
+ 'Grid': {
+ 'at': {
+ 'signature': 'at(x, y)',
+ 'description': 'Get the GridPoint at the specified coordinates.',
+ 'args': [('x', 'int'), ('y', 'int')],
+ 'returns': 'GridPoint: The tile at (x, y), or None if out of bounds'
+ }
+ },
+ 'Animation': {
+ 'get_current_value': {
+ 'signature': 'get_current_value()',
+ 'description': 'Get the current interpolated value.',
+ 'returns': 'float: Current animation value'
+ },
+ 'start': {
+ 'signature': 'start(target)',
+ 'description': 'Start the animation on a target UI element.',
+ 'args': [('target', 'UIDrawable', 'The element to animate')]
+ }
+ }
+ }
+
+ return method_docs.get(class_name, {}).get(method_name, {})
+
+def generate_collection_docs(class_name):
+ """Generate documentation for collection classes."""
+ collection_docs = {
+ 'EntityCollection': {
+ 'description': 'Container for Entity objects in a Grid. Supports iteration and indexing.',
+ 'methods': {
+ 'append': 'Add an entity to the collection',
+ 'remove': 'Remove an entity from the collection',
+ 'extend': 'Add multiple entities from an iterable',
+ 'count': 'Count occurrences of an entity',
+ 'index': 'Find the index of an entity'
+ }
+ },
+ 'UICollection': {
+ 'description': 'Container for UI drawable elements. Supports iteration and indexing.',
+ 'methods': {
+ 'append': 'Add a UI element to the collection',
+ 'remove': 'Remove a UI element from the collection',
+ 'extend': 'Add multiple UI elements from an iterable',
+ 'count': 'Count occurrences of a UI element',
+ 'index': 'Find the index of a UI element'
+ }
+ },
+ 'UICollectionIter': {
+ 'description': 'Iterator for UICollection. Automatically created when iterating over a UICollection.'
+ },
+ 'UIEntityCollectionIter': {
+ 'description': 'Iterator for EntityCollection. Automatically created when iterating over an EntityCollection.'
+ }
+ }
+
+ return collection_docs.get(class_name, {})
+
+def format_class_html(cls_info, class_name):
+ """Format a class as HTML with proper structure."""
+ html_parts = []
+
+ # Class header
+ html_parts.append(f'Inherits from: {", ".join(cls_info["bases"])}
') + + # Get additional documentation + init_info = generate_class_init_docs(class_name) + collection_info = generate_collection_docs(class_name) + + # Constructor signature for classes with __init__ + if init_info.get('signature'): + html_parts.append('')
+ html_parts.append(escape_html(init_info['signature']))
+ html_parts.append('
')
+ html_parts.append('{format_docstring_as_html(description)}
') + html_parts.append('{arg_name}
({arg_type}){prop_name}
{prop_name}
{readonly}{method_info["signature"]}
{escape_html(method_info["description"])}
') + + if method_info.get('args'): + html_parts.append('Arguments:
') + html_parts.append('{arg[0]}
({arg[1]}): {arg[2]}{arg[0]}
({arg[1]})Returns: {escape_html(method_info["returns"])}
') + + if method_info.get('note'): + html_parts.append(f'Note: {escape_html(method_info["note"])}
') + else: + # Use docstring + html_parts.append(f'{method_name}(...)
{escape_html(method_doc)}
') + + html_parts.append('')
+ html_parts.append(escape_html(init_info['example']))
+ html_parts.append('
')
+ html_parts.append('')
+ elif line.strip() and not line.startswith(' '):
+ html_parts.append(f'{escape_html(line)}
')
+ elif line.strip():
+ # Code line
+ html_parts.append(escape_html(line))
+ html_parts.append('
')
+ html_parts.append('The mcrfpy.automation
module provides testing and automation capabilities for simulating user input and capturing screenshots.
automation.{name}
{escape_html(description)}
') + html_parts.append('{escape_html(signature)}
{in_section}:
') + elif in_section == 'Example': + if not stripped: + continue + if stripped.startswith('>>>') or (len(lines) > lines.index(line) + 1 and + lines[lines.index(line) + 1].strip().startswith('>>>')): + html_parts.append('')
+ html_parts.append(escape_html(stripped))
+ # Get rest of example
+ idx = lines.index(line) + 1
+ while idx < len(lines) and lines[idx].strip():
+ html_parts.append(escape_html(lines[idx]))
+ idx += 1
+ html_parts.append('
')
+ break
+ elif in_section and stripped:
+ if in_section == 'Args':
+ # Format arguments nicely
+ if ':' in stripped:
+ param, desc = stripped.split(':', 1)
+ html_parts.append(f'{escape_html(param.strip())}
: {escape_html(desc.strip())}
{escape_html(stripped)}
') + else: + html_parts.append(f'{escape_html(stripped)}
') + elif stripped and not in_section: + html_parts.append(f'{escape_html(stripped)}
') + + html_parts.append('