mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2026-07-23 22:33:42 -04:00
Merge branch 'master' into refactor/polyfills
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user