Skip to content
This repository was archived by the owner on Jan 13, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion _unittests/ut_helpgen/test_rst2html_toc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__,
Expand Down Expand Up @@ -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__,
Expand Down Expand Up @@ -89,6 +92,7 @@ def test_rst2html_autoclass(self):
f.write(text)
self.assertIn("* ``:indent:<int>`` to indent the output", text)

@ignore_warnings(PendingDeprecationWarning)
def test_rst2html_toctree(self):
fLOG(
__file__,
Expand Down
15 changes: 8 additions & 7 deletions src/pyquickhelper/helpgen/sphinx_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
34 changes: 16 additions & 18 deletions src/pyquickhelper/sphinxext/blog_post.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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(
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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:: "
Expand All @@ -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
20 changes: 11 additions & 9 deletions src/pyquickhelper/sphinxext/blog_post_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
27 changes: 18 additions & 9 deletions src/pyquickhelper/sphinxext/sphinx_blog_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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):
"""
Expand Down
3 changes: 2 additions & 1 deletion src/pyquickhelper/sphinxext/sphinx_mathdef_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
38 changes: 18 additions & 20 deletions src/pyquickhelper/sphinxext/sphinximages/sphinxtrib/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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,
Expand All @@ -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'])
Expand All @@ -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]
Expand Down Expand Up @@ -181,6 +176,7 @@ def run(self):

img['content'] = description.astext()
img['target'] = target
img['source'] = "unknown-source"

if title is None:
img['title'] = ''
Expand All @@ -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):
Expand All @@ -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):
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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']:
Expand Down