Skip to content

Commit

Permalink
Fixed social plugin crashing on Windows when downloading fonts (#7085) (
Browse files Browse the repository at this point in the history
#7117)

* fix: social plugin fonts on Windows (squidfunk #7085)

* fix: managed to edit in material instead of src

* added resource mgmt for ByteIO, comments

* formatted comment

* Fix for Social plugin crashes when font autoloading is disabled (#7118)
  • Loading branch information
alexvoss committed Apr 29, 2024
1 parent ff49d74 commit e90871f
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 26 deletions.
31 changes: 18 additions & 13 deletions material/plugins/social/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
from mkdocs.commands.build import DuplicateFilter
from mkdocs.exceptions import PluginError
from mkdocs.plugins import BasePlugin
from mkdocs.utils import copy_file
from mkdocs.utils import write_file
from shutil import copyfile
from tempfile import NamedTemporaryFile

Expand Down Expand Up @@ -444,11 +444,17 @@ def _load_logo_svg(self, path, fill = None):
svg2png(bytestring = data, write_to = file, scale = 10)
return Image.open(file)

# Retrieve font
# Retrieve font either from the card layout option or from the Material
# font defintion. If no font is defined for Material or font is False
# then choose a default.
def _load_font(self, config):
name = self.config.cards_layout_options.get("font_family")
if not name:
name = config.theme.get("font", {}).get("text", "Roboto")
material_name = config.theme.get("font", False)
if material_name is False:
name = "Roboto"
else:
name = material_name.get("text", "Roboto")

# Resolve relevant fonts
font = {}
Expand Down Expand Up @@ -522,19 +528,18 @@ def _fetch_font_from_google_fonts(self, family: str):
with requests.get(match) as res:
res.raise_for_status()

# Create a temporary file to download the font
with NamedTemporaryFile() as temp:
temp.write(res.content)
temp.flush()

# Extract font family name and style
font = ImageFont.truetype(temp.name)
# Extract font family name and style using the content in the
# response via ByteIO to avoid writing a temp file. Done to fix
# problems with passing a NamedTemporaryFile to
# ImageFont.truetype() on Windows, see https://t.ly/LiF_k
with BytesIO(res.content) as fontdata:
font = ImageFont.truetype(fontdata)
name, style = font.getname()
name = " ".join([name.replace(family, ""), style]).strip()

# Move fonts to cache directory
target = os.path.join(path, family, f"{name}.ttf")
copy_file(temp.name, target)

# write file to cache
write_file(res.content, target)

# -----------------------------------------------------------------------------
# Data
Expand Down
31 changes: 18 additions & 13 deletions src/plugins/social/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
from mkdocs.commands.build import DuplicateFilter
from mkdocs.exceptions import PluginError
from mkdocs.plugins import BasePlugin
from mkdocs.utils import copy_file
from mkdocs.utils import write_file
from shutil import copyfile
from tempfile import NamedTemporaryFile

Expand Down Expand Up @@ -444,11 +444,17 @@ def _load_logo_svg(self, path, fill = None):
svg2png(bytestring = data, write_to = file, scale = 10)
return Image.open(file)

# Retrieve font
# Retrieve font either from the card layout option or from the Material
# font defintion. If no font is defined for Material or font is False
# then choose a default.
def _load_font(self, config):
name = self.config.cards_layout_options.get("font_family")
if not name:
name = config.theme.get("font", {}).get("text", "Roboto")
material_name = config.theme.get("font", False)
if material_name is False:
name = "Roboto"
else:
name = material_name.get("text", "Roboto")

# Resolve relevant fonts
font = {}
Expand Down Expand Up @@ -522,19 +528,18 @@ def _fetch_font_from_google_fonts(self, family: str):
with requests.get(match) as res:
res.raise_for_status()

# Create a temporary file to download the font
with NamedTemporaryFile() as temp:
temp.write(res.content)
temp.flush()

# Extract font family name and style
font = ImageFont.truetype(temp.name)
# Extract font family name and style using the content in the
# response via ByteIO to avoid writing a temp file. Done to fix
# problems with passing a NamedTemporaryFile to
# ImageFont.truetype() on Windows, see https://t.ly/LiF_k
with BytesIO(res.content) as fontdata:
font = ImageFont.truetype(fontdata)
name, style = font.getname()
name = " ".join([name.replace(family, ""), style]).strip()

# Move fonts to cache directory
target = os.path.join(path, family, f"{name}.ttf")
copy_file(temp.name, target)

# write file to cache
write_file(res.content, target)

# -----------------------------------------------------------------------------
# Data
Expand Down

0 comments on commit e90871f

Please sign in to comment.