diff --git a/_unittests/ut_helpgen/test_rst2html_toc.py b/_unittests/ut_helpgen/test_rst2html_toc.py
index c80672df..8e941a86 100644
--- a/_unittests/ut_helpgen/test_rst2html_toc.py
+++ b/_unittests/ut_helpgen/test_rst2html_toc.py
@@ -8,12 +8,14 @@
import unittest
from pyquickhelper.loghelper.flog import fLOG
-from pyquickhelper.pycode import get_temp_folder, is_travis_or_appveyor
+from pyquickhelper.pycode import (
+ get_temp_folder, is_travis_or_appveyor, ignore_warnings)
from pyquickhelper.helpgen import rst2html
class TestRst2HtmlToc(unittest.TestCase):
+ @ignore_warnings(PendingDeprecationWarning)
def test_rst2html_toc(self):
fLOG(
__file__,
@@ -58,6 +60,7 @@ def test_rst2html_toc(self):
f.write(text)
self.assertIn("* :ref:`title2`", text)
+ @ignore_warnings(PendingDeprecationWarning)
def test_rst2html_autoclass(self):
fLOG(
__file__,
@@ -89,6 +92,7 @@ def test_rst2html_autoclass(self):
f.write(text)
self.assertIn("* ``:indent:`` to indent the output", text)
+ @ignore_warnings(PendingDeprecationWarning)
def test_rst2html_toctree(self):
fLOG(
__file__,
diff --git a/src/pyquickhelper/helpgen/sphinx_main.py b/src/pyquickhelper/helpgen/sphinx_main.py
index 2b330209..630e814a 100644
--- a/src/pyquickhelper/helpgen/sphinx_main.py
+++ b/src/pyquickhelper/helpgen/sphinx_main.py
@@ -637,14 +637,15 @@ def lay_build_override_newconf(t3):
if os.path.exists(blog_fold):
fLOG("[generate_help_sphinx] BlogPostList")
- plist = BlogPostList(blog_fold, language=language, fLOG=fLOG)
+ plist = BlogPostList(blog_fold, language=language, fLOG=fLOG,
+ conf=theconf)
fLOG("[generate_help_sphinx] BlogPostList.write_aggregated")
- plist.write_aggregated(blog_fold,
- blog_title=theconf.__dict__.get(
- "blog_title", project_var_name),
- blog_description=theconf.__dict__.get(
- "blog_description", "blog associated to " + project_var_name),
- blog_root=theconf.__dict__.get("blog_root", "__BLOG_ROOT__"))
+ plist.write_aggregated(
+ blog_fold,
+ blog_title=theconf.__dict__.get("blog_title", project_var_name),
+ blog_description=theconf.__dict__.get(
+ "blog_description", "blog associated to " + project_var_name),
+ blog_root=theconf.__dict__.get("blog_root", "__BLOG_ROOT__"))
else:
plist = None
diff --git a/src/pyquickhelper/sphinxext/blog_post.py b/src/pyquickhelper/sphinxext/blog_post.py
index dee364c4..e803824e 100644
--- a/src/pyquickhelper/sphinxext/blog_post.py
+++ b/src/pyquickhelper/sphinxext/blog_post.py
@@ -27,7 +27,7 @@ class BlogPost:
"""
def __init__(self, filename, encoding='utf-8-sig', raise_exception=False,
- extensions=None, **kwargs_overrides):
+ extensions=None, conf=None, **kwargs_overrides):
"""
Creates an instance of a blog post from a file or a string.
@@ -39,6 +39,7 @@ def __init__(self, filename, encoding='utf-8-sig', raise_exception=False,
the content of the blog, if None, it will consider
a default list (see @see cl BlogPost and
@see fn get_default_extensions)
+ :param conf: existing configuration
:param kwargs_overrides: additional parameters for :epkg:`sphinx`
The constructor creates the following members:
@@ -77,14 +78,16 @@ def __init__(self, filename, encoding='utf-8-sig', raise_exception=False,
overrides["blog_background"] = True
overrides["blog_background_page"] = False
overrides["sharepost"] = None
- overrides['epkg_dictionary'] = get_epkg_dictionary()
+ if conf is None or not getattr(conf, 'epkg_dictionary'):
+ overrides['epkg_dictionary'] = get_epkg_dictionary()
+ else:
+ overrides['epkg_dictionary'] = conf.epkg_dictionary
overrides.update(kwargs_overrides)
overrides.update({ # 'warning_stream': StringIO(),
'out_blogpostlist': [],
'out_runpythonlist': [],
- 'master_doc': 'stringblog'
- })
+ 'master_doc': 'stringblog'})
if "extensions" not in overrides:
if extensions is None:
@@ -97,7 +100,7 @@ def __init__(self, filename, encoding='utf-8-sig', raise_exception=False,
app = MockSphinxApp.create(confoverrides=overrides)
env = app[0].env
config = env.config
-
+
if 'blog_background' not in config:
raise AttributeError( # pragma: no cover
"Unable to find 'blog_background' in config:\n{0}".format(
@@ -108,9 +111,9 @@ def __init__(self, filename, encoding='utf-8-sig', raise_exception=False,
"\n".join(sorted(config.values))))
if 'epkg_dictionary' in config:
if len(config.epkg_dictionary) > 0:
- overrides['epkg_dictionary'] = config.epkg_dictionary
+ overrides['epkg_dictionary'].update(config.epkg_dictionary)
else:
- overrides['epkg_dictionary'] = get_epkg_dictionary()
+ overrides['epkg_dictionary'].update(get_epkg_dictionary())
env.temp_data["docname"] = "stringblog"
overrides["env"] = env
@@ -334,8 +337,8 @@ def can_cut(i, r, rows_stack):
last = rows_stack[-1]
if len(last) > 0:
last = last[-1]
- if indent == indent2 and len(rs) == 0 and \
- last in {'.', ';', ',', ':', '!', '?'}:
+ if (indent == indent2 and len(rs) == 0 and
+ last in {'.', ';', ',', ':', '!', '?'}):
return True
rows_stack.append(r)
return False
@@ -345,20 +348,16 @@ def can_cut(i, r, rows_stack):
for i, r in enumerate(self.Content):
rows.append(" " + self._update_link(r))
if cut and can_cut(i, r, rows_stack):
- rows.append("")
- rows.append(" ...")
+ rows.extend(["", " ..."])
break
else:
for i, r in enumerate(self.Content):
rows.append(" " + r)
if cut and can_cut(i, r, rows_stack):
- rows.append("")
- rows.append(" ...")
+ rows.extend(["", " ..."])
break
- rows.append("")
- rows.append("")
-
+ rows.extend(["", ""])
return "\n".join(rows)
image_tag = ".. image:: "
@@ -379,5 +378,4 @@ def _update_link(self, row):
return row
row = f"{row[:i]}{self.Year}/{r2}"
return row
- else:
- return row
+ return row
diff --git a/src/pyquickhelper/sphinxext/blog_post_list.py b/src/pyquickhelper/sphinxext/blog_post_list.py
index 6eb909dc..9efab141 100644
--- a/src/pyquickhelper/sphinxext/blog_post_list.py
+++ b/src/pyquickhelper/sphinxext/blog_post_list.py
@@ -18,18 +18,20 @@ class BlogPostList:
Defines a list of @see cl BlogPost.
"""
- def __init__(self, folder, encoding="utf8", language="en", extensions=None, fLOG=noLOG):
+ def __init__(self, folder, encoding="utf8", language="en", extensions=None,
+ conf=None, fLOG=noLOG):
"""
Creates a list of @see cl BlogPost, we assume each blog
post belongs to a subfolder ``YYYY``.
- @param folder folder when to find files
- @param encoding encoding
- @param language language
- @param extensions list of extension to use to parse the content of the blog,
- if None, it will consider a default list
- (@see cl BlogPost and @see fn get_default_extensions)
- @param fLOG logging function
+ :param folder: folder when to find files
+ :param encoding: encoding
+ :param language: language
+ :param extensions: list of extension to use to parse the content
+ of the blog, if None, it will consider a default list
+ (@see cl BlogPost and @see fn get_default_extensions)
+ :param conf: existing configuration
+ :param fLOG: logging function
"""
self._blogposts = []
sub = os.listdir(folder)
@@ -43,7 +45,7 @@ def __init__(self, folder, encoding="utf8", language="en", extensions=None, fLOG
fpost = os.path.join(full, post)
fLOG(f" reading post {post!r}")
obj = BlogPost(fpost, encoding=encoding,
- extensions=extensions)
+ extensions=extensions, conf=conf)
self._blogposts.append((obj.date, obj))
fLOG(f"[BlogPostList] end reading folder {full!r}")
self._blogposts.sort(reverse=True)
diff --git a/src/pyquickhelper/sphinxext/sphinx_blog_extension.py b/src/pyquickhelper/sphinxext/sphinx_blog_extension.py
index cfaf1721..fa7dad0a 100644
--- a/src/pyquickhelper/sphinxext/sphinx_blog_extension.py
+++ b/src/pyquickhelper/sphinxext/sphinx_blog_extension.py
@@ -128,8 +128,9 @@ def run(self):
'lid': self.options.get("lid", self.options.get("label", None)),
}
- tag = BlogPost.build_tag(p["date"], p["title"]) if p[
- 'lid'] is None else p['lid']
+ tag = BlogPost.build_tag(
+ p["date"],
+ p["title"]) if p['lid'] is None else p['lid']
targetnode = nodes.target(p['title'], '', ids=[tag])
p["target"] = targetnode
idbp = tag + "-container"
@@ -140,13 +141,21 @@ def run(self):
env.blogpost_all.append(p)
# build node
- node = self.__class__.blogpost_class(ids=[idbp], year=p["date"][:4],
- rawfile=self.options.get(
- "rawfile", None),
- linktitle=p["title"], lg=language_code,
- blog_background=p["blog_background"])
-
- return self.fill_node(node, env, tag, p, language_code, targetnode, sharepost)
+ if not docname:
+ raise RuntimeError( # pragma: no cover
+ f'docname is missing in blogpost {docname}.')
+ node = self.__class__.blogpost_class(
+ ids=[idbp], year=p["date"][:4],
+ rawfile=self.options.get("rawfile", None),
+ linktitle=p["title"], lg=language_code,
+ blog_background=p["blog_background"])
+ node.source = docname
+ if not node.source:
+ raise RuntimeError( # pragma: no cover
+ f'node.source is missing in blogpost '
+ f'{self.options.get("rawfile", None)}.')
+ return self.fill_node(node, env, tag, p, language_code,
+ targetnode, sharepost)
def fill_node(self, node, env, tag, p, language_code, targetnode, sharepost):
"""
diff --git a/src/pyquickhelper/sphinxext/sphinx_mathdef_extension.py b/src/pyquickhelper/sphinxext/sphinx_mathdef_extension.py
index fb74a408..316d521a 100644
--- a/src/pyquickhelper/sphinxext/sphinx_mathdef_extension.py
+++ b/src/pyquickhelper/sphinxext/sphinx_mathdef_extension.py
@@ -259,7 +259,8 @@ def run(self):
self.state.document.settings, "env") else None
tag = self.options.get('tag', '').strip()
contents = self.options.get(
- 'contents', False) in (True, "True", "true", 1, "1", "", None, "None")
+ 'contents', False) in (True, "True", "true", 1,
+ "1", "", None, "None")
if env is not None:
targetid = f"indexmathelist-{env.new_serialno('indexmathelist')}"
targetnode = nodes.target('', '', ids=[targetid])
diff --git a/src/pyquickhelper/sphinxext/sphinximages/sphinxtrib/images.py b/src/pyquickhelper/sphinxext/sphinximages/sphinxtrib/images.py
index 775a1543..c21beab5 100644
--- a/src/pyquickhelper/sphinxext/sphinximages/sphinxtrib/images.py
+++ b/src/pyquickhelper/sphinxext/sphinximages/sphinxtrib/images.py
@@ -61,11 +61,10 @@ def directive_boolean(value):
raise ValueError("No argument provided but required")
if value.lower().strip() in ["yes", "1", 1, "true", "ok"]:
return True
- elif value.lower().strip() in ['no', '0', 0, 'false', 'none']:
+ if value.lower().strip() in ['no', '0', 0, 'false', 'none']:
return False
- else:
- raise ValueError("Please use on of: yes, true, no, false. "
- "Do not use `{}` as boolean.".format(value))
+ raise ValueError("Please use on of: yes, true, no, false. "
+ "Do not use `{}` as boolean.".format(value))
def get_image_extension(uri):
@@ -110,7 +109,6 @@ def align(self):
'width': directives.length_or_percentage_or_unitless,
'height': directives.length_or_unitless,
'strech': directives.choice,
-
'group': directives.unchanged,
'class': directives.class_option, # or str?
'alt': directives.unchanged,
@@ -126,9 +124,9 @@ def run(self):
env = self.state.document.settings.env
conf = env.app.config.images_config
- # TODO get defaults from config
- group = self.options.get('group',
- conf['default_group'] if conf['default_group'] else uuid.uuid4())
+ group = self.options.get(
+ 'group',
+ conf['default_group'] if conf['default_group'] else uuid.uuid4())
classes = self.options.get('class', '')
width = self.options.get('width', conf['default_image_width'])
height = self.options.get('height', conf['default_image_height'])
@@ -139,12 +137,9 @@ def run(self):
align = self.options.get('align', '')
show_caption = self.options.get('show_caption', False)
legacy_classes = self.options.get('legacy_class', '')
-
- # TODO get default from config
download = self.options.get('download', conf['download'])
# parse nested content
- # TODO: something is broken here, not parsed as expected
description = nodes.paragraph()
content = nodes.paragraph()
content += [nodes.Text(f"{x}") for x in self.content]
@@ -181,6 +176,7 @@ def run(self):
img['content'] = description.astext()
img['target'] = target
+ img['source'] = "unknown-source"
if title is None:
img['title'] = ''
@@ -196,10 +192,10 @@ def run(self):
img['size'] = (width, height)
img['width'] = width
img['height'] = height
- img['classes'] += classes
img['alt'] = alt
img['align'] = align
img['download'] = download
+ img['classes'] += classes
return [img]
def is_remote(self, uri):
@@ -222,9 +218,8 @@ def is_remote(self, uri):
return False
if '://' in uri:
return True
- raise ValueError('Image URI `{}` has to be local relative or '
- 'absolute path to image, or remote address.'
- .format(uri))
+ raise ValueError(f'Image URI {uri!r} has to be local relative or '
+ f'absolute path to image, or remote address.')
def install_backend_static_files(app, env):
@@ -282,7 +277,6 @@ def download_images(app, env):
dirn = os.path.dirname(dst)
ensuredir(dirn)
if not os.path.isfile(dst):
-
logger.info('%r -> %r (downloading)', src, dst)
with open(dst, 'wb') as f:
# TODO: apply reuqests_kwargs
@@ -333,13 +327,17 @@ def inner_wrapper(writer, node):
return f(writer, node)
return inner_wrapper
signature = f'_{node.__name__}_{output_type}'
- return (backend_method(getattr(backend, 'visit' + signature, getattr(backend, 'visit_' + node.__name__ + '_fallback'))),
- backend_method(getattr(backend, 'depart' + signature, getattr(backend, 'depart_' + node.__name__ + '_fallback'))))
+ return (backend_method(getattr(backend, 'visit' + signature,
+ getattr(backend, 'visit_' + node.__name__ + '_fallback'))),
+ backend_method(getattr(backend, 'depart' + signature,
+ getattr(backend, 'depart_' + node.__name__ + '_fallback'))))
# add new node to the stack
# connect backend processing methods to this node
- app.add_node(image_node, **{output_type: backend_methods(image_node, output_type)
- for output_type in ('html', 'latex', 'man', 'texinfo', 'text', 'epub')})
+ app.add_node(
+ image_node,
+ **{output_type: backend_methods(image_node, output_type)
+ for output_type in ('html', 'latex', 'man', 'texinfo', 'text', 'epub')})
app.add_directive('thumbnail', ImageDirective)
if config['override_image_directive']: