forked from godotengine/godot-docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create Sphinx extension to generate HTML meta description tags
- Loading branch information
1 parent
0b6d26e
commit 2927a91
Showing
2 changed files
with
118 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
godot_descriptions | ||
~~~~~~~~~~~~~~~~~~ | ||
Sphinx extension to automatically generate HTML meta description tags | ||
for all pages. Also comes with some special support for Godot class docs. | ||
:copyright: Copyright 2020 by The Godot Engine Community | ||
:license: MIT. | ||
based on the work of Takayuki Shimizukawa on OpenGraph support for Sphinx, | ||
see: https://github.com/sphinx-contrib/ogp | ||
""" | ||
|
||
import re | ||
from docutils import nodes | ||
from sphinx import addnodes | ||
|
||
|
||
class DescriptionGenerator: | ||
def __init__(self, document, pagename="", n_sections_max=3, max_length=220): | ||
self.document = document | ||
self.text_list = [] | ||
self.max_length = max_length | ||
self.current_length = 0 | ||
self.n_sections = 0 | ||
self.n_sections_max = n_sections_max | ||
self.pagename = pagename | ||
self.is_class = pagename.startswith("classes/") | ||
self.stop_word_reached = False | ||
|
||
def dispatch_visit(self, node): | ||
if ( | ||
self.stop_word_reached | ||
or self.current_length > self.max_length | ||
or self.n_sections > self.n_sections_max | ||
): | ||
return | ||
|
||
if isinstance(node, addnodes.compact_paragraph) and node.get("toctree"): | ||
raise nodes.SkipChildren | ||
|
||
add = True | ||
|
||
if isinstance(node, nodes.paragraph): | ||
text = node.astext() | ||
|
||
if self.is_class: | ||
# Skip OOP hierarchy info for description | ||
if ( | ||
text.startswith("Inherits:") | ||
or text.startswith("Inherited By:") | ||
or text.strip() == "Example:" | ||
): | ||
add = False | ||
|
||
# If we're in a class doc and reached the first table, | ||
# stop adding to the description | ||
if text.strip() == "Properties": | ||
self.stop_word_reached = True | ||
add = False | ||
|
||
if add: | ||
self.text_list.append(text) | ||
self.current_length = self.current_length + len(text) | ||
|
||
if add and isinstance(node, nodes.section): | ||
self.n_sections += 1 | ||
|
||
def dispatch_departure(self, node): | ||
pass | ||
|
||
def format_description(self, desc): | ||
# Replace newlines with spaces | ||
desc = re.sub("\r|\n", " ", desc) | ||
|
||
# Replace multiple spaces with single spaces | ||
desc = re.sub("\\s+", " ", desc) | ||
|
||
return desc | ||
|
||
def create_description(self, cutoff_suffix="..."): | ||
text = " ".join(self.text_list) | ||
|
||
text = self.format_description(text) | ||
|
||
# Cut to self.max_length, add cutoff_suffix at end | ||
if len(text) > self.max_length: | ||
text = text[: self.max_length - len(cutoff_suffix)].strip() + cutoff_suffix | ||
|
||
return text | ||
|
||
|
||
def generate_description(app, pagename, templatename, context, doctree): | ||
if not doctree: | ||
return | ||
|
||
generator = DescriptionGenerator(doctree, pagename) | ||
doctree.walkabout(generator) | ||
|
||
description = ( | ||
'<meta name="description" content="' + generator.create_description() + '">\n' | ||
) | ||
|
||
context["metatags"] += description | ||
|
||
|
||
def setup(app): | ||
# Hook into Sphinx for all pages to | ||
# generate meta description tag and add to meta tag list | ||
app.connect("html-page-context", generate_description) | ||
|
||
return { | ||
"parallel_read_safe": True, | ||
"parallel_write_safe": True, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters