Merge branch 'master' into refactor/polyfills

This commit is contained in:
squidfunk
2023-07-06 13:28:16 +02:00
2510 changed files with 10115 additions and 11988 deletions

View File

@@ -432,7 +432,8 @@ class Parser(HTMLParser):
# Remove element from skip list
el = self.context.pop()
if el in self.skip:
self.skip.remove(el)
if el.tag not in ["script", "style", "object"]:
self.skip.remove(el)
return
# Render closing tag if kept

View File

@@ -57,8 +57,19 @@ class SocialPluginConfig(Config):
# Options for social cards
cards = opt.Type(bool, default = True)
cards_dir = opt.Type(str, default = "assets/images/social")
cards_color = opt.Type(dict, default = dict())
cards_font = opt.Optional(opt.Type(str))
cards_layout_options = opt.Type(dict, default = {})
# Deprecated options
cards_color = opt.Deprecated(
option_type = opt.Type(dict, default = {}),
message =
"Deprecated, use 'cards_layout_options.background_color' "
"and 'cards_layout_options.color' with 'default' layout"
)
cards_font = opt.Deprecated(
option_type = opt.Type(str),
message = "Deprecated, use 'cards_layout_options.font_family'"
)
# -----------------------------------------------------------------------------
@@ -67,6 +78,7 @@ class SocialPlugin(BasePlugin[SocialPluginConfig]):
def __init__(self):
self._executor = concurrent.futures.ThreadPoolExecutor(4)
self.custom_dir = None
# Retrieve configuration
def on_config(self, config):
@@ -74,6 +86,24 @@ class SocialPlugin(BasePlugin[SocialPluginConfig]):
if not self.config.cards:
return
# Move color options
if self.config.cards_color:
# Move background color to new option
value = self.config.cards_color.get("fill")
if value:
self.config.cards_layout_options["background_color"] = value
# Move color to new option
value = self.config.cards_color.get("text")
if value:
self.config.cards_layout_options["color"] = value
# Move font family to new option
if self.config.cards_font:
value = self.config.cards_font
self.config.cards_layout_options["font_family"] = value
# Check if required dependencies are installed
if not dependencies:
log.error(
@@ -109,7 +139,18 @@ class SocialPlugin(BasePlugin[SocialPluginConfig]):
self.color = colors.get(primary, self.color)
# Retrieve color overrides
self.color = { **self.color, **self.config.cards_color }
options = self.config.cards_layout_options
self.color = {
"fill": options.get("background_color", self.color["fill"]),
"text": options.get("color", self.color["text"])
}
# Retrieve custom_dir path
for user_config in config.user_configs:
custom_dir = user_config.get("theme", {}).get("custom_dir")
if custom_dir:
self.custom_dir = custom_dir
break
# Retrieve logo and font
self._resized_logo_promise = self._executor.submit(self._load_resized_logo, config)
@@ -343,8 +384,15 @@ class SocialPlugin(BasePlugin[SocialPluginConfig]):
if "logo" in theme:
_, extension = os.path.splitext(theme["logo"])
# Load SVG and convert to PNG
path = os.path.join(config.docs_dir, theme["logo"])
# Allow users to put the logo inside their custom_dir (theme["logo"] case)
if self.custom_dir:
custom_dir_logo = os.path.join(self.custom_dir, theme["logo"])
if os.path.exists(custom_dir_logo):
path = custom_dir_logo
# Load SVG and convert to PNG
if extension == ".svg":
return self._load_logo_svg(path)
@@ -352,10 +400,11 @@ class SocialPlugin(BasePlugin[SocialPluginConfig]):
return Image.open(path).convert("RGBA")
# Handle icons
logo = "material/library"
icon = theme["icon"] or {}
if "logo" in icon and icon["logo"]:
logo = icon["logo"]
else:
logo = "material/library"
# Resolve path of package
base = os.path.abspath(os.path.join(
@@ -363,8 +412,15 @@ class SocialPlugin(BasePlugin[SocialPluginConfig]):
"../.."
))
# Load icon data and fill with color
path = f"{base}/.icons/{logo}.svg"
# Allow users to put the logo inside their custom_dir (theme["icon"]["logo"] case)
if self.custom_dir:
custom_dir_logo = os.path.join(self.custom_dir, ".icons", f"{logo}.svg")
if os.path.exists(custom_dir_logo):
path = custom_dir_logo
# Load icon data and fill with color
return self._load_logo_svg(path, self.color["text"])
# Load SVG file and convert to PNG
@@ -382,28 +438,41 @@ class SocialPlugin(BasePlugin[SocialPluginConfig]):
# Retrieve font
def _load_font(self, config):
name = self.config.cards_font
name = self.config.cards_layout_options.get("font_family")
if not name:
# Retrieve from theme (default: Roboto)
theme = config.theme
if theme["font"]:
if isinstance(theme["font"], dict) and "text" in theme["font"]:
name = theme["font"]["text"]
else:
name = "Roboto"
# Retrieve font files, if not already done
files = os.listdir(self.cache)
files = [file for file in files if file.endswith(".ttf") or file.endswith(".otf")] or (
self._load_font_from_google(name)
)
# Google fonts can return varients like OpenSans_Condensed-Regular.ttf so
# we only use the font requested e.g. OpenSans-Regular.ttf
font_filename_base = name.replace(' ', '')
filename_regex = re.escape(font_filename_base)+r"-(\w+)\.[ot]tf$"
# Map available font weights to file paths
font = dict()
for file in files:
match = re.search(r"-(\w+)\.[ot]tf$", file)
if match:
font[match.group(1)] = os.path.join(self.cache, file)
# Check for cached files - note these may be in subfolders
for currentpath, folders, files in os.walk(self.cache):
for file in files:
# Map available font weights to file paths
fname = os.path.join(currentpath, file)
match = re.search(filename_regex, fname)
if match:
font[match.group(1)] = fname
# If none found, fetch from Google and try again
if len(font) == 0:
self._load_font_from_google(name)
for currentpath, folders, files in os.walk(self.cache):
for file in files:
# Map available font weights to file paths
fname = os.path.join(currentpath, file)
match = re.search(filename_regex, fname)
if match:
font[match.group(1)] = fname
# Return available font weights with fallback
return defaultdict(lambda: font["Regular"], font)

View File

@@ -19,7 +19,6 @@
# IN THE SOFTWARE.
import logging
import os
import sys
from collections import defaultdict
@@ -36,6 +35,9 @@ from mkdocs.plugins import BasePlugin
# Tags plugin configuration scheme
class TagsPluginConfig(Config):
enabled = opt.Type(bool, default = True)
# Options for tags
tags_file = opt.Optional(opt.Type(str))
# -----------------------------------------------------------------------------
@@ -46,6 +48,10 @@ class TagsPlugin(BasePlugin[TagsPluginConfig]):
# Initialize plugin
def on_config(self, config):
if not self.config.enabled:
return
# Initialize tags
self.tags = defaultdict(list)
self.tags_file = None
@@ -64,12 +70,20 @@ class TagsPlugin(BasePlugin[TagsPluginConfig]):
# Hack: 2nd pass for tags index page(s)
def on_nav(self, nav, config, files):
if not self.config.enabled:
return
# Resolve tags index page
file = self.config.tags_file
if file:
self.tags_file = self._get_tags_file(files, file)
# Build and render tags index page
def on_page_markdown(self, markdown, page, config, files):
if not self.config.enabled:
return
# Render tags index page
if page.file == self.tags_file:
return self._render_tag_index(markdown)
@@ -79,6 +93,10 @@ class TagsPlugin(BasePlugin[TagsPluginConfig]):
# Inject tags into page (after search and before minification)
def on_page_context(self, context, page, config, nav):
if not self.config.enabled:
return
# Provide tags for page
if "tags" in page.meta:
context["tags"] = [
self._render_tag(tag)
@@ -116,7 +134,7 @@ class TagsPlugin(BasePlugin[TagsPluginConfig]):
classes.append("md-tag-icon")
type = self.tags_map.get(tag)
if type:
classes.append(f"md-tag-icon--{type}")
classes.append(f"md-tag--{type}")
# Render section for tag and a link to each page
classes = " ".join(classes)