Skip to content

Commit 8752ead

Browse files
committed
Sphinx docs fixed
1 parent 5467291 commit 8752ead

2 files changed

Lines changed: 81 additions & 9 deletions

File tree

sphinx-docs/source/conf.py

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,14 @@ def _rewrite_locale_asset_paths(doctree: nodes.document) -> None:
193193
"""Rewrite image paths so they work in both normal and gettext (locale) builds.
194194
195195
In locale builds, content comes from .po files; relative paths like ../images/...
196-
are then resolved from the document dir (source/), so ../images points to
197-
sphinx-docs/images instead of project root. Fix by rewriting ../images/ to
198-
../../images/ (relative to source/ = project root images/).
196+
are resolved from the document dir (source/). Use ../../images/ (2 levels up from
197+
source/ = project root). If Read the Docs resolves from locale/es/, try
198+
setting LOCALE_IMAGE_LEVELS=3 in the build environment.
199199
"""
200+
# Allow override: LOCALE_IMAGE_LEVELS=3 if Read the Docs resolves from locale/es/
201+
levels = max(1, int(os.environ.get("LOCALE_IMAGE_LEVELS", "3")))
200202
prefix = '../images/'
201-
replacement = '../../images/'
203+
replacement = ("../" * levels) + "images/"
202204
for node in doctree.traverse(nodes.image):
203205
uri = node.get('uri', '')
204206
if uri.startswith(prefix):
@@ -216,10 +218,31 @@ def _rewrite_locale_asset_paths(doctree: nodes.document) -> None:
216218
r'^\[([^\]]*)\]\s*\(\s*([^)]+)\s*\)\s*$',
217219
re.DOTALL,
218220
)
219-
# Link inside a paragraph: [text](url)
221+
# Link inside a paragraph: [text](url) or [text] (url) - allow space between ] and (
220222
_LINK_INLINE_RE = re.compile(
221-
r'\[([^\]]*)\]\(\s*([^)]+)\s*\)',
223+
r'\[([^\]]*)\]\s*\(\s*([^)]+)\s*\)',
222224
)
225+
# Inline image inside a paragraph: ![alt](path) - path may be ../images/...
226+
_IMAGE_INLINE_RE = re.compile(
227+
r'!\s*\[([^\]]*)\]\s*\(\s*((?:\.\./)+images/[^)]+)\s*\)',
228+
)
229+
_IMAGE_EXTENSIONS = ('.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp')
230+
231+
232+
def _is_image_path(target: str) -> bool:
233+
"""Return True if target is an image path (e.g. ../images/.../file.png)."""
234+
t = target.strip().lower()
235+
return any(t.endswith(ext) for ext in _IMAGE_EXTENSIONS) or (
236+
'images/' in t and any(ext in t for ext in _IMAGE_EXTENSIONS)
237+
)
238+
239+
240+
def _image_uri_from_path(path: str) -> str:
241+
"""Normalize image path to correct depth for locale builds."""
242+
levels = int(os.environ.get("LOCALE_IMAGE_LEVELS", "3"))
243+
if "images/" in path:
244+
return ("../" * levels) + "images/" + path.split("images/", 1)[1]
245+
return path
223246

224247

225248
def _convert_literal_markdown_paragraphs(app, doctree: nodes.document, docname: str) -> None:
@@ -249,9 +272,10 @@ def _convert_literal_markdown_paragraphs(app, doctree: nodes.document, docname:
249272
if match:
250273
alt = match.group(1).strip()
251274
path = match.group(2).strip()
252-
# Normalize to ../../images/... (relative to source/ = project root)
275+
# Normalize path (same logic as _rewrite_locale_asset_paths)
276+
levels = int(os.environ.get("LOCALE_IMAGE_LEVELS", "3"))
253277
if "images/" in path:
254-
uri = "../../images/" + path.split("images/", 1)[1]
278+
uri = ("../" * levels) + "images/" + path.split("images/", 1)[1]
255279
else:
256280
uri = path
257281
img = nodes.image(uri=uri, alt=alt)
@@ -265,6 +289,17 @@ def _convert_literal_markdown_paragraphs(app, doctree: nodes.document, docname:
265289
if match:
266290
link_text = match.group(1).strip()
267291
target = match.group(2).strip()
292+
# If target is an image path, render as img not link
293+
if _is_image_path(target):
294+
uri = _image_uri_from_path(target)
295+
from html import escape
296+
raw = nodes.raw(
297+
"",
298+
f'<img src="{escape(uri)}" alt="{escape(link_text)}" />',
299+
format="html",
300+
)
301+
node.replace_self(raw)
302+
continue
268303
if any(target.startswith(s) for s in ("http://", "https://", "mailto:")):
269304
refuri = target
270305
elif get_uri:
@@ -288,6 +323,28 @@ def _convert_literal_markdown_paragraphs(app, doctree: nodes.document, docname:
288323
node.replace_self(raw)
289324
continue
290325

326+
# Paragraph contains inline image: "text ![alt](../images/...)" - render img
327+
match_img = _IMAGE_INLINE_RE.search(text)
328+
if match_img and _IMAGE_INLINE_RE.search(text, match_img.end()) is None:
329+
from html import escape
330+
before = text[: match_img.start()]
331+
alt = match_img.group(1).strip()
332+
path = match_img.group(2).strip()
333+
uri = _image_uri_from_path(path)
334+
after = text[match_img.end() :]
335+
new_children = []
336+
if before:
337+
new_children.append(nodes.Text(before))
338+
new_children.append(
339+
nodes.raw("", f'<img src="{escape(uri)}" alt="{escape(alt)}" />', format="html")
340+
)
341+
if after:
342+
new_children.append(nodes.Text(after))
343+
node.clear()
344+
for c in new_children:
345+
node += c
346+
continue
347+
291348
# Paragraph contains one markdown link in the middle (e.g. "Consulta la [Guía](installation.md) para...")
292349
match_inline = _LINK_INLINE_RE.search(text)
293350
if match_inline and _LINK_INLINE_RE.search(text, match_inline.end()) is None:
@@ -297,6 +354,21 @@ def _convert_literal_markdown_paragraphs(app, doctree: nodes.document, docname:
297354
link_text = match_inline.group(1).strip()
298355
target = match_inline.group(2).strip()
299356
after = text[match_inline.end() :]
357+
# If target is an image path, render as img not link
358+
if _is_image_path(target):
359+
uri = _image_uri_from_path(target)
360+
new_children = []
361+
if before:
362+
new_children.append(nodes.Text(before))
363+
new_children.append(
364+
nodes.raw("", f'<img src="{escape(uri)}" alt="{escape(link_text)}" />', format="html")
365+
)
366+
if after:
367+
new_children.append(nodes.Text(after))
368+
node.clear()
369+
for c in new_children:
370+
node += c
371+
continue
300372
if any(target.startswith(s) for s in ("http://", "https://", "mailto:")):
301373
refuri = target
302374
elif get_uri:

src/config/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
__credits__ = ["Alejandro Mata Ali"]
1616
__maintainer__ = "Alejandro Mata Ali"
1717
__email__ = "alejandro.mata.ali@gmail.com"
18-
__status__ = "Beta"
18+
__status__ = "Production"
1919

2020
# ---------------------------------------------------------------------------
2121
# Equations configuration

0 commit comments

Comments
 (0)