mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-05 22:09:56 +03:00
Create Sphinx extension to generate HTML meta description tags
(cherry picked from commit 2927a912a5)
This commit is contained in:
committed by
Rémi Verschelde
parent
ad2e2c9ec0
commit
496c7bf0e7
117
_extensions/godot_descriptions.py
Normal file
117
_extensions/godot_descriptions.py
Normal file
@@ -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,
|
||||||
|
}
|
||||||
1
conf.py
1
conf.py
@@ -13,6 +13,7 @@ needs_sphinx = "1.3"
|
|||||||
sys.path.append(os.path.abspath("_extensions"))
|
sys.path.append(os.path.abspath("_extensions"))
|
||||||
extensions = [
|
extensions = [
|
||||||
"gdscript",
|
"gdscript",
|
||||||
|
"godot_descriptions",
|
||||||
"sphinx_tabs.tabs",
|
"sphinx_tabs.tabs",
|
||||||
"sphinx.ext.imgmath",
|
"sphinx.ext.imgmath",
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user