feat: implement --emoji flag and MARKITECT_EMOJI environment variable - Issue #37

Add comprehensive emoji preference support to complement existing --ascii flag:

🎯 Core Features:
• Add --emoji flag to visualization tools (visualize_schema.py, schema_summary.py)
• Implement MARKITECT_EMOJI environment variable support
• Maintain backward compatibility with existing --ascii flag behavior
• Establish proper priority: CLI flags > environment variables > defaults

🏗️ Architecture:
• Create shared emoji_utils.py module for centralized logic
• Implement determine_output_mode() for standardized preference resolution
• Add add_emoji_arguments() for consistent argument parser setup
• Follow DRY principle - eliminate duplicate code between tools

🧪 Testing:
• 18 comprehensive tests covering all functionality
• Basic flag tests: existence, mutual exclusivity, defaults, precedence
• Environment variable tests: recognition, case handling, CLI overrides
• Configuration integration tests: system compatibility, error handling
• All 1337 project tests pass (no regressions)

💡 User Experience:
• Consistent behavior across all MarkiTect visualization tools
• Multiple preference setting methods (CLI flags, environment variables)
• Robust error handling with sensible defaults (emoji by default)
• Clear help documentation and discoverable usage patterns

🔧 Implementation Details:
• Mutually exclusive argument groups prevent conflicting flags
• Case-insensitive environment variable processing
• Valid false values: 'false', 'f', '0' - all others default to emoji
• Comprehensive documentation with usage examples

The implementation follows TDD principles and MarkiTect architectural
patterns, ensuring high quality and maintainability while delivering
enhanced usability features.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-10-06 17:46:54 +02:00
parent 9fc5b0d21e
commit e46e97801d
7 changed files with 936 additions and 5 deletions

119
tools/emoji_utils.py Normal file
View File

@@ -0,0 +1,119 @@
"""
Shared utilities for emoji/ASCII output mode handling - Issue #37
This module provides common functionality for handling emoji vs ASCII output
preferences across different MarkiTect tools. It implements the standardized
approach for emoji preference handling with proper priority management.
Priority Order:
1. CLI flags (--ascii or --emoji) - highest priority
2. MARKITECT_EMOJI environment variable - medium priority
3. Default to emoji output - fallback behavior
Environment Variable Support:
- MARKITECT_EMOJI=true/false (case-insensitive)
- Valid false values: 'false', 'f', '0'
- Invalid values default to emoji output (true)
Usage:
from emoji_utils import determine_output_mode, add_emoji_arguments
parser = argparse.ArgumentParser(description='My tool')
add_emoji_arguments(parser)
args = parser.parse_args()
use_ascii = determine_output_mode(args)
"""
import os
def determine_output_mode(args):
"""
Determine whether to use ASCII or emoji output based on CLI args and env.
This function implements the standardized priority logic for emoji/ASCII
mode selection across MarkiTect tools. It respects user preferences set
via CLI flags or environment variables, with appropriate fallback behavior.
Priority order (highest to lowest):
1. CLI flags (--ascii or --emoji) - explicit user choice
2. MARKITECT_EMOJI environment variable - persistent user preference
3. Default to emoji output - engaging default behavior
Environment Variable Handling:
- MARKITECT_EMOJI is processed case-insensitively
- Valid false values: 'false', 'f', '0'
- All other values (including invalid ones) default to emoji mode
- This provides robust fallback behavior for configuration errors
Args:
args (argparse.Namespace): Parsed command line arguments containing
'ascii' and 'emoji' boolean attributes from add_emoji_arguments()
Returns:
bool: True if ASCII mode should be used, False for emoji mode
Example:
>>> args = parser.parse_args(['--ascii'])
>>> determine_output_mode(args)
True
>>> # With MARKITECT_EMOJI=false environment variable set
>>> args = parser.parse_args([])
>>> determine_output_mode(args)
True
"""
# CLI flags take precedence
if args.ascii:
return True
if args.emoji:
return False
# No explicit flag, check environment variable
emoji_env = os.getenv('MARKITECT_EMOJI', 'true').lower()
return emoji_env in ['false', 'f', '0']
def add_emoji_arguments(parser):
"""
Add standardized emoji/ASCII output format arguments to an ArgumentParser.
This function adds the standard --ascii and --emoji flags to any
command-line tool, ensuring consistent behavior across MarkiTect. The flags
are configured as mutually exclusive to prevent conflicting output modes.
The added arguments integrate seamlessly with determine_output_mode() to
provide complete emoji preference handling.
Arguments Added:
- --ascii: Use ASCII characters only (no emojis)
- --emoji: Use emoji output (default behavior)
Args:
parser (argparse.ArgumentParser): The ArgumentParser instance to modify
Returns:
argparse._MutuallyExclusiveGroup: The mutually exclusive group
containing the emoji-related arguments for further customization
Example:
>>> import argparse
>>> parser = argparse.ArgumentParser(description='My tool')
>>> parser.add_argument('input_file', help='Input file path')
>>> emoji_group = add_emoji_arguments(parser)
>>> args = parser.parse_args(['file.txt', '--ascii'])
>>> print(f"Use ASCII: {determine_output_mode(args)}")
Use ASCII: True
Note:
This function must be called before parser.parse_args() to ensure
the arguments are available for parsing.
"""
format_group = parser.add_mutually_exclusive_group()
format_group.add_argument(
'--ascii', action='store_true',
help='Use ASCII characters only (no emojis)')
format_group.add_argument(
'--emoji', action='store_true',
help='Use emoji output (default)')
return format_group

View File

@@ -5,12 +5,15 @@ Schema summary tool - provides concise 4-line summary of markdown structure.
import sys
import argparse
import os
from pathlib import Path
# Add markitect to path
sys.path.insert(0, '.')
from markitect.schema_generator import SchemaGenerator
# Issue #37: Import shared emoji/ASCII output mode utilities
from emoji_utils import determine_output_mode, add_emoji_arguments
def generate_summary(file_path, ascii_mode=False):
"""Generate a concise 4-line summary of the document structure."""
@@ -89,13 +92,18 @@ def generate_summary(file_path, ascii_mode=False):
def main():
parser = argparse.ArgumentParser(description='Generate concise schema summary')
parser.add_argument('file_path', help='Path to the markdown file')
parser.add_argument('--ascii', action='store_true',
help='Use ASCII characters only (no emojis)')
# Issue #37: Add emoji/ASCII output format arguments
add_emoji_arguments(parser)
args = parser.parse_args()
# Issue #37: Determine output mode using shared utility
# Respects CLI flags and MARKITECT_EMOJI environment variable
use_ascii = determine_output_mode(args)
try:
summary_lines = generate_summary(args.file_path, args.ascii)
summary_lines = generate_summary(args.file_path, use_ascii)
for line in summary_lines:
print(line)
except Exception as e:

View File

@@ -6,12 +6,15 @@ Beautiful command-line visualization for markdown schema structure.
import sys
import json
import argparse
import os
from pathlib import Path
# Add markitect to path
sys.path.insert(0, '.')
from markitect.schema_generator import SchemaGenerator
# Issue #37: Import shared emoji/ASCII output mode utilities
from emoji_utils import determine_output_mode, add_emoji_arguments
def visualize_schema_structure(file_path, max_depth=None, ascii_only=False):
"""Create a beautiful tree visualization of the document structure."""
@@ -177,7 +180,9 @@ def main():
parser = argparse.ArgumentParser(description='Visualize markdown document schema structure')
parser.add_argument('file_path', help='Path to the markdown file')
parser.add_argument('--max-depth', type=int, help='Maximum heading depth to include')
parser.add_argument('--ascii', action='store_true', help='Use ASCII characters only (no colorful icons)')
# Issue #37: Add emoji/ASCII output format arguments
add_emoji_arguments(parser)
args = parser.parse_args()
@@ -185,7 +190,11 @@ def main():
print(f"File not found: {args.file_path}")
sys.exit(1)
visualize_schema_structure(args.file_path, args.max_depth, args.ascii)
# Issue #37: Determine output mode using shared utility
# Respects CLI flags and MARKITECT_EMOJI environment variable
use_ascii = determine_output_mode(args)
visualize_schema_structure(args.file_path, args.max_depth, use_ascii)
if __name__ == "__main__":
main()