Coder Social home page Coder Social logo

mkdocs-material-extensions's Introduction

Donate via PayPal Build Coverage Status PyPI Version PyPI - Python Version License

MkDocs Material Extensions

NOTE: This project is now deprecated as MkDocs for Material now implements this logic directly. Users should migrate to using mkdocs-material's material.extensions.emoji.twemoji and material.extensions.emoji.to_svg in place of the respective materialx.emoji.twemoji and materialx.emoji.to_svg functions provided by this library.

Markdown extension resources for MkDocs for Material

Install

Generally, just installing MkDocs Material will automatically install mkdocs-material-extensions. But if you had a need to manually install it, you can use pip.

pip install mkdocs-material-extensions

But make sure you've also installed MkDocs Material as well as this won't work without it.

pip install mkdocs-material

Inline SVG Icons

MkDocs Material provides numerous icons from Material, FontAwesome, and Octicons, but it does so by inlining the SVG icons into the source. Currently there is no easy way access these icons and arbitrarily insert them into Markdown content. Users must include the icon fonts themselves and do it with HTML.

This module allows you to use PyMdown Extensions' Emoji extension to enable easy insertion of MkDocs Material's SVG assets using simple :emoji-syntax:. This is done by creating our own emoji index and emoji generator. The custom index provides a modified version of the Emoji extensions Twemoji index.

In addition to the custom index, you must also specify the associated custom generator. This will will find the appropriate icon and insert it into your Markdown content as an inlined SVG.

Example:

markdown_extensions:
  - pymdownx.emoji:
      emoji_index: !!python/name:materialx.emoji.twemoji
      emoji_generator: !!python/name:materialx.emoji.to_svg

Then, using the folder structure of Material's .icons folder, you can specify icons:

We can use Material Icons :material-airplane:.

We can also use Fontawesome Icons :fontawesome-solid-ambulance:.

That's not all, we can also use Octicons :octicons-octoface:.

Using Local Custom Icons

In MkDocs, you can override theme assets locally, and even add assets to the theme. Unfortunately, the Markdown parsing process isn't aware of the MkDocs environment. Luckily, if you are using PyMdown Extensions 7.1, you can pass in custom icon paths that will be used when constructing the emoji index and include your custom SVG assets. If a folder path of theme/my_icons was given to the index builder, all icons under my_project/my_icons, even in sub-folders, would become part of the index.

markdown_extensions:
  - pymdownx.emoji:
      emoji_index: !!python/name:materialx.emoji.twemoji
      emoji_generator: !!python/name:materialx.emoji.to_svg
      options:
        custom_icons:
          - theme/my_icons

If given an icon at my_project/my_icons/animals/bird.svg, the icon would be available using the emoji syntax as :animals-bird:. Notice that the base folder that is provided doesn't contribute to the icon's name. Also, folders are separated with -. Folder names and icon names should be compatible with the emoji syntax, so special characters should be avoided -- - and _ are okay.

You can provide as many paths as you would like, and they will be evaluated in the order that they are specified. The Material theme's own icons will be evaluated after all custom paths. This allows a user to override Material's icons if desired.

If an icon name is already in the index, the icon will not be added. It is recommended to always have your icons in sub-folders to help namespace them to avoid name collisions. In the example above, bird was under animals which created the name :animals-bird: and helped create a more unique name with less of a chance of creating a duplicate name with existing emoji and Material icons.

mkdocs-material-extensions's People

Contributors

facelessuser avatar oprypin avatar squidfunk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mkdocs-material-extensions's Issues

materialx/emoji.py wants to import material, but the potential dependency isn't listed in setup.py

Hi,

while trying to improve the Debian packaging for mkdocs-material-extensions I want to get the tests working.
This fails currently as materialx/emoji.py is trying to import a module material.

   dh_auto_test -O--buildsystem=pybuild
I: pybuild base:240: cd /build/mkdocs-material-extensions-1.0.3/.pybuild/cpython3_3.10_materialx/build; python3.10 -m unittest discover -v 
tests.extensions.test_emoji (unittest.loader._FailedTest) ... ERROR

======================================================================
ERROR: tests.extensions.test_emoji (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: tests.extensions.test_emoji
Traceback (most recent call last):
  File "/usr/lib/python3.10/unittest/loader.py", line 436, in _find_test_path
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.10/unittest/loader.py", line 377, in _get_module_from_name
    __import__(name)
  File "/build/mkdocs-material-extensions-1.0.3/.pybuild/cpython3_3.10_materialx/build/tests/extensions/test_emoji.py", line 3, in <module>
    from materialx import emoji
  File "/build/mkdocs-material-extensions-1.0.3/.pybuild/cpython3_3.10_materialx/build/materialx/emoji.py", line 11, in <module>
    import material
ModuleNotFoundError: No module named 'material'


----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)

The setup.py file nor requirements/project.txt is holding any list of depending packages.

The only reference for a module named material I've found on PyPi is quite old. https://pypi.org/project/material/
But this looks not quite the correct one. If this the correct thing, is it really needed to include that old code with only a few lines of code, it was last touched in 2014? Couldn't get this included into the package itself somehow. Otherwise I would need to get this old stuff packaged for Debian and this isn't something I'd do with joy. :-/

Github Page is down

While trying to figure out the emoji syntax, I tried clicking all the links in the README and all of them 404. It looks like https://facelessuser.github.io/mkdocs-material-extensions/extensions/emoji no longer exists.

This site being down / no real documentation on the emoji naming scheme is making it difficult to figure out what an emoji's name is in markdown. I've spend quite some time trying to figure out how to get the windows logo to work, knowing that it's in font awesome.

Custom icons are not available with the markdown syntax

Description

When adding custom icons as described with squidfunk/mkdocs-material#1620, I want to use them not only in the mkdocs.yml but also from within markdown.

Two potential setups come to mind:

  1. Add custom icons within a new namespace (e.g. bootstrap)
  2. Overwrite icons from an exisiting namespace (e.g. fontawesome/brands) Not sure why you want to do that, but it is technically possible

Setup

  1. I use the exact same setup that mkdocs-material recommends.
  2. I specify the mkdocs-material-extension within requirements.txt as it is not pulled by pip yet (I assume since mkdocs throws errors without).

Working example

I will use the following directory structure, a working example can be found at mkdocs-material-playground on the "Home" page:

theme: 
    name: material
    custom_dir: theme

    icon:
        logo: bootstrap/circle-square
docs
    index.md
theme
    .icons 
        bootstrap
            circle-square.svg (newly added)
        fontawesome
            brands
                git-alt.svg (replaced with bootstrap/app.svg)
mkdocs.yml

and the icons from a markdown file:

1. Default icon: :material-pen:
2. Bootstrap custom icon: :bootstrap-circle-square:
3. Fontawesome overwritten icon: :fontawesome-brands-git-alt:

Note that I have purposefully overwritten fontawesome/brands/git-alt.svg to see what mkdocs-material does with it. It is correctly displayed as repository icon (However, as noted above, I am not sure if that is really a use case to consider).

I have a custom stylesheet in place which scales the icons to the correct size.

Expectation

Following the naming schema as described in the readme, I would assume that the new icons are available from within markdown.

  1. Default icon is displayed (as proof it is working). This works.
  2. Custom icon should be displayed. This is not replaced
  3. Overwritten icon should be changed (see above). The original icon is displayed.

Solution

While I do not fully understand how your extension integrates into mkdocs, I assume that you get the icons from within mkdocs-material folder via this line.

If it is at all possible that you access the custom .icons folder, they should be loaded first, so that the index is populated before loading those from mkdocs-material/material/.icons.

typo in pyproject.toml

Hi @facelessuser

I just noticed the following typo in line 27 of pyproject.toml.

Homepage = "https://github.com/facelessuser/mkdocs-material-extensions'"

The last char of the url is a single quote. So the url is invalid right now.

Hope this might be helpful.

Regards, Jean-Luc

Non-Pre Release

Please consider cutting a new release that does not include pre-release specifiers (currently 1.0b1).


I ran into this issue when updating a mkdocs-material site to mkdocs 1.1 and mkdocs-material 5.x. mkdocs-material relies on mkdocs-material-extensions>=1.0b1 (presumably as that's the latest release): https://github.com/squidfunk/mkdocs-material/blob/c5f9c53116e974e6027c216cd6e5103e636d44e1/requirements.txt#L26

This caused issues with our site, the environment of which is managed by pipenv. It seems that pipenv considers 1.0b1 to be a "pre-release" due to the b1 specifier. I believe this is because it is attempting to apply semver rules (though under semver, there would be a - before b1). Regardless, this means that pipenv is unable to set up the environment without forcing it to allow pre-releases (which is not ideal for production).

If 1.0b1 is stable (or "stable enough" to be included in a stable release of mkdocs-material), please consider a new 1.0 release so that downstream consumers can use a stable version without allowing pre-release versions into the environment.

(If you consider this to be a mkdocs-material problem as that project is depending on a pre-release version, I am happy to open an issue in that repo. Let me know. I'll note that with no other mkdocs-material-extensions releases, it seems that the only solution on the mkdocs-material side would be to stop using this library until it has a stable release)

Support for custom icons

I was wondering, if this can also be used, to directly integrate custom (own) SVG icons, which are included through theme-extension.

For example having the icon.svg in a custom folder would allow to have :custom-icon:

Deprecate after Material 9.4 Releases

We've long felt that this work should live in the MkDocs Material repo, but we provided it as a courtesy as Material was uncomfortable maintaining this extension.

With the upcoming release of MkDocs Material 9.4, the maintainer now feels confident enough to maintain this extension. Once this release is made, and everything has been confirmed to have 1:1 behavior, we will deprecate this extension and generate a warning to use the Material's version.

This is a much better arrangement moving forward as Material will have all the "Material" support baked in and we can focus on Pymdown Extensions.

[Feature request] host emoji's with site

Is it possible to have a feature where instead of having an external CDN provide the emoji icons, that they could be downloaded during the mkdocs build stage to be hosted along with the site that was built.

This feature would be a valuable one in relation to privacy. As the user browsing the site would not be contacting a third party. The theme provided icons are a good example of being provided by the same host as the site.

Currently I use the material theme and haven't deployed it yet due to emoji's being provided by a third party and therefore a privacy concern.

Idea for config (add a .to_local to the generator)

markdown_extensions:
  - pymdownx.emoji:
      emoji_index: !!python/name:materialx.emoji.twemoji
      emoji_generator: !!python/name:materialx.emoji.to_local

Possible workflow

  • as the site is being built by mkdocs, every emoji found is downloaded to assets/emoji/{provider}/{emoji_name}.svg
  • the the CDN URL would be set to a reletive link to the emoji folder. If not a relative link, use site_name from config and append the emoji path.
  • preference would be to download instead of imbed as this enables browser caching to be utilised.

Have looked at the licence of twemoji, my proposal doesn't create any issues there.

Icon set discovery broken on Poetry installations, due to unescaped glob path

I'm running mkdocs-material using Poetry and a Python 3.10 installation from the Windows Store.

In emoji.py:43, there's the following expression:

glob.glob(icon_path.replace('\\', '/') + '/**/*.svg', recursive=True)

This doesn't yield any files for me. The issue is that Poetry generates square brackets in folder names, and these have significance for the glob() function. For example:

C:\Users\me\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\Local\pypoetry\Cache\virtualenvs\[mkdocs]-yKbMSAs--py3.10\lib\site-packages\material\.icons

Therefore:

>>> glob.glob(icon_path + '/**/*.svg', recursive=True)
[]

The cleanest solution I've found is to separate pattern from directory by using the root_dir argument:

>>> glob.glob('**/*.svg', root_dir=icon_path, recursive=True)
['logo.svg', 'fontawesome\\brands\\42-group.svg', 'fontawesome\\brands\\500px.svg', ...

However, I believe that parameter was introduced in Python 3.10 and I think mkdocs-material specifies 3.7+ in its requirements.

So alternatively, there's glob.escape(). This works:

>>> glob.glob(glob.escape(icon_path) + '/**/*.svg', recursive=True)
['C:\\Users\\me\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\LocalCache\\Local\\pypoetry\\Cache\\virtualenvs\\[mkdocs]-yKbMSAs--py3.10\\lib\\site-packages\\material\\.icons\\logo.svg', ...

I'm not sure what the purpose of the .replace('\\', '/') call was, because the glob module has no issues with either backslashes or slashes on Windows in my tests. Was this an attempt of platform-independence? Either way, I would suggest not doing this manually, but using pathlib instead:

>>> glob.glob(str(pathlib.Path(glob.escape(icon_path)) / '**' / '*.svg'), recursive=True)
['C:\\Users\\me\\AppData\\Local\\Packages\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\LocalCache\\Local\\pypoetry\\Cache\\virtualenvs\\[mkdocs]-yKbMSAs--py3.10\\lib\\site-packages\\material\\.icons\\logo.svg', ...

PS: Your PyPI page has a broken Homepage link, it contains a superfluous apostrophe and links here.

[Feature Request] YouTube Embeds

I'm not sure what your intentions for this project are, but I currently do some very ugly hacks in JavaScript at the moment to get a few missing Markdown features working.

One of them is a tag for YouTube embeds. Currently I'm scanning the alt tag of images for YOUTUBE and then replace the image with an iframe like so:

const elements = document.querySelectorAll("img[alt=\"YOUTUBE\"]")

  Array.prototype.forEach.call(elements, (el, i) => {
    const id = el.getAttribute("title").split("/")[el.getAttribute("title").split("/").length - 1]
    const oldClass = el.getAttribute("class")
    const iframe = document.createElement("iframe")

    iframe.title = "YouTube"
    iframe.src = `https://www.youtube.com/embed/${id}?modestbranding=1&amp;`

    if (oldClass !== "null") {
      iframe.className = `video-embed ${oldClass}`
    } else {
      iframe.className = "video-embed"
    }

    el.replaceWith(iframe)
  })

Now if we could do this natively and on compile instead of run, that would be great.

Custom icons and `mkdocs serve` (rebuild) behavior

First, thanks for the custom icon set support!

Writing down what I'm experiencing using a custom icon directory with mkdocs-material 5.2.2 docker's image.

markdown_extensions:
  - pymdownx.emoji:
      emoji_index: !!python/name:materialx.emoji.twemoji
      emoji_generator: !!python/name:materialx.emoji.to_svg
      options:
        custom_icons:
          - custom_theme/my_icons

I'm noticing that rebuilds get longer each during mkdocs serve with a custom icon set. _patch_index is called for each markdown file I think. I started modifying the docker image's emojy.py and found a workaround but not sure the ideal fix.

Workaround:

docker run -it -v ${PWD}:/docs -v ${PWD}/deploy/dist:/docs/site --entrypoint /bin/sh squidfunk/mkdocs-material:5.2.2
PATCHED_INDEX = None

def _patch_index(options):
    """Patch the given index."""
    global PATCHED_INDEX
    if PATCHED_INDEX is not None:
        return PATCHED_INDEX
...
    # Before return
    PATCHED_INDEX = index

I think the append keeps adding RESOURCES for each call of _patch_index. Then the globbing grows over time. Another option would be to copy the options.get('custom_icons', []).copy() instead of workaround above.

https://github.com/facelessuser/mkdocs-material-extensions/blob/master/materialx/emoji.py#L32

Build time significantly increases with custom_icons

This is a followup / repost of squidfunk/mkdocs-material#1942

Description

The site build time significantly increases (x8) when additional icons are enabled via custom_icons.

Expected behavior

Same, or at least comparable build times with or without additional icons.

Actual behavior

  • without additional icons:
    $ grep -A3 pymdownx.emoji mkdocs.yml
      - pymdownx.emoji:
          emoji_index: !!python/name:materialx.emoji.twemoji
          emoji_generator: !!python/name:pymdownx.emoji.to_svg
          #    options:
          #  custom_icons:
          #    - overrides/.icons
    $ time mkdocs -q build
    
    real    0m8.947s
    user    0m8.744s
    sys     0m0.645s
    
  • with additional icons:
    $ grep -A3 pymdownx.emoji mkdocs.yml
      - pymdownx.emoji:
          emoji_index: !!python/name:materialx.emoji.twemoji
          emoji_generator: !!python/name:pymdownx.emoji.to_svg
          options:
            custom_icons:
              - overrides/.icons
    $ time mkdocs -q build
    
    real    0m57.974s
    user    0m50.919s
    sys     0m7.643s
    

The actual icons don't seem to matter, nor the number of icons in overrides/.icons.

What seems to be happening is that with custom_icons enabled, mkdocs spends more and more time to read each page, as it's progressing through them. In verbose mode you can see that each of the lines:

DEBUG   -  Reading: docs/page.md

takes longer to process than the previous one, and end up almost crawling to a halt.
Without custom_icons, the build process goes through all of then quickly, each page taking the same time to read.

Steps to reproduce the bug

  1. enable custom icons in mkdocs.yml as per the materials for MkDocs documentation
  2. build the pages with mdocs build or mkdocs serve

Package versions

  • Python: Python 3.7.8
  • MkDocs: mkdocs, version 1.1.2
  • mkdocs-material-extensions: 1.0

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.