diff --git a/src/rocky_man/main.py b/src/rocky_man/main.py index 97d8e1a..253ec19 100644 --- a/src/rocky_man/main.py +++ b/src/rocky_man/main.py @@ -149,11 +149,6 @@ def process_version( logger.error(f"No man pages were successfully processed for version {version}") return False - # Link cross-references between man pages - logger.info("Linking cross-references...") - converter = ManPageConverter(version_output_dir) - converter.link_cross_references(all_man_files) - # Generate web pages logger.info("Generating web pages...") web_gen = WebGenerator(template_dir, config.output_dir) diff --git a/src/rocky_man/processor/converter.py b/src/rocky_man/processor/converter.py index 5f201e0..4b8ed06 100644 --- a/src/rocky_man/processor/converter.py +++ b/src/rocky_man/processor/converter.py @@ -73,6 +73,20 @@ class ManPageConverter: # Clean up HTML html = self._clean_html(html) + # Check if mandoc output indicates this is a symlink/redirect + # Pattern:
/usr/share/man/man8/target.8.gz
+ # or:
See the file /usr/share/man/man8/target.8.
+ symlink_match = re.search(r'
(?:See the file )?(/usr/share/man/man\d+[a-z]*/([^/]+)\.(\d+[a-z]*)(?:\.gz)?)\.
', html) + if not symlink_match: + # Try simpler pattern without "See the file" or period + symlink_match = re.search(r'
(/usr/share/man/man\d+[a-z]*/([^/<]+)\.(\d+[a-z]*)(?:\.gz)?)
', html) + + if symlink_match: + name = symlink_match.group(2) + section = symlink_match.group(3) + logger.info(f"{man_file.display_name} detected as symlink to {name}({section})") + html = self._generate_redirect_html({'name': name, 'section': section}) + # Store in ManFile object man_file.html_content = html @@ -187,87 +201,34 @@ class ManPageConverter: return html - def link_cross_references(self, man_files: List[ManFile]) -> None: - """Add hyperlinks to cross-references in SEE ALSO sections. - - Goes through all converted HTML files and converts man page references - like pty(4) into working hyperlinks. + def _generate_redirect_html(self, target_info: dict) -> str: + """Generate HTML for a symlink/redirect page. Args: - man_files: List of all converted ManFile objects + target_info: Dict with 'name' and 'section' of target man page + + Returns: + HTML fragment for redirect page """ - # Build lookup index: (name, section) -> relative_path - lookup = {} - for mf in man_files: - key = (mf.name.lower(), str(mf.section)) - if key not in lookup: - # Store the relative path from the version root - lookup[key] = f"{mf.package_name}/man{mf.section}/{mf.html_filename}" + name = target_info['name'] + section = target_info['section'] - logger.info(f"Linking cross-references across {len(man_files)} man pages...") + # Generate the relative path to the target man page + # Symlinks are in the same package, just different file names + target_filename = f"{name}.{section}.html" - # Process each man page HTML file - for man_file in man_files: - if not man_file.html_path or not man_file.html_path.exists(): - continue + # Generate simple redirect HTML with a working hyperlink + html = f'''''' - try: - # Read the HTML - with open(man_file.html_path, 'r', encoding='utf-8') as f: - html = f.read() + return html - # Find and replace man page references - # Mandoc outputs references as: name(section) - # Pattern matches both name(section) and plain name(section) - pattern = r'([\w\-_.]+)\((\d+[a-z]*)\)|\b([\w\-_.]+)\((\d+[a-z]*)\)' - - def replace_reference(match): - full_match = match.group(0) - - # Check if this match is already inside an tag - # Look back up to 500 chars for context - before_text = html[max(0, match.start()-500):match.start()] - - # Find the last before this match - last_open = before_text.rfind('') - - # If the last is after the last , we're inside a link - if last_open > last_close: - return full_match - - if match.group(1): # name(section) format - name = match.group(1).lower() - section = match.group(2) - else: # plain name(section) format - name = match.group(3).lower() - section = match.group(4) - - # Look up the referenced man page - key = (name, section) - if key in lookup: - # Calculate relative path from current file to target - target_path = lookup[key] - # File structure: output_dir/version/package_name/manN/file.html - # Need to go up 3 levels to reach version root - # Current: package_name/manN/file.html - # Target: other_package/manM/file.html - rel_path = f"../../../{target_path}" - return f'{full_match}' - - return full_match - - updated_html = re.sub(pattern, replace_reference, html) - - # Only write if something changed - if updated_html != html: - with open(man_file.html_path, 'w', encoding='utf-8') as f: - f.write(updated_html) - - except Exception as e: - logger.warning(f"Error linking references in {man_file.display_name}: {e}") - - logger.info("Cross-reference linking complete") def _get_output_path(self, man_file: ManFile) -> Path: """Determine output path for HTML file.