Skip to content

Commit b098fc0

Browse files
authored
Merge pull request #254 from posit-dev/fix-add-llms-txt-references-robots-txt
fix: add `llms.txt` and `llms-full.txt` references to `robots.txt`
2 parents 121a144 + 2181cf9 commit b098fc0

2 files changed

Lines changed: 51 additions & 0 deletions

File tree

great_docs/assets/post-render.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4734,6 +4734,44 @@ def _param_dl_to_html(m):
47344734
print("##GD:PASS:Markdown pages generated", flush=True)
47354735

47364736

4737+
# ══════════════════════════════════════════════════════════════════════════════
4738+
# INJECT MARKDOWN ALTERNATE LINKS
4739+
# ══════════════════════════════════════════════════════════════════════════════
4740+
# Add <link rel="alternate" type="text/markdown"> to HTML pages that have a
4741+
# corresponding .md companion, so AI agents can discover the Markdown variant.
4742+
4743+
if _gd_options.get("markdown_pages", True):
4744+
print("\nInjecting Markdown alternate links...")
4745+
_md_alt_count = 0
4746+
for html_file in glob.glob("_site/**/*.html", recursive=True):
4747+
md_companion = html_file.rsplit(".", 1)[0] + ".md"
4748+
if not os.path.isfile(md_companion):
4749+
continue
4750+
try:
4751+
with open(html_file, "r", encoding="utf-8") as f:
4752+
content = f.read()
4753+
4754+
# Skip if already has a markdown alternate link
4755+
if 'rel="alternate" type="text/markdown"' in content:
4756+
continue
4757+
4758+
# Build the href (just the filename — same directory)
4759+
md_basename = os.path.basename(md_companion)
4760+
alt_tag = f'<link rel="alternate" type="text/markdown" href="{md_basename}">'
4761+
modified = content.replace("</head>", f" {alt_tag}\n</head>", 1)
4762+
4763+
if modified != content:
4764+
with open(html_file, "w", encoding="utf-8") as f:
4765+
f.write(modified)
4766+
_md_alt_count += 1
4767+
except Exception as e:
4768+
print(f" Error injecting md alternate for {html_file}: {e}")
4769+
4770+
if _md_alt_count > 0:
4771+
print(f" Injected alternate links in {_md_alt_count} page(s)")
4772+
print("##GD:PASS:Markdown alternate links injected", flush=True)
4773+
4774+
47374775
# ══════════════════════════════════════════════════════════════════════════════
47384776
# STRIP COLGROUP TAGS FROM TABLES
47394777
# ══════════════════════════════════════════════════════════════════════════════

great_docs/core.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14543,6 +14543,19 @@ def _generate_robots_txt(self) -> None:
1454314543
lines.append(f"Sitemap: {base_url}sitemap.xml")
1454414544
lines.append("")
1454514545

14546+
# Add llms.txt references for AI agent discoverability
14547+
base_url = self._get_canonical_base_url()
14548+
if base_url:
14549+
llms_path = site_dir / "llms.txt"
14550+
llms_full_path = site_dir / "llms-full.txt"
14551+
if llms_path.exists() or llms_full_path.exists():
14552+
lines.append("# AI agent context files")
14553+
if llms_path.exists():
14554+
lines.append(f"Llms-txt: {base_url}llms.txt")
14555+
if llms_full_path.exists():
14556+
lines.append(f"Llms-txt: {base_url}llms-full.txt")
14557+
lines.append("")
14558+
1454614559
# Write robots.txt
1454714560
robots_path = site_dir / "robots.txt"
1454814561
robots_path.write_text("\n".join(lines), encoding="utf-8")

0 commit comments

Comments
 (0)