test bkp
This commit is contained in:
1 parent
6ccab0347b
commit
954a2fd6d6
18684 files changed
+601012
-190
No files matched your search
@@ -0,0 +1,190 @@
|
||||
"""
|
||||
Path Converter.
|
||||
|
||||
pymdownx.pathconverter
|
||||
An extension for Python Markdown.
|
||||
|
||||
An extension to covert tag paths to relative or absolute:
|
||||
|
||||
Given an absolute base and a target relative path, this extension searches for file
|
||||
references that are relative and converts them to a path relative
|
||||
to the base path.
|
||||
|
||||
-or-
|
||||
|
||||
Given an absolute base path, this extension searches for file
|
||||
references that are relative and converts them to absolute paths.
|
||||
|
||||
MIT license.
|
||||
|
||||
Copyright (c) 2014 - 2017 Isaac Muse <isaacmuse@gmail.com>
|
||||
|
||||
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.
|
||||
"""
|
||||
from markdown import Extension
|
||||
from markdown.postprocessors import Postprocessor
|
||||
from . import util
|
||||
import os
|
||||
import re
|
||||
from urllib.parse import urlunparse
|
||||
|
||||
RE_TAG_HTML = r'''(?xus)
|
||||
(?:
|
||||
(?P<avoid>
|
||||
<\s*(?P<script_name>script|style)[^>]*>.*?</\s*(?P=script_name)\s*> |
|
||||
(?:(\r?\n?\s*)<!--[\s\S]*?-->(\s*)(?=\r?\n)|<!--[\s\S]*?-->)
|
||||
)|
|
||||
(?P<open><\s*(?P<tag>(?:%s)))
|
||||
(?P<attr>(?:\s+[\w\-:]+(?:\s*=\s*(?:"[^"]*"|'[^']*'))?)*)
|
||||
(?P<close>\s*(?:\/?)>)
|
||||
)
|
||||
'''
|
||||
|
||||
RE_TAG_LINK_ATTR = re.compile(
|
||||
r'''(?xus)
|
||||
(?P<attr>
|
||||
(?:
|
||||
(?P<name>\s+(?:href|src)\s*=\s*)
|
||||
(?P<path>"[^"]*"|'[^']*')
|
||||
)
|
||||
)
|
||||
'''
|
||||
)
|
||||
|
||||
|
||||
def repl_relative(m, base_path, relative_path):
|
||||
"""Replace path with relative path."""
|
||||
|
||||
link = m.group(0)
|
||||
try:
|
||||
scheme, netloc, path, params, query, fragment, is_url, is_absolute = util.parse_url(m.group('path')[1:-1])
|
||||
|
||||
if not is_url:
|
||||
# Get the absolute path of the file or return
|
||||
# if we can't resolve the path
|
||||
path = util.url2path(path)
|
||||
if (not is_absolute):
|
||||
# Convert current relative path to absolute
|
||||
path = os.path.relpath(
|
||||
os.path.normpath(os.path.join(base_path, path)),
|
||||
os.path.normpath(relative_path)
|
||||
)
|
||||
# Convert the path, URL encode it, and format it as a link
|
||||
path = util.path2url(path)
|
||||
link = '{}"{}"'.format(
|
||||
m.group('name'),
|
||||
urlunparse((scheme, netloc, path, params, query, fragment))
|
||||
)
|
||||
except Exception: # pragma: no cover
|
||||
# Parsing crashed and burned; no need to continue.
|
||||
pass
|
||||
|
||||
return link
|
||||
|
||||
|
||||
def repl_absolute(m, base_path, file_scheme):
|
||||
"""Replace path with absolute path."""
|
||||
|
||||
link = m.group(0)
|
||||
try:
|
||||
scheme, netloc, path, params, query, fragment, is_url, is_absolute = util.parse_url(m.group('path')[1:-1])
|
||||
|
||||
if (not is_absolute and not is_url):
|
||||
path = util.url2path(path)
|
||||
path = os.path.normpath(os.path.join(base_path, path))
|
||||
path = util.path2url(path)
|
||||
if file_scheme:
|
||||
if not path.startswith('/'):
|
||||
path = '/' + path
|
||||
link = '{}"{}"'.format(
|
||||
m.group('name'),
|
||||
urlunparse(("file", netloc, path, params, query, fragment))
|
||||
)
|
||||
else:
|
||||
start = '/' if not path.startswith('/') else ''
|
||||
link = '{}"{}{}"'.format(
|
||||
m.group('name'),
|
||||
start,
|
||||
urlunparse((scheme, netloc, path, params, query, fragment))
|
||||
)
|
||||
except Exception: # pragma: no cover
|
||||
# Parsing crashed and burned; no need to continue.
|
||||
pass
|
||||
|
||||
return link
|
||||
|
||||
|
||||
def repl(m, base_path, rel_path=None, file_scheme=None):
|
||||
"""Replace."""
|
||||
|
||||
if m.group('avoid'):
|
||||
tag = m.group('avoid')
|
||||
else:
|
||||
tag = m.group('open')
|
||||
if rel_path is None:
|
||||
tag += RE_TAG_LINK_ATTR.sub(lambda m2: repl_absolute(m2, base_path, file_scheme), m.group('attr'))
|
||||
else:
|
||||
tag += RE_TAG_LINK_ATTR.sub(lambda m2: repl_relative(m2, base_path, rel_path), m.group('attr'))
|
||||
tag += m.group('close')
|
||||
return tag
|
||||
|
||||
|
||||
class PathConverterPostprocessor(Postprocessor):
|
||||
"""Post process to find tag lings to convert."""
|
||||
|
||||
def run(self, text):
|
||||
"""Find and convert paths."""
|
||||
|
||||
basepath = self.config['base_path']
|
||||
relativepath = self.config['relative_path']
|
||||
absolute = bool(self.config['absolute'])
|
||||
filescheme = bool(self.config['file_scheme'])
|
||||
tags = re.compile(RE_TAG_HTML % '|'.join(self.config['tags'].split()))
|
||||
if not absolute and basepath and relativepath:
|
||||
text = tags.sub(lambda m: repl(m, basepath, rel_path=relativepath), text)
|
||||
elif absolute and basepath:
|
||||
text = tags.sub(lambda m: repl(m, basepath, file_scheme=filescheme), text)
|
||||
return text
|
||||
|
||||
|
||||
class PathConverterExtension(Extension):
|
||||
"""PathConverter extension."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize."""
|
||||
|
||||
self.config = {
|
||||
'base_path': ["", "Base path used to find files - Default: \"\""],
|
||||
'relative_path': ["", "Path that files will be relative to (not needed if using absolute) - Default: \"\""],
|
||||
'absolute': [False, "Paths are absolute by default; disable for relative - Default: False"],
|
||||
'tags': ["img script a link", "tags to convert src and/or href in - Default: 'img scripts a link'"],
|
||||
'file_scheme': [False, "Use file:// scheme for absolute paths - Default: False"],
|
||||
}
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def extendMarkdown(self, md):
|
||||
"""Add post processor to Markdown instance."""
|
||||
|
||||
rel_path = PathConverterPostprocessor(md)
|
||||
rel_path.config = self.getConfigs()
|
||||
md.postprocessors.register(rel_path, "path-converter", 2)
|
||||
md.registerExtension(self)
|
||||
|
||||
|
||||
def makeExtension(*args, **kwargs):
|
||||
"""Return extension."""
|
||||
|
||||
return PathConverterExtension(*args, **kwargs)
|
||||
Reference in new issue
Block a user