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.