Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add full support for image, video and audio tags. #60

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 43 additions & 25 deletions sphinxext/opengraph/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import posixpath
from typing import Any, Dict
from urllib.parse import urljoin, urlparse, urlunparse
from pathlib import Path
from pathlib import Path, PurePosixPath

import docutils.nodes as nodes
from sphinx.application import Sphinx
from sphinx.util import images

from .descriptionparser import get_description
from .titleparser import get_title
Expand All @@ -28,6 +30,28 @@
}


def image_abs_url(image_uri: str, docname: str, site_url: str, app: Sphinx):
parsed_url = urlparse(image_uri)

if not parsed_url.scheme:
# Convert relative url to absolute urls and make sure image gets copied on build
return urljoin(site_url, note_image(parsed_url.path, docname, app))

return image_uri


def note_image(image_path: str, docname: str, app: Sphinx):
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open for comments on any of the matters mentioned in the comments in this function

# potentially temporary solution
if any([PurePosixPath(image_path).match(dir + "/*") for dir in app.config["html_static_path"] + app.config["html_extra_path"]]):
ItayZiv marked this conversation as resolved.
Show resolved Hide resolved
return image_path

if not (image_path.startswith('/') or image_path.startswith(os.sep)):
image_path = str(PurePosixPath(docname).parent / image_path)

new_path = app.builder.images[image_path] = app.env.images.add_file(docname, image_path)
return posixpath.join(app.builder.imgpath, new_path)


def make_tag(property: str, content: str) -> str:
# Parse quotation, so they won't break html tags if smart quotes are disabled
content = content.replace('"', """)
Expand All @@ -40,6 +64,7 @@ def get_tags(
doctree: nodes.document,
config: Dict[str, Any],
) -> str:
docname = context["pagename"]
# Get field lists for per-page overrides
fields = context["meta"]
if fields is None:
Expand Down Expand Up @@ -89,10 +114,10 @@ def get_tags(
# url tag
# Get the URL of the specific page
if context["builder"] == "dirhtml":
page_url = urljoin(config["ogp_site_url"], context["pagename"] + "/")
page_url = urljoin(config["ogp_site_url"], docname + "/")
else:
page_url = urljoin(
config["ogp_site_url"], context["pagename"] + context["file_suffix"]
config["ogp_site_url"], docname + context["file_suffix"]
)
tags["og:url"] = page_url

Expand All @@ -106,27 +131,19 @@ def get_tags(
tags["og:description"] = description

# image tag
# Get basic values from config
# Get basic values from config or field list
#image_url = fields.pop("og:image", config["ogp_image"])
#ogp_image_alt = fields.pop("og:image:alt", config["ogp_image_alt"])
if "og:image" in fields:
image_url = fields["og:image"]
ogp_use_first_image = False
ogp_image_alt = fields.get("og:image:alt")
fields.pop("og:image", None)
image_url = image_abs_url(fields.pop("og:image"), docname, site_name, app)
image_alt = fields.pop("og:image:alt", None)
elif fields.get("ogp_use_first_image", config["ogp_use_first_image"]) and (first_image := doctree.next_node(nodes.image)):
image_url = first_image["uri"]
image_alt = first_image.get("alt", None)
else:
image_url = config["ogp_image"]
ogp_use_first_image = config["ogp_use_first_image"]
ogp_image_alt = fields.get("og:image:alt", config["ogp_image_alt"])

fields.pop("og:image:alt", None)

if ogp_use_first_image:
first_image = doctree.next_node(nodes.image)
if (
first_image
and Path(first_image.get("uri", "")).suffix[1:].lower() in IMAGE_MIME_TYPES
):
image_url = first_image["uri"]
ogp_image_alt = first_image.get("alt", None)
# if alt text isn't provided, use site_name instead
image_alt = config["ogp_image_alt"]

if image_url:
# temporarily disable relative image paths with field lists
Expand All @@ -142,14 +159,15 @@ def get_tags(
root = page_url

image_url = urljoin(root, image_url_parsed.path)
# image_url = urljoin(config["ogp_site_url"], note_image(image_url_parsed.path, docname, app))
tags["og:image"] = image_url

# Add image alt text (either provided by config or from site_name)
if isinstance(ogp_image_alt, str):
tags["og:image:alt"] = ogp_image_alt
elif ogp_image_alt is None and site_name:
if isinstance(image_alt, str):
tags["og:image:alt"] = image_alt
elif image_alt is None and site_name:
tags["og:image:alt"] = site_name
elif ogp_image_alt is None and title:
elif image_alt is None and title:
tags["og:image:alt"] = title

# arbitrary tags and overrides
Expand Down