Skip to content

Instantly share code, notes, and snippets.

@flavorjones
Created November 22, 2022 18:27
Show Gist options
  • Save flavorjones/a2ee50d94888537d561db53c837c4bbf to your computer and use it in GitHub Desktop.
Save flavorjones/a2ee50d94888537d561db53c837c4bbf to your computer and use it in GitHub Desktop.
patch of mkdocs-material search plugin to support rdoc

I should really make this into a real plugin when I get time. But for now it will do.

diff --git a/src/plugins/search/plugin.py b/src/plugins/search/plugin.py
index cb27a0e..657fd7d 100644
--- a/src/plugins/search/plugin.py
+++ b/src/plugins/search/plugin.py
@@ -22,6 +22,7 @@
import logging
import os
import regex as re
+import fnmatch
from html import escape
from html.parser import HTMLParser
@@ -31,6 +32,8 @@
from mkdocs.config.base import Config
from mkdocs.contrib.search import LangOption
from mkdocs.plugins import BasePlugin
+from mkdocs.structure.pages import Page
+from bs4 import BeautifulSoup
try:
import jieba
@@ -109,6 +112,14 @@ def on_page_context(self, context, *, page, config, nav):
page.content
)
+ def on_files(self, files, *, config):
+ rdoc_files = filter(lambda f: fnmatch.fnmatch(f.src_path, "rdoc/[A-Z]*.html"),
+ files.static_pages())
+ for file in rdoc_files:
+ log.info('Indexing rdoc ' + file.src_path)
+ self.search_index.add_entry_from_rdoc_file(file)
+ files
+
# Generate search index
def on_post_build(self, *, config):
base = os.path.join(config.site_dir, "search")
@@ -152,6 +163,62 @@ def add_entry_from_context(self, page):
if not section.is_excluded():
self.create_entry_for_section(section, page.toc, page.url, page)
+
+ def add_entry_from_rdoc_file(self, file) -> None:
+ """
+ Create a set of entries in the index for a static html file containing rdoc docs.
+ """
+
+ page_url = Page(None, file, self.config).url
+ with open(file.abs_src_path, 'r') as io: page_content = io.read()
+ page = BeautifulSoup(page_content, 'html.parser')
+
+ page_title = page.main.h1.get_text().strip()
+ if page_description := page.find("section", class_="description"):
+ entry = {
+ "title": page_title,
+ "text": str(page_description),
+ "location": page_url,
+ }
+ self.entries.append(entry)
+ else:
+ entry = {
+ "title": page_title,
+ "text": "",
+ "location": page_url,
+ }
+ self.entries.append(entry)
+
+ for method in page.find_all("div", class_="method-detail"):
+ if (heading := method.find("div", class_="method-heading")) is None: continue
+
+ section_id = method['id']
+ section_url = page_url + "#" + section_id
+
+ section_text = ''
+ if description := method.find("div", class_="method-description"):
+ for p in description.find_all("p"):
+ if p is not None:
+ section_text += str(p)
+
+ section_title = ''
+ for class_ in ["method-callseq", "method-name", "method-args"]:
+ if node := heading.find("span", class_=class_):
+ section_title += node.get_text()
+ section_title = section_title.strip()
+ if section_id.startswith('method-c-'):
+ section_title = page_title + "." + section_title
+ else:
+ section_title = page_title + "#" + section_title
+
+ entry = {
+ "title": section_title,
+ "text": section_text,
+ "location": section_url,
+ }
+ self.entries.append(entry)
+
+
# Override: graceful indexing and additional fields
def create_entry_for_section(self, section, toc, url, page):
item = self._find_toc_by_id(toc, section.id)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment