-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4b4e887
Showing
14 changed files
with
1,185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# editorconfig.org | ||
|
||
root = true | ||
|
||
[*] | ||
charset = utf-8 | ||
indent_size = 4 | ||
indent_style = space | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
|
||
[*.{js,ts,css,scss}] | ||
indent_size = 2 | ||
|
||
[*.md, *.rst] | ||
trim_trailing_whitespace = false | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text=auto eol=lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Python Bytecode | ||
*.pyc | ||
|
||
# Building and Distributing | ||
/*.egg-info | ||
/.eggs | ||
/build | ||
/dist | ||
/docs/_build | ||
|
||
# Various Tools | ||
/.coverage | ||
/coverage.xml | ||
/htmlcov | ||
/env | ||
/venv | ||
/.vagrant | ||
/.cache | ||
|
||
# Tests | ||
/.pytest_cache | ||
/tests/test_draw/results |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"cSpell.words": [ | ||
"mkdocs", | ||
"orzih" | ||
], | ||
"python.linting.pylintEnabled": false, | ||
"python.linting.flake8Enabled": true, | ||
"python.linting.enabled": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Contribution Guidelines | ||
|
||
Thank you for considering to contribute to this project. These guidelines will help you get going with development and outline the most important rules to follow when submitting pull requests for this project. | ||
|
||
## Submitting Changes | ||
|
||
To get changes merged, create a pull request. Here are a few things to pay attention to when doing so: | ||
|
||
### Commit Messages | ||
|
||
The summary of a commit should be concise and worded in an imperative mood. | ||
...a *what* mood? This should clear things up: *[How to Write a Git Commit Message][git-commit-message]* | ||
|
||
### Code Style | ||
|
||
Make sure your code follows [PEP-8](https://www.python.org/dev/peps/pep-0008/) and keeps things consistent with the rest of the code. | ||
|
||
[git-commit-message]: https://chris.beams.io/posts/git-commit/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# MIT License | ||
|
||
Copyright (c) 2021, orzih | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
recursive-exclude * __pycache__ | ||
recursive-exclude * *.py[co] | ||
include README.md | ||
include LICENSE.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# mkdocs-extra-sass-plugin | ||
|
||
[![PyPI version](https://img.shields.io/pypi/v/mkdocs-extra-sass-plugin.svg)](https://pypi.org/project/mkdocs-extra-sass-plugin) | ||
[![PyPI downloads](https://img.shields.io/pypi/dm/mkdocs-extra-sass-plugin.svg)](https://pypi.org/project/mkdocs-extra-sass-plugin) | ||
|
||
--- | ||
|
||
This plugin adds stylesheets to your mkdocs site from `Sass`/`SCSS`. | ||
|
||
## Features | ||
|
||
* using [LibSass][LibSass] with [libsass-python][libsass-python]. | ||
|
||
## How to use | ||
|
||
### Installation | ||
|
||
1. Install the package with pip: | ||
|
||
```sh | ||
pip install mkdocs-extra-sass-plugin | ||
``` | ||
|
||
2. Enable the plugin in your `mkdocs.yml`: | ||
|
||
```yml | ||
plugins: | ||
- extra-sass | ||
``` | ||
|
||
> **Note**: If you have no `plugins` entry in your config file yet, you'll likely also want to add the `search` plugin. MkDocs enables it by default if there is no `plugins` entry set, but now you have to enable it explicitly. | ||
3. Create a `extra_sass` directory in your working directory _(usually the same directory as` mkdocs.yml`)_, and create **entry point file** named `style.css.sass` or `style.css.scss`. | ||
|
||
```none | ||
(top) | ||
├── docs | ||
: ...snip... | ||
│ └── index.md | ||
├── extra_sass | ||
: ...snip... | ||
│ └── style.css.scss (or style.css.sass) # compiler entry point file. | ||
└── mkdocs.yml | ||
``` | ||
|
||
More information about plugins in the [MkDocs documentation][mkdocs-plugins]. | ||
|
||
## Contributing | ||
|
||
From reporting a bug to submitting a pull request: every contribution is appreciated and welcome. Report bugs, ask questions and request features using [Github issues][github-issues]. | ||
If you want to contribute to the code of this project, please read the [Contribution Guidelines][contributing]. | ||
|
||
[LibSass]: https://sass-lang.com/libsass | ||
[libsass-python]: https://github.com/sass/libsass-python | ||
[mkdocs-plugins]: https://www.mkdocs.org/user-guide/plugins/ | ||
[github-issues]: https://github.com/orzih/mkdocs-extra-sass-plugin/issues | ||
[contributing]: https://github.com/orzih/mkdocs-extra-sass-plugin/blob/master/CONTRIBUTING.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = '0.1.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
import io | ||
import logging | ||
import os | ||
from abc import ABC | ||
from tempfile import NamedTemporaryFile | ||
from typing import Type, TypeVar | ||
|
||
import sass | ||
from bs4 import BeautifulSoup | ||
from livereload import Server | ||
from mkdocs.config import Config | ||
from mkdocs.plugins import BasePlugin | ||
from mkdocs.structure.pages import Page | ||
from mkdocs.utils import normalize_url | ||
|
||
_T_SassEntry = TypeVar('_T', bound='_SassEntry') | ||
|
||
|
||
_logger = logging.getLogger('mkdocs.extra-sass') | ||
|
||
|
||
class ExtraSassPlugin(BasePlugin): | ||
"""Extra Sass Plugin""" | ||
|
||
def __init__(self): | ||
self.__entry_point = None | ||
|
||
def on_config(self, config: Config): | ||
self.__entry_point = None | ||
|
||
def on_serve(self, server: Server, config: Config, builder, **kwargs): | ||
self._entry_point(config).on_serve(server, builder) | ||
return server | ||
|
||
def on_post_page( | ||
self, output_content: str, page: Page, config: Config | ||
) -> str: | ||
relative_path = self._entry_point(config).relative_path | ||
if not relative_path: | ||
return output_content | ||
|
||
# injection | ||
|
||
href = normalize_url(relative_path, page=page) | ||
|
||
soup = BeautifulSoup(output_content, 'html.parser') | ||
|
||
stylesheet = soup.new_tag('link') | ||
stylesheet.attrs['href'] = href | ||
stylesheet.attrs['rel'] = 'stylesheet' | ||
|
||
soup.head.append(stylesheet) | ||
|
||
_logger.debug( | ||
"[SASS] add on Page: %s, entry_point: %s" % | ||
(page.url, stylesheet)) | ||
_logger.debug(str(soup.head)) | ||
|
||
return str(soup) | ||
|
||
# ------------------------------ | ||
|
||
def _entry_point(self, config: Config) -> _T_SassEntry: | ||
if self.__entry_point is None: | ||
self.__entry_point = self._build_entry(config) | ||
return self.__entry_point | ||
|
||
def _build_entry(self, config: Config) -> _T_SassEntry: | ||
entry_point = _SassEntry.search_entry_point() | ||
if entry_point.is_available: | ||
try: | ||
site_dir = config["site_dir"] | ||
dest_dir = os.path.join("assets", "stylesheets") | ||
info = entry_point.save_to(site_dir, dest_dir) | ||
_logger.info( | ||
'[SASS] Build CSS "%s" from "%s"' % ( | ||
info['dst'], info['src'])) | ||
except Exception as ex: | ||
_logger.exception('[SASS] Failed to build CSS: %s', ex) | ||
if config['strict']: | ||
raise ex | ||
|
||
return entry_point | ||
|
||
|
||
# ============================== | ||
# | ||
# | ||
|
||
|
||
class _SassEntry(ABC): | ||
|
||
_styles_dir = 'extra_sass' | ||
_style_filenames = [ | ||
'style.css.sass', 'style.sass', | ||
'style.css.scss', 'style.scss', | ||
] | ||
|
||
@classmethod | ||
def search_entry_point(cls: Type[_T_SassEntry]) -> _T_SassEntry: | ||
d = cls._styles_dir | ||
if os.path.isdir(d): | ||
for f in cls._style_filenames: | ||
path = os.path.join(d, f) | ||
if path and os.path.isfile(path): | ||
return _AvailableSassEntry(d, f) | ||
return _NoSassEntry() | ||
|
||
@property | ||
def is_available(self) -> bool: | ||
return False | ||
|
||
@property | ||
def relative_path(self) -> str: | ||
return "" | ||
|
||
def on_serve(self, server: Server, builder) -> None: | ||
pass | ||
|
||
def save_to(self, site_dir: str, dest_dir: str) -> dict: | ||
raise AssertionError('DO NOT CALL HERE') | ||
|
||
|
||
class _NoSassEntry(_SassEntry): | ||
pass | ||
|
||
|
||
class _AvailableSassEntry(_SassEntry): | ||
|
||
def __init__(self, dirname: str, filename: str): | ||
self._dirname = dirname | ||
self._filename = filename | ||
|
||
self._relative_path = None | ||
|
||
@property | ||
def is_available(self) -> bool: | ||
return True | ||
|
||
@property | ||
def relative_path(self) -> str: | ||
""" Compiled CSS file: relative path from `SITE_DIR` """ | ||
return self._relative_path | ||
|
||
def on_serve(self, server: Server, builder) -> None: | ||
source_path = os.path.join(self._dirname, self._filename) | ||
if os.path.isfile(source_path): | ||
server.watch(self._dirname, builder) | ||
|
||
def save_to(self, site_dir: str, dest_dir: str) -> dict: | ||
|
||
def fix_umask(temp_file): | ||
# see: https://stackoverflow.com/questions/10541760/can-i-set-the-umask-for-tempfile-namedtemporaryfile-in-python # noqa: E501 | ||
umask = os.umask(0o666) | ||
os.umask(umask) | ||
os.chmod(temp_file.name, 0o666 & ~umask) | ||
|
||
source_path = os.path.join(self._dirname, self._filename) | ||
|
||
output_dir = os.path.join(site_dir, dest_dir) | ||
os.makedirs(output_dir, exist_ok=True) | ||
|
||
with NamedTemporaryFile( | ||
prefix='extra-style.', | ||
suffix='.min.css', | ||
dir=output_dir, | ||
delete=False, | ||
mode='w', | ||
encoding='utf-8', | ||
newline='' | ||
) as css_file: | ||
fix_umask(css_file) | ||
|
||
_, filename = os.path.split(css_file.name) | ||
source_map_filename = filename + '.map' | ||
|
||
css, source_map = sass.compile( | ||
filename=source_path, | ||
output_style='compressed', | ||
source_map_filename=source_map_filename, | ||
source_map_contents=True, | ||
omit_source_map_url=False, | ||
output_filename_hint=filename | ||
) | ||
|
||
css_file.write(css) | ||
|
||
map_file = os.path.join(output_dir, source_map_filename) | ||
with io.open(map_file, 'w', encoding='utf-8', newline='') as f: | ||
f.write(source_map) | ||
|
||
self._relative_path = os.path.join(dest_dir, filename) | ||
|
||
return { | ||
'src': source_path, | ||
'dst': self._relative_path | ||
} |
Oops, something went wrong.