Skip to content

Commit 3bce601

Browse files
committed
feat: index Doxygen Participant page in Algolia search
1 parent d80789f commit 3bce601

File tree

5 files changed

+148
-2
lines changed

5 files changed

+148
-2
lines changed

.github/workflows/update-algolia.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,36 @@ jobs:
1414
submodules: true
1515
lfs: false
1616
path: website
17+
- name: Fetch precice main
18+
uses: actions/checkout@v4
19+
with:
20+
repository: precice/precice
21+
ref: main
22+
path: main
23+
fetch-tags: true
24+
- name: Patch Doxyfile for main
25+
run: |
26+
sed -e "/^ *TAGFILES/d" -e "/^ *SITEMAP_URL/d" -e "/^ *PROJECT_NUMBER/d" -i main/Doxyfile
27+
TAGFILE="../website/doxygen/cppreference-doxygen-web.tag.xml=http://en.cppreference.com/w/"
28+
echo "TAGFILES = $TAGFILE" >> main/Doxyfile
29+
echo "SITEMAP_URL = https://precice.org/doxygen/main/" >> main/Doxyfile
30+
echo "PROJECT_NUMBER = $( cd main && git describe --tags )" >> main/Doxyfile
31+
- name: Install doxygen dependencies
32+
run: |
33+
sudo apt-get -yyq update
34+
sudo apt-get -yyq install graphviz plantuml
35+
mkdir doxygen-bin
36+
curl -sL https://github.com/doxygen/doxygen/releases/download/Release_1_14_0/doxygen-1.14.0.linux.bin.tar.gz | tar -xz --strip-components=1 -C doxygen-bin
37+
readlink -f doxygen-bin/bin >> $GITHUB_PATH
38+
- name: Build doxygen - main
39+
working-directory: main
40+
run: doxygen
41+
env:
42+
PLANTUML_JAR_PATH: /usr/share/plantuml/plantuml.jar
43+
- name: Place doxygen HTML for indexing
44+
run: |
45+
mkdir -p website/_doxygen_html/main
46+
cp -r main/docs/source-code-documentation/html/* website/_doxygen_html/main/
1747
- uses: ruby/setup-ruby@v1
1848
with:
1949
bundler-cache: true

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ _pdf
77
.idea
88
vendor/
99
.bundle/
10-
Gemfile.lock
10+
Gemfile.lock
11+
_doxygen_html/

_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ exclude:
3939
- createtag
4040
- pdf-docs.sh
4141
- doxygen/
42+
- _doxygen_html/
4243
- tools/
4344
- content/**/_index.md
4445
# these are the files and directories that jekyll will exclude from the build

_plugins/algolia_hooks.rb

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# frozen_string_literal: true
2+
3+
require 'nokogiri'
4+
require 'digest'
5+
6+
module Jekyll
7+
module Algolia
8+
module Hooks
9+
DOXYGEN_HTML_PATH = '_doxygen_html/main/classprecice_1_1Participant.html'
10+
DOXYGEN_URL = '/doxygen/main/classprecice_1_1Participant.html'
11+
12+
def self.before_indexing_all(records, _context)
13+
unless File.exist?(DOXYGEN_HTML_PATH)
14+
Jekyll.logger.warn 'Algolia:', "Doxygen HTML not found at #{DOXYGEN_HTML_PATH}, skipping Doxygen indexing"
15+
return records
16+
end
17+
18+
Jekyll.logger.info 'Algolia:', 'Parsing Doxygen Participant page for indexing...'
19+
doxygen_records = parse_doxygen_participant
20+
Jekyll.logger.info 'Algolia:', "Added #{doxygen_records.length} Doxygen records"
21+
22+
records + doxygen_records
23+
end
24+
25+
def self.parse_doxygen_participant
26+
html = File.read(DOXYGEN_HTML_PATH)
27+
doc = Nokogiri::HTML(html)
28+
records = []
29+
30+
# Extract class overview record
31+
brief = doc.at_css('.contents .textblock')
32+
brief_text = brief ? brief.text.strip : 'Main class of the preCICE API for coupling simulations.'
33+
34+
records << build_record(
35+
title: 'Participant Class Reference',
36+
anchor: nil,
37+
html: brief_text,
38+
headings: %w[precice Participant],
39+
object_id: 'doxygen-participant-overview'
40+
)
41+
42+
# Extract public method records from member documentation
43+
doc.css('.contents .memitem').each do |memitem|
44+
# The anchor is on the preceding h2 > a element, or in the memname
45+
anchor_el = memitem.previous_element
46+
anchor = nil
47+
48+
# Doxygen wraps each method doc in a div.memitem preceded by an h2.memtitle
49+
# with an anchor link. Walk back to find the anchor.
50+
while anchor_el
51+
if anchor_el.name == 'a' && anchor_el['id']
52+
anchor = anchor_el['id']
53+
break
54+
end
55+
# Check for anchor inside the element
56+
a_tag = anchor_el.at_css('a[id]')
57+
if a_tag
58+
anchor = a_tag['id']
59+
break
60+
end
61+
anchor_el = anchor_el.previous_element
62+
end
63+
64+
# Extract method name from memname
65+
memname_el = memitem.at_css('.memname')
66+
next unless memname_el
67+
68+
method_name = extract_method_name(memname_el.text.strip)
69+
next if method_name.nil? || method_name.empty?
70+
71+
# Extract brief description
72+
memdoc = memitem.at_css('.memdoc')
73+
description = memdoc ? memdoc.text.strip.gsub(/\s+/, ' ')[0, 500] : ''
74+
next if description.empty?
75+
76+
records << build_record(
77+
title: "Participant::#{method_name}",
78+
anchor: anchor,
79+
html: description,
80+
headings: %w[precice Participant],
81+
object_id: "doxygen-participant-#{anchor || Digest::MD5.hexdigest(method_name)}"
82+
)
83+
end
84+
85+
records
86+
end
87+
88+
def self.extract_method_name(memname_text)
89+
# memname_text looks like "void precice::Participant::initialize ()"
90+
# or "precice::Participant::Participant (...)"
91+
# Extract the last component before the parentheses
92+
match = memname_text.match(/(\w+)\s*\(/)
93+
match ? match[1] : nil
94+
end
95+
96+
def self.build_record(title:, anchor:, html:, headings:, object_id:)
97+
{
98+
title: title,
99+
url: DOXYGEN_URL,
100+
anchor: anchor,
101+
html: html,
102+
headings: headings,
103+
type: 'content',
104+
custom_ranking: { position: 0, heading: 90 },
105+
objectID: object_id
106+
}
107+
end
108+
109+
private_class_method :parse_doxygen_participant, :extract_method_name, :build_record
110+
end
111+
end
112+
end

js/algolia-search.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ const hitTemplate = function(hit) {
2020
date = moment.unix(hit.date).format('MMM D, YYYY');
2121
}
2222

23-
let url = `{{ site.baseurl }}${hit.url}#${hit.anchor}`;
23+
let url = hit.anchor
24+
? `{{ site.baseurl }}${hit.url}#${hit.anchor}`
25+
: `{{ site.baseurl }}${hit.url}`;
2426

2527
const title = hit._highlightResult.title.value;
2628

0 commit comments

Comments
 (0)