From 1d0fd456e875d743516b56458ab9767511f3e5d3 Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Mon, 13 Nov 2023 12:18:41 -0700 Subject: [PATCH 001/147] Add `tzdata` requirement on Windows --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index e0e118f5..cf3c23c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,6 +40,7 @@ dependencies = [ "unidecode>=1.3.7", "backports-zoneinfo>=0.2.1; python_version < \"3.9\"", "watchfiles>=0.21.0", + "tzdata; sys_platform == 'win32'", ] [project.optional-dependencies] From a2525f7db442e99c4210c07aed9e4a04afb494be Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Mon, 13 Nov 2023 14:42:29 -0700 Subject: [PATCH 002/147] Remove `tzdata` from testing requirements. Should be installed by pelican directly, if needed, based on OS. --- requirements/test.pip | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements/test.pip b/requirements/test.pip index 87869e67..8eb1029f 100644 --- a/requirements/test.pip +++ b/requirements/test.pip @@ -3,7 +3,6 @@ Pygments==2.14.0 pytest pytest-cov pytest-xdist[psutil] -tzdata # Optional Packages Markdown==3.5.1 From f510b4b21f8c7d707eb42d6261d910e327b71bc0 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 15 Nov 2023 17:52:41 +0100 Subject: [PATCH 003/147] Remove reference to non-existent requirements file --- requirements/developer.pip | 1 - 1 file changed, 1 deletion(-) diff --git a/requirements/developer.pip b/requirements/developer.pip index 5c2f5a69..58b2a1dc 100644 --- a/requirements/developer.pip +++ b/requirements/developer.pip @@ -1,3 +1,2 @@ -r test.pip -r docs.pip --r style.pip From 76f7343b6149e300dc014fd9128f6f4214099b91 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 15 Nov 2023 18:08:10 +0100 Subject: [PATCH 004/147] Prepare release --- RELEASE.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 RELEASE.md diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..b61180cb --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,3 @@ +Release type: patch + +* Ensure ``tzdata`` dependency is installed on Windows From 7194cf579571dbbca85faad5bace71627c56152d Mon Sep 17 00:00:00 2001 From: botpub <52496925+botpub@users.noreply.github.com> Date: Wed, 15 Nov 2023 17:16:23 +0000 Subject: [PATCH 005/147] Release Pelican 4.9.1 --- RELEASE.md | 3 --- docs/changelog.rst | 5 +++++ pyproject.toml | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) delete mode 100644 RELEASE.md diff --git a/RELEASE.md b/RELEASE.md deleted file mode 100644 index b61180cb..00000000 --- a/RELEASE.md +++ /dev/null @@ -1,3 +0,0 @@ -Release type: patch - -* Ensure ``tzdata`` dependency is installed on Windows diff --git a/docs/changelog.rst b/docs/changelog.rst index 98da5b20..5ef19b17 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,11 @@ Release history ############### +4.9.1 - 2023-11-15 +================== + +* Ensure ``tzdata`` dependency is installed on Windows + 4.9.0 - 2023-11-12 ================== diff --git a/pyproject.toml b/pyproject.toml index cf3c23c0..c8bbe985 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,7 +2,7 @@ name = "pelican" authors = [{ name = "Justin Mayer", email = "authors@getpelican.com" }] description = "Static site generator supporting Markdown and reStructuredText" -version = "4.9.0" +version = "4.9.1" license = { text = "AGPLv3" } readme = "README.rst" keywords = ["static site generator", "static sites", "ssg"] From d9b2bc3a4ea9f11aea58180aaaea69cc95db1f8c Mon Sep 17 00:00:00 2001 From: Vivek Bharadwaj <67718556+vbharadwaj-bk@users.noreply.github.com> Date: Sun, 19 Nov 2023 01:48:13 -0800 Subject: [PATCH 006/147] Add GH pages action to fix file permissions (#3248) --- .github/workflows/github_pages.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/github_pages.yml b/.github/workflows/github_pages.yml index ccf172b4..7eae170a 100644 --- a/.github/workflows/github_pages.yml +++ b/.github/workflows/github_pages.yml @@ -44,6 +44,11 @@ jobs: --settings "${{ inputs.settings }}" \ --extra-settings SITEURL='"${{ steps.pages.outputs.base_url }}"' \ --output "${{ inputs.output-path }}" + - name: Fix permissions + run: | + chmod -c -R +rX "${{ inputs.output-path }}" | while read line; do + echo "::warning title=Invalid file permissions automatically fixed::$line" + done - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: From 7466b13e0a6c2f0a19ee7b8640adfbd8a7a8ec9e Mon Sep 17 00:00:00 2001 From: Salar Nosrati-Ershad Date: Wed, 22 Nov 2023 22:54:30 +0330 Subject: [PATCH 007/147] fix: keep newline at the end of the file in tools As referenced in Jinja documentation about whitespace control: > To keep single trailing newlines, configure Jinja to > `keep_trailing_newline` I added this to our Jinja environment to keep EOL new line in tools scripts --- RELEASE.md | 3 +++ pelican/tools/pelican_quickstart.py | 1 + 2 files changed, 4 insertions(+) create mode 100644 RELEASE.md diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 00000000..7881aeac --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,3 @@ +Release type: patch + +Keep the newline at the end of the file in generating tools scripts diff --git a/pelican/tools/pelican_quickstart.py b/pelican/tools/pelican_quickstart.py index db00ce70..a4dc98e1 100755 --- a/pelican/tools/pelican_quickstart.py +++ b/pelican/tools/pelican_quickstart.py @@ -44,6 +44,7 @@ _TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "templ _jinja_env = Environment( loader=FileSystemLoader(_TEMPLATES_DIR), trim_blocks=True, + keep_trailing_newline=True, ) From 4ed5c0d5b87e7711e779be6a26c4a1d9ad21aeaa Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Sat, 25 Nov 2023 20:57:40 -0700 Subject: [PATCH 008/147] Log the original calling location, rather than the wrapper function --- pelican/log.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pelican/log.py b/pelican/log.py index 0d2b6a3f..befecbf1 100644 --- a/pelican/log.py +++ b/pelican/log.py @@ -85,13 +85,15 @@ class FatalLogger(LimitLogger): warnings_fatal = False errors_fatal = False + # adding `stacklevel=2` means that the displayed filename and line number + # will match the "original" calling location, rather than the wrapper here def warning(self, *args, **kwargs): - super().warning(*args, **kwargs) + super().warning(*args, stacklevel=2, **kwargs) if FatalLogger.warnings_fatal: raise RuntimeError("Warning encountered") def error(self, *args, **kwargs): - super().error(*args, **kwargs) + super().error(*args, stacklevel=2, **kwargs) if FatalLogger.errors_fatal: raise RuntimeError("Error encountered") From 61eacffa90760c1323aaac15dc6829412e08d2a8 Mon Sep 17 00:00:00 2001 From: Paolo Melchiorre Date: Tue, 28 Nov 2023 21:38:26 +0100 Subject: [PATCH 009/147] Update tox and GitHub pipeline --- .github/workflows/github_pages.yml | 2 +- .github/workflows/main.yml | 18 +++++++++--------- tox.ini | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/github_pages.yml b/.github/workflows/github_pages.yml index 7eae170a..eb9e955f 100644 --- a/.github/workflows/github_pages.yml +++ b/.github/workflows/github_pages.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c29a08c2..cd646522 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ jobs: python: "3.9" steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v4 with: @@ -52,10 +52,10 @@ jobs: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: pdm-project/setup-pdm@v3 with: - python-version: 3.9 + python-version: "3.11" cache: true cache-dependency-path: ./pyproject.toml - name: Install dependencies @@ -70,10 +70,10 @@ jobs: name: Test build runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: pdm-project/setup-pdm@v3 with: - python-version: 3.9 + python-version: "3.11" cache: true cache-dependency-path: ./pyproject.toml - name: Install dependencies @@ -88,11 +88,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.11" cache: "pip" cache-dependency-path: "**/requirements/*" - name: Install tox @@ -117,14 +117,14 @@ jobs: id-token: write steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: token: ${{ secrets.GH_TOKEN }} - name: Set up Python uses: actions/setup-python@v4 with: - python-version: "3.9" + python-version: "3.11" - name: Check release id: check_release diff --git a/tox.ini b/tox.ini index f6f45af1..61e8908a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{3.8,3.9,3.10,3.11.3.12},docs +envlist = py{3.8,3.9,3.10,3.11,3.12},docs [testenv] basepython = @@ -18,7 +18,7 @@ commands = pytest -s --cov=pelican pelican [testenv:docs] -basepython = python3.9 +basepython = python3.11 deps = -rrequirements/docs.pip changedir = docs From 8626d5bd85da049e7ca7828a785d08e02b736aa1 Mon Sep 17 00:00:00 2001 From: Raphael Das Gupta Date: Fri, 22 Dec 2023 15:56:57 +0100 Subject: [PATCH 010/147] docs: update URL to AsciiDoc website https://www.methods.co.nz/asciidoc/ gives a SSL certificate warning and a 404 (page not found) error. https://asciidoc.org is the new official website for the AsciiDoc file format. (It's also what https://en.wikipedia.org/wiki/AsciiDoc links to.) --- docs/content.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content.rst b/docs/content.rst index cacacea9..8a5d9b32 100644 --- a/docs/content.rst +++ b/docs/content.rst @@ -631,7 +631,7 @@ are not included by default in tag, category, and author indexes, nor in the main article feed. This has the effect of creating an "unlisted" post. .. _W3C ISO 8601: https://www.w3.org/TR/NOTE-datetime -.. _AsciiDoc: https://www.methods.co.nz/asciidoc/ +.. _AsciiDoc: https://asciidoc.org .. _Pelican Plugins: https://github.com/pelican-plugins .. _pelican-plugins: https://github.com/getpelican/pelican-plugins .. _Python-Markdown: https://github.com/Python-Markdown/markdown From f0beb81a973f44ed1c8704984bc325b5f4df095c Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Sun, 14 Jan 2024 13:45:51 -0700 Subject: [PATCH 011/147] Better error logging if a plugin refuses to load --- pelican/__init__.py | 3 ++- pelican/log.py | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index a25f5624..40251887 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -80,7 +80,8 @@ class Pelican: plugin.register() self.plugins.append(plugin) except Exception as e: - logger.error("Cannot register plugin `%s`\n%s", name, e) + logger.error("Cannot register plugin `%s`\n%s", name, e, stacklevel=3) + print(e.stacktrace) self.settings["PLUGINS"] = [get_plugin_name(p) for p in self.plugins] diff --git a/pelican/log.py b/pelican/log.py index befecbf1..6a8fcdf1 100644 --- a/pelican/log.py +++ b/pelican/log.py @@ -88,12 +88,16 @@ class FatalLogger(LimitLogger): # adding `stacklevel=2` means that the displayed filename and line number # will match the "original" calling location, rather than the wrapper here def warning(self, *args, **kwargs): - super().warning(*args, stacklevel=2, **kwargs) + if "stacklevel" not in kwargs.keys(): + kwargs["stacklevel"] = 2 + super().warning(*args, **kwargs) if FatalLogger.warnings_fatal: raise RuntimeError("Warning encountered") def error(self, *args, **kwargs): - super().error(*args, stacklevel=2, **kwargs) + if "stacklevel" not in kwargs.keys(): + kwargs["stacklevel"] = 2 + super().error(*args, **kwargs) if FatalLogger.errors_fatal: raise RuntimeError("Error encountered") From f69e2cca6b5d26c8a6b2f3f4444a2c3de2e2d202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Sun, 17 Dec 2023 13:56:33 +0100 Subject: [PATCH 012/147] Add type hints for settings module Types make it easier to understand the code and improve autocompletion in IDEs. --- pelican/settings.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/pelican/settings.py b/pelican/settings.py index 33ec210a..29051ddb 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -8,11 +8,13 @@ import re import sys from os.path import isabs from pathlib import Path +from types import ModuleType +from typing import Any, Dict, Optional from pelican.log import LimitFilter -def load_source(name, path): +def load_source(name: str, path: str) -> ModuleType: spec = importlib.util.spec_from_file_location(name, path) mod = importlib.util.module_from_spec(spec) sys.modules[name] = mod @@ -22,6 +24,8 @@ def load_source(name, path): logger = logging.getLogger(__name__) +Settings = Dict[str, Any] + DEFAULT_THEME = os.path.join( os.path.dirname(os.path.abspath(__file__)), "themes", "notmyidea" ) @@ -177,7 +181,9 @@ DEFAULT_CONFIG = { PYGMENTS_RST_OPTIONS = None -def read_settings(path=None, override=None): +def read_settings( + path: Optional[str] = None, override: Optional[Settings] = None +) -> Settings: settings = override or {} if path: @@ -221,7 +227,7 @@ def read_settings(path=None, override=None): return settings -def get_settings_from_module(module=None): +def get_settings_from_module(module: Optional[ModuleType] = None) -> Settings: """Loads settings from a module, returns a dictionary.""" context = {} @@ -230,7 +236,7 @@ def get_settings_from_module(module=None): return context -def get_settings_from_file(path): +def get_settings_from_file(path: str) -> Settings: """Loads settings from a file path, returning a dict.""" name, ext = os.path.splitext(os.path.basename(path)) @@ -238,7 +244,7 @@ def get_settings_from_file(path): return get_settings_from_module(module) -def get_jinja_environment(settings): +def get_jinja_environment(settings: Settings) -> Settings: """Sets the environment for Jinja""" jinja_env = settings.setdefault( @@ -253,7 +259,7 @@ def get_jinja_environment(settings): return settings -def _printf_s_to_format_field(printf_string, format_field): +def _printf_s_to_format_field(printf_string: str, format_field: str) -> str: """Tries to replace %s with {format_field} in the provided printf_string. Raises ValueError in case of failure. """ @@ -269,7 +275,7 @@ def _printf_s_to_format_field(printf_string, format_field): return result -def handle_deprecated_settings(settings): +def handle_deprecated_settings(settings: Settings) -> Settings: """Converts deprecated settings and issues warnings. Issues an exception if both old and new setting is specified. """ @@ -566,7 +572,7 @@ def handle_deprecated_settings(settings): return settings -def configure_settings(settings): +def configure_settings(settings: Settings) -> Settings: """Provide optimizations, error checking, and warnings for the given settings. Also, specify the log messages to be ignored. From bf4fd679a5322433cc4313a80cac49d4ed6c348f Mon Sep 17 00:00:00 2001 From: boxydog <93335439+boxydog@users.noreply.github.com> Date: Mon, 15 Jan 2024 03:43:19 -0600 Subject: [PATCH 013/147] Document how to import posts from Medium (#3262) --- docs/importer.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/importer.rst b/docs/importer.rst index 997a4632..08092984 100644 --- a/docs/importer.rst +++ b/docs/importer.rst @@ -26,6 +26,12 @@ not be converted (as Pelican also supports Markdown). manually, or use a plugin such as `More Categories`_ that enables multiple categories per article. +.. note:: + + Imported pages may contain links to images that still point to the original site. + So you might want to download those images into your local content and manually + re-link them from the relevant pages of your site. + Dependencies ============ @@ -121,6 +127,15 @@ For WordPress:: $ pelican-import --wpfile -o ~/output ~/posts.xml +For Medium (an example of using an RSS feed): + + $ python -m pip install feedparser + $ pelican-import --feed https://medium.com/feed/@username + +.. note:: + + The RSS feed may only return the most recent posts — not all of them. + Tests ===== From 5e6dba73acfd6a85560d82870d1cda9d184c3cb5 Mon Sep 17 00:00:00 2001 From: Salar Nosrati-Ershad Date: Mon, 15 Jan 2024 13:33:54 +0330 Subject: [PATCH 014/147] Add Github Pages commit message variable (#3250) --- pelican/tools/templates/Makefile.jinja2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pelican/tools/templates/Makefile.jinja2 b/pelican/tools/templates/Makefile.jinja2 index 93ab1aa7..1e9dbff5 100644 --- a/pelican/tools/templates/Makefile.jinja2 +++ b/pelican/tools/templates/Makefile.jinja2 @@ -37,6 +37,7 @@ DROPBOX_DIR={{dropbox_dir}} {% endif %} {% if github %} GITHUB_PAGES_BRANCH={{github_pages_branch}} +GITHUB_PAGES_COMMIT_MESSAGE=Generate Pelican site {% endif %} @@ -161,7 +162,7 @@ cf_upload: publish {% if github %} {% set upload = upload + ["github"] %} github: publish - ghp-import -m "Generate Pelican site" -b $(GITHUB_PAGES_BRANCH) "$(OUTPUTDIR)" + ghp-import -m "$(GITHUB_PAGES_COMMIT_MESSAGE)" -b $(GITHUB_PAGES_BRANCH) "$(OUTPUTDIR)" git push origin $(GITHUB_PAGES_BRANCH) {% endif %} From b1cb6c7326e32afba373113b86d823d46f94a812 Mon Sep 17 00:00:00 2001 From: Salar Nosrati-Ershad Date: Mon, 15 Jan 2024 13:40:12 +0330 Subject: [PATCH 015/147] Use `--no-jekyll` flag when invoking `ghp-import` (#3259) --- pelican/tools/templates/Makefile.jinja2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pelican/tools/templates/Makefile.jinja2 b/pelican/tools/templates/Makefile.jinja2 index 1e9dbff5..67571b47 100644 --- a/pelican/tools/templates/Makefile.jinja2 +++ b/pelican/tools/templates/Makefile.jinja2 @@ -162,7 +162,7 @@ cf_upload: publish {% if github %} {% set upload = upload + ["github"] %} github: publish - ghp-import -m "$(GITHUB_PAGES_COMMIT_MESSAGE)" -b $(GITHUB_PAGES_BRANCH) "$(OUTPUTDIR)" + ghp-import -m "$(GITHUB_PAGES_COMMIT_MESSAGE)" -b $(GITHUB_PAGES_BRANCH) "$(OUTPUTDIR)" --no-jekyll git push origin $(GITHUB_PAGES_BRANCH) {% endif %} From d6a33f1d21a8cbb34b584895554147ad97e97a72 Mon Sep 17 00:00:00 2001 From: boxydog Date: Fri, 1 Dec 2023 11:27:16 -0600 Subject: [PATCH 016/147] Medium post importer (from medium export) --- docs/content.rst | 4 +- docs/importer.rst | 13 +- pelican/tests/content/medium_post_content.txt | 4 + ...2017-04-21_-medium-post--d1bf01d62ba3.html | 72 ++++++++ pelican/tests/test_generators.py | 37 +++- pelican/tests/test_importer.py | 83 +++++++++ pelican/tools/pelican_import.py | 165 +++++++++++++++++- 7 files changed, 357 insertions(+), 21 deletions(-) create mode 100644 pelican/tests/content/medium_post_content.txt create mode 100644 pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html diff --git a/docs/content.rst b/docs/content.rst index cacacea9..46db1140 100644 --- a/docs/content.rst +++ b/docs/content.rst @@ -439,8 +439,8 @@ For **Markdown**, one must rely on an extension. For example, using the `mdx_inc Importing an existing site ========================== -It is possible to import your site from WordPress, Tumblr, Dotclear, and RSS -feeds using a simple script. See :ref:`import`. +It is possible to import your site from several other blogging sites +(like WordPress, Tumblr, ..) using a simple script. See :ref:`import`. Translations ============ diff --git a/docs/importer.rst b/docs/importer.rst index 997a4632..093ef465 100644 --- a/docs/importer.rst +++ b/docs/importer.rst @@ -11,6 +11,7 @@ software to reStructuredText or Markdown. The supported import formats are: - Blogger XML export - Dotclear export +- Medium export - Tumblr API - WordPress XML export - RSS/Atom feed @@ -65,6 +66,7 @@ Optional arguments -h, --help Show this help message and exit --blogger Blogger XML export (default: False) --dotclear Dotclear export (default: False) + --medium Medium export (default: False) --tumblr Tumblr API (default: False) --wpfile WordPress XML export (default: False) --feed Feed to parse (default: False) @@ -80,8 +82,7 @@ Optional arguments (default: False) --filter-author Import only post from the specified author --strip-raw Strip raw HTML code that can't be converted to markup - such as flash embeds or iframes (wordpress import - only) (default: False) + such as flash embeds or iframes (default: False) --wp-custpost Put wordpress custom post types in directories. If used with --dir-cat option directories will be created as "/post_type/category/" (wordpress import only) @@ -113,6 +114,14 @@ For Dotclear:: $ pelican-import --dotclear -o ~/output ~/backup.txt +For Medium:: + + $ pelican-import --medium -o ~/output ~/medium-export/posts/ + +The Medium export is a zip file. Unzip it, and point this tool to the +"posts" subdirectory. For more information on how to export, see +https://help.medium.com/hc/en-us/articles/115004745787-Export-your-account-data. + For Tumblr:: $ pelican-import --tumblr -o ~/output --blogname= diff --git a/pelican/tests/content/medium_post_content.txt b/pelican/tests/content/medium_post_content.txt new file mode 100644 index 00000000..5e21881c --- /dev/null +++ b/pelican/tests/content/medium_post_content.txt @@ -0,0 +1,4 @@ + +

Title header

A paragraph of content.

Paragraph number two.

A list:

  1. One.
  2. Two.
  3. Three.

A link: link text.

Header 2

A block quote:

quote words strong words

after blockquote

A figure caption.

A final note: Cross-Validated has sometimes been helpful.


Next: Next post +

+

By User Name on .

Canonical link

Exported from Medium on December 1, 2023.

diff --git a/pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html b/pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html new file mode 100644 index 00000000..02d272dc --- /dev/null +++ b/pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html @@ -0,0 +1,72 @@ +A title diff --git a/pelican/tests/test_generators.py b/pelican/tests/test_generators.py index af6f5b1a..8c257b55 100644 --- a/pelican/tests/test_generators.py +++ b/pelican/tests/test_generators.py @@ -264,6 +264,7 @@ class TestArticlesGenerator(unittest.TestCase): def test_generate_context(self): articles_expected = [ + ["A title", "published", "medium_posts", "article"], ["Article title", "published", "Default", "article"], [ "Article with markdown and summary metadata multi", @@ -391,13 +392,24 @@ class TestArticlesGenerator(unittest.TestCase): # terms of process order will define the name for that category categories = [cat.name for cat, _ in self.generator.categories] categories_alternatives = ( - sorted(["Default", "TestCategory", "Yeah", "test", "指導書"]), - sorted(["Default", "TestCategory", "yeah", "test", "指導書"]), + sorted( + ["Default", "TestCategory", "medium_posts", "Yeah", "test", "指導書"] + ), + sorted( + ["Default", "TestCategory", "medium_posts", "yeah", "test", "指導書"] + ), ) self.assertIn(sorted(categories), categories_alternatives) # test for slug categories = [cat.slug for cat, _ in self.generator.categories] - categories_expected = ["default", "testcategory", "yeah", "test", "zhi-dao-shu"] + categories_expected = [ + "default", + "testcategory", + "medium_posts", + "yeah", + "test", + "zhi-dao-shu", + ] self.assertEqual(sorted(categories), sorted(categories_expected)) def test_do_not_use_folder_as_category(self): @@ -549,7 +561,8 @@ class TestArticlesGenerator(unittest.TestCase): granularity: {period["period"] for period in periods} for granularity, periods in period_archives.items() } - expected = {"year": {(1970,), (2010,), (2012,), (2014,)}} + self.maxDiff = None + expected = {"year": {(1970,), (2010,), (2012,), (2014,), (2017,)}} self.assertEqual(expected, abbreviated_archives) # Month archives enabled: @@ -570,7 +583,7 @@ class TestArticlesGenerator(unittest.TestCase): for granularity, periods in period_archives.items() } expected = { - "year": {(1970,), (2010,), (2012,), (2014,)}, + "year": {(1970,), (2010,), (2012,), (2014,), (2017,)}, "month": { (1970, "January"), (2010, "December"), @@ -578,6 +591,7 @@ class TestArticlesGenerator(unittest.TestCase): (2012, "November"), (2012, "October"), (2014, "February"), + (2017, "April"), }, } self.assertEqual(expected, abbreviated_archives) @@ -602,7 +616,7 @@ class TestArticlesGenerator(unittest.TestCase): for granularity, periods in period_archives.items() } expected = { - "year": {(1970,), (2010,), (2012,), (2014,)}, + "year": {(1970,), (2010,), (2012,), (2014,), (2017,)}, "month": { (1970, "January"), (2010, "December"), @@ -610,6 +624,7 @@ class TestArticlesGenerator(unittest.TestCase): (2012, "November"), (2012, "October"), (2014, "February"), + (2017, "April"), }, "day": { (1970, "January", 1), @@ -619,6 +634,7 @@ class TestArticlesGenerator(unittest.TestCase): (2012, "October", 30), (2012, "October", 31), (2014, "February", 9), + (2017, "April", 21), }, } self.assertEqual(expected, abbreviated_archives) @@ -836,8 +852,12 @@ class TestArticlesGenerator(unittest.TestCase): categories = sorted([category.name for category, _ in generator.categories]) categories_expected = [ - sorted(["Default", "TestCategory", "yeah", "test", "指導書"]), - sorted(["Default", "TestCategory", "Yeah", "test", "指導書"]), + sorted( + ["Default", "TestCategory", "medium_posts", "yeah", "test", "指導書"] + ), + sorted( + ["Default", "TestCategory", "medium_posts", "Yeah", "test", "指導書"] + ), ] self.assertIn(categories, categories_expected) @@ -864,6 +884,7 @@ class TestArticlesGenerator(unittest.TestCase): generator.generate_context() expected = [ + "A title", "An Article With Code Block To Test Typogrify Ignore", "Article title", "Article with Nonconformant HTML meta tags", diff --git a/pelican/tests/test_importer.py b/pelican/tests/test_importer.py index 05ef5bbd..916c1183 100644 --- a/pelican/tests/test_importer.py +++ b/pelican/tests/test_importer.py @@ -21,6 +21,10 @@ from pelican.tools.pelican_import import ( get_attachments, tumblr2fields, wp2fields, + mediumpost2fields, + mediumposts2fields, + strip_medium_post_content, + medium_slug, ) from pelican.utils import path_to_file_url, slugify @@ -708,3 +712,82 @@ class TestTumblrImporter(TestCaseWithCLocale): posts, posts, ) + + +class TestMediumImporter(TestCaseWithCLocale): + def setUp(self): + super().setUp() + self.test_content_root = "pelican/tests/content" + # The content coming out of parsing is similar, but not the same. + # Beautiful soup rearranges the order of attributes, for example. + # So, we keep a copy of the content for the test. + content_filename = f"{self.test_content_root}/medium_post_content.txt" + with open(content_filename, encoding="utf-8") as the_content_file: + # Many editors and scripts add a final newline, so live with that + # in our test + the_content = the_content_file.read() + assert the_content[-1] == "\n" + the_content = the_content[:-1] + self.post_tuple = ( + "A title", + the_content, + # slug: + "2017-04-21-medium-post", + "2017-04-21 17:11", + "User Name", + None, + (), + "published", + "article", + "html", + ) + + def test_mediumpost2field(self): + """Parse one post""" + post_filename = f"{self.test_content_root}/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html" + val = mediumpost2fields(post_filename) + self.assertEqual(self.post_tuple, val, val) + + def test_mediumposts2field(self): + """Parse all posts in an export directory""" + posts = [ + fields + for fields in mediumposts2fields(f"{self.test_content_root}/medium_posts") + ] + self.assertEqual(1, len(posts)) + self.assertEqual(self.post_tuple, posts[0]) + + def test_strip_content(self): + """Strip out unhelpful tags""" + html_doc = ( + "
This keeps lots of tags, but not " + "the
section
tags
" + ) + soup = BeautifulSoup(html_doc, "html.parser") + self.assertEqual( + "This keeps lots of tags, but not the section tags", + strip_medium_post_content(soup), + ) + + def test_medium_slug(self): + # Remove hex stuff at the end + self.assertEqual( + "2017-04-27_A-long-title", + medium_slug( + "medium-export/posts/2017-04-27_A-long-title--2971442227dd.html" + ), + ) + # Remove "--DRAFT" at the end + self.assertEqual( + "2017-04-27_A-long-title", + medium_slug("medium-export/posts/2017-04-27_A-long-title--DRAFT.html"), + ) + # Remove both (which happens) + self.assertEqual( + "draft_How-to-do", medium_slug("draft_How-to-do--DRAFT--87225c81dddd.html") + ) + # If no hex stuff, leave it alone + self.assertEqual( + "2017-04-27_A-long-title", + medium_slug("medium-export/posts/2017-04-27_A-long-title.html"), + ) diff --git a/pelican/tools/pelican_import.py b/pelican/tools/pelican_import.py index 681a5c45..eb343860 100755 --- a/pelican/tools/pelican_import.py +++ b/pelican/tools/pelican_import.py @@ -15,6 +15,8 @@ from urllib.error import URLError from urllib.parse import quote, urlparse, urlsplit, urlunsplit from urllib.request import urlretrieve +import dateutil.parser + # because logging.setLoggerClass has to be called before logging.getLogger from pelican.log import init from pelican.settings import DEFAULT_CONFIG @@ -114,19 +116,25 @@ def decode_wp_content(content, br=True): return content -def xml_to_soup(xml): - """Opens an xml file""" +def _import_bs4(): + """Import and return bs4, otherwise sys.exit.""" try: - from bs4 import BeautifulSoup + import bs4 except ImportError: error = ( 'Missing dependency "BeautifulSoup4" and "lxml" required to ' "import XML files." ) sys.exit(error) + return bs4 + + +def file_to_soup(xml, features="xml"): + """Reads a file, returns soup.""" + bs4 = _import_bs4() with open(xml, encoding="utf-8") as infile: xmlfile = infile.read() - soup = BeautifulSoup(xmlfile, "xml") + soup = bs4.BeautifulSoup(xmlfile, features) return soup @@ -140,7 +148,7 @@ def get_filename(post_name, post_id): def wp2fields(xml, wp_custpost=False): """Opens a wordpress XML file, and yield Pelican fields""" - soup = xml_to_soup(xml) + soup = file_to_soup(xml) items = soup.rss.channel.findAll("item") for item in items: if item.find("status").string in ["publish", "draft"]: @@ -210,7 +218,7 @@ def wp2fields(xml, wp_custpost=False): def blogger2fields(xml): """Opens a blogger XML file, and yield Pelican fields""" - soup = xml_to_soup(xml) + soup = file_to_soup(xml) entries = soup.feed.findAll("entry") for entry in entries: raw_kind = entry.find( @@ -536,6 +544,133 @@ def tumblr2fields(api_key, blogname): posts = _get_tumblr_posts(api_key, blogname, offset) +def strip_medium_post_content(soup) -> str: + """Strip some tags and attributes from medium post content. + + For example, the 'section' and 'div' tags cause trouble while rendering. + + The problem with these tags is you can get a section divider (--------------) + that is not between two pieces of content. For example: + + Some text. + + .. container:: section-divider + + -------------- + + .. container:: section-content + + More content. + + In this case, pandoc complains: "Unexpected section title or transition." + + Also, the "id" and "name" attributes in tags cause similar problems. They show + up in .rst as extra junk that separates transitions. + """ + # Remove tags + # section and div cause problems + # footer also can cause problems, and has nothing we want to keep + # See https://stackoverflow.com/a/8439761 + invalid_tags = ["section", "div", "footer"] + for tag in invalid_tags: + for match in soup.findAll(tag): + match.replaceWithChildren() + + # Remove attributes + # See https://stackoverflow.com/a/9045719 + invalid_attributes = ["name", "id", "class"] + bs4 = _import_bs4() + for tag in soup.descendants: + if isinstance(tag, bs4.element.Tag): + tag.attrs = { + key: value + for key, value in tag.attrs.items() + if key not in invalid_attributes + } + + # Get the string of all content, keeping other tags + all_content = "".join(str(element) for element in soup.contents) + return all_content + + +def mediumpost2fields(filepath: str) -> tuple: + """Take an HTML post from a medium export, return Pelican fields.""" + + soup = file_to_soup(filepath, "html.parser") + if not soup: + raise ValueError(f"{filepath} could not be parsed by beautifulsoup") + kind = "article" + + content = soup.find("section", class_="e-content") + if not content: + raise ValueError(f"{filepath}: Post has no content") + + title = soup.find("title").string or "" + + raw_date = soup.find("time", class_="dt-published") + date = None + if raw_date: + # This datetime can include timezone, e.g., "2017-04-21T17:11:55.799Z" + # python before 3.11 can't parse the timezone using datetime.fromisoformat + # See also https://docs.python.org/3.10/library/datetime.html#datetime.datetime.fromisoformat + # "This does not support parsing arbitrary ISO 8601 strings" + # So, we use dateutil.parser, which can handle it. + date_object = dateutil.parser.parse(raw_date.attrs["datetime"]) + date = date_object.strftime("%Y-%m-%d %H:%M") + status = "published" + else: + status = "draft" + author = soup.find("a", class_="p-author h-card") + if author: + author = author.string + + # Now that we're done with classes, we can strip the content + content = strip_medium_post_content(content) + + # medium HTML export doesn't have tag or category + # RSS feed has tags, but it doesn't have all the posts. + tags = () + + slug = medium_slug(filepath) + + # TODO: make the fields a python dataclass + return ( + title, + content, + slug, + date, + author, + None, + tags, + status, + kind, + "html", + ) + + +def medium_slug(filepath: str) -> str: + """Make the filepath of a medium exported file into a slug.""" + # slug: filename without extension + slug = os.path.basename(filepath) + slug = os.path.splitext(slug)[0] + # A medium export filename looks like date_-title-...html + # But, RST doesn't like "_-" (see https://github.com/sphinx-doc/sphinx/issues/4350) + # so get rid of it + slug = slug.replace("_-", "-") + # drop the hex string medium puts on the end of the filename, why keep it. + # e.g., "-a8a8a8a8" or "---a9a9a9a9" + # also: drafts don't need "--DRAFT" + slug = re.sub(r"((-)+([0-9a-f]+|DRAFT))+$", "", slug) + return slug + + +def mediumposts2fields(medium_export_dir: str): + """Take HTML posts in a medium export directory, and yield Pelican fields.""" + for file in os.listdir(medium_export_dir): + filename = os.fsdecode(file) + yield mediumpost2fields(os.path.join(medium_export_dir, filename)) + + def feed2fields(file): """Read a feed and yield pelican fields""" import feedparser @@ -711,7 +846,7 @@ def get_attachments(xml): """returns a dictionary of posts that have attachments with a list of the attachment_urls """ - soup = xml_to_soup(xml) + soup = file_to_soup(xml) items = soup.rss.channel.findAll("item") names = {} attachments = [] @@ -837,6 +972,9 @@ def fields2pelican( posts_require_pandoc.append(filename) slug = not disable_slugs and filename or None + assert slug is None or filename == os.path.basename( + filename + ), f"filename is not a basename: {filename}" if wp_attach and attachments: try: @@ -984,6 +1122,9 @@ def main(): parser.add_argument( "--dotclear", action="store_true", dest="dotclear", help="Dotclear export" ) + parser.add_argument( + "--medium", action="store_true", dest="medium", help="Medium export" + ) parser.add_argument( "--tumblr", action="store_true", dest="tumblr", help="Tumblr export" ) @@ -1069,6 +1210,8 @@ def main(): input_type = "blogger" elif args.dotclear: input_type = "dotclear" + elif args.medium: + input_type = "medium" elif args.tumblr: input_type = "tumblr" elif args.wpfile: @@ -1077,8 +1220,8 @@ def main(): input_type = "feed" else: error = ( - "You must provide either --blogger, --dotclear, " - "--tumblr, --wpfile or --feed options" + "You must provide one of --blogger, --dotclear, " + "--medium, --tumblr, --wpfile or --feed options" ) exit(error) @@ -1097,12 +1240,16 @@ def main(): fields = blogger2fields(args.input) elif input_type == "dotclear": fields = dc2fields(args.input) + elif input_type == "medium": + fields = mediumposts2fields(args.input) elif input_type == "tumblr": fields = tumblr2fields(args.input, args.blogname) elif input_type == "wordpress": fields = wp2fields(args.input, args.wp_custpost or False) elif input_type == "feed": fields = feed2fields(args.input) + else: + raise ValueError(f"Unhandled input_type {input_type}") if args.wp_attach: attachments = get_attachments(args.input) From fbe81a971a8f96eae6a13aee4471468f31cbf194 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 17 Jan 2024 09:48:05 +0100 Subject: [PATCH 017/147] Delete RELEASE.md --- RELEASE.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 RELEASE.md diff --git a/RELEASE.md b/RELEASE.md deleted file mode 100644 index 7881aeac..00000000 --- a/RELEASE.md +++ /dev/null @@ -1,3 +0,0 @@ -Release type: patch - -Keep the newline at the end of the file in generating tools scripts From d39dd9b85f0309e4101e74a270fd2ce97f051a84 Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Sun, 21 Jan 2024 22:52:56 -0700 Subject: [PATCH 018/147] Resolve inter-site links in summaries. c.f. https://github.com/getpelican/pelican/issues/3265 c.f. https://github.com/MinchinWeb/minchin.pelican.plugins.summary/issues/5 --- pelican/__init__.py | 7 +++++-- pelican/contents.py | 17 +++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index a25f5624..1a3090f8 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -120,12 +120,15 @@ class Pelican: if hasattr(p, "generate_context"): p.generate_context() + # for plugins that create/edit the summary + logger.debug("Signal all_generators_finalized.send()") + signals.all_generators_finalized.send(generators) + + # update links in the summary, etc for p in generators: if hasattr(p, "refresh_metadata_intersite_links"): p.refresh_metadata_intersite_links() - signals.all_generators_finalized.send(generators) - writer = self._get_writer() for p in generators: diff --git a/pelican/contents.py b/pelican/contents.py index 474e5bbf..27b8bbc3 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -520,12 +520,17 @@ class Content: # _summary is an internal variable that some plugins may be writing to, # so ensure changes to it are picked up - if ( - "summary" in self.settings["FORMATTED_FIELDS"] - and "summary" in self.metadata - ): - self._summary = self._update_content(self._summary, self.get_siteurl()) - self.metadata["summary"] = self._summary + if "summary" in self.settings["FORMATTED_FIELDS"]: + if hasattr(self, "_summary"): + self.metadata["summary"] = self._summary + + if "summary" in self.metadata: + self.metadata["summary"] = self._update_content( + self.metadata["summary"], self.get_siteurl() + ) + + if hasattr(self, "_summary") and "summary" in self.metadata: + self._summary = self.metadata["summary"] class Page(Content): From 2fa5c515b0232ce212a3d83827de88b01deaa598 Mon Sep 17 00:00:00 2001 From: namori <157323136+nam-ori@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:43:07 +0100 Subject: [PATCH 019/147] Feeds - Update generators.py to fix a bug with slugs (#3279) --- pelican/generators.py | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/pelican/generators.py b/pelican/generators.py index 3b5ca9e4..076c8d38 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -384,8 +384,8 @@ class ArticlesGenerator(CachingGenerator): str(self.settings["CATEGORY_FEED_ATOM"]).format(slug=cat.slug), self.settings.get( "CATEGORY_FEED_ATOM_URL", - str(self.settings["CATEGORY_FEED_ATOM"]).format(slug=cat.slug), - ), + str(self.settings["CATEGORY_FEED_ATOM"]), + ).format(slug=cat.slug), feed_title=cat.name, ) @@ -396,8 +396,8 @@ class ArticlesGenerator(CachingGenerator): str(self.settings["CATEGORY_FEED_RSS"]).format(slug=cat.slug), self.settings.get( "CATEGORY_FEED_RSS_URL", - str(self.settings["CATEGORY_FEED_RSS"]).format(slug=cat.slug), - ), + str(self.settings["CATEGORY_FEED_RSS"]), + ).format(slug=cat.slug), feed_title=cat.name, feed_type="rss", ) @@ -410,8 +410,8 @@ class ArticlesGenerator(CachingGenerator): str(self.settings["AUTHOR_FEED_ATOM"]).format(slug=auth.slug), self.settings.get( "AUTHOR_FEED_ATOM_URL", - str(self.settings["AUTHOR_FEED_ATOM"]).format(slug=auth.slug), - ), + str(self.settings["AUTHOR_FEED_ATOM"]), + ).format(slug=auth.slug), feed_title=auth.name, ) @@ -422,8 +422,8 @@ class ArticlesGenerator(CachingGenerator): str(self.settings["AUTHOR_FEED_RSS"]).format(slug=auth.slug), self.settings.get( "AUTHOR_FEED_RSS_URL", - str(self.settings["AUTHOR_FEED_RSS"]).format(slug=auth.slug), - ), + str(self.settings["AUTHOR_FEED_RSS"]), + ).format(slug=auth.slug), feed_title=auth.name, feed_type="rss", ) @@ -437,8 +437,8 @@ class ArticlesGenerator(CachingGenerator): str(self.settings["TAG_FEED_ATOM"]).format(slug=tag.slug), self.settings.get( "TAG_FEED_ATOM_URL", - str(self.settings["TAG_FEED_ATOM"]).format(slug=tag.slug), - ), + str(self.settings["TAG_FEED_ATOM"]), + ).format(slug=tag.slug), feed_title=tag.name, ) @@ -449,8 +449,8 @@ class ArticlesGenerator(CachingGenerator): str(self.settings["TAG_FEED_RSS"]).format(slug=tag.slug), self.settings.get( "TAG_FEED_RSS_URL", - str(self.settings["TAG_FEED_RSS"]).format(slug=tag.slug), - ), + str(self.settings["TAG_FEED_RSS"]), + ).format(slug=tag.slug), feed_title=tag.name, feed_type="rss", ) @@ -471,10 +471,8 @@ class ArticlesGenerator(CachingGenerator): str(self.settings["TRANSLATION_FEED_ATOM"]).format(lang=lang), self.settings.get( "TRANSLATION_FEED_ATOM_URL", - str(self.settings["TRANSLATION_FEED_ATOM"]).format( - lang=lang - ), - ), + str(self.settings["TRANSLATION_FEED_ATOM"]), + ).format(lang=lang), ) if self.settings.get("TRANSLATION_FEED_RSS"): writer.write_feed( From 3a662ace031a20d15f4933c028b3fffd1b588430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Thu, 18 Jan 2024 17:17:29 +0100 Subject: [PATCH 020/147] Add type hints for contents module Types make it easier to understand the code and improve autocompletion in IDEs. --- pelican/contents.py | 95 +++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/pelican/contents.py b/pelican/contents.py index 474e5bbf..82be8f73 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -6,7 +6,8 @@ import os import re from datetime import timezone from html import unescape -from urllib.parse import unquote, urljoin, urlparse, urlunparse +from typing import Any, Dict, Optional, Set, Tuple +from urllib.parse import ParseResult, unquote, urljoin, urlparse, urlunparse try: from zoneinfo import ZoneInfo @@ -15,7 +16,7 @@ except ModuleNotFoundError: from pelican.plugins import signals -from pelican.settings import DEFAULT_CONFIG +from pelican.settings import DEFAULT_CONFIG, Settings from pelican.utils import ( deprecated_attribute, memoized, @@ -44,12 +45,20 @@ class Content: """ + default_template: Optional[str] = None + mandatory_properties: Tuple[str, ...] = () + @deprecated_attribute(old="filename", new="source_path", since=(3, 2, 0)) def filename(): return None def __init__( - self, content, metadata=None, settings=None, source_path=None, context=None + self, + content: str, + metadata: Optional[Dict[str, Any]] = None, + settings: Optional[Settings] = None, + source_path: Optional[str] = None, + context: Optional[Dict[Any, Any]] = None, ): if metadata is None: metadata = {} @@ -156,10 +165,10 @@ class Content: signals.content_object_init.send(self) - def __str__(self): + def __str__(self) -> str: return self.source_path or repr(self) - def _has_valid_mandatory_properties(self): + def _has_valid_mandatory_properties(self) -> bool: """Test mandatory properties are set.""" for prop in self.mandatory_properties: if not hasattr(self, prop): @@ -169,7 +178,7 @@ class Content: return False return True - def _has_valid_save_as(self): + def _has_valid_save_as(self) -> bool: """Return true if save_as doesn't write outside output path, false otherwise.""" try: @@ -190,7 +199,7 @@ class Content: return True - def _has_valid_status(self): + def _has_valid_status(self) -> bool: if hasattr(self, "allowed_statuses"): if self.status not in self.allowed_statuses: logger.error( @@ -204,7 +213,7 @@ class Content: # if undefined we allow all return True - def is_valid(self): + def is_valid(self) -> bool: """Validate Content""" # Use all() to not short circuit and get results of all validations return all( @@ -216,7 +225,7 @@ class Content: ) @property - def url_format(self): + def url_format(self) -> Dict[str, Any]: """Returns the URL, formatted with the proper values""" metadata = copy.copy(self.metadata) path = self.metadata.get("path", self.get_relative_source_path()) @@ -232,19 +241,19 @@ class Content: ) return metadata - def _expand_settings(self, key, klass=None): + def _expand_settings(self, key: str, klass: Optional[str] = None) -> str: if not klass: klass = self.__class__.__name__ fq_key = (f"{klass}_{key}").upper() return str(self.settings[fq_key]).format(**self.url_format) - def get_url_setting(self, key): + def get_url_setting(self, key: str) -> str: if hasattr(self, "override_" + key): return getattr(self, "override_" + key) key = key if self.in_default_lang else "lang_%s" % key return self._expand_settings(key) - def _link_replacer(self, siteurl, m): + def _link_replacer(self, siteurl: str, m: re.Match) -> str: what = m.group("what") value = urlparse(m.group("value")) path = value.path @@ -272,15 +281,15 @@ class Content: # XXX Put this in a different location. if what in {"filename", "static", "attach"}: - def _get_linked_content(key, url): + def _get_linked_content(key: str, url: ParseResult) -> Optional[Content]: nonlocal value - def _find_path(path): + def _find_path(path: str) -> Optional[Content]: if path.startswith("/"): path = path[1:] else: # relative to the source path of this content - path = self.get_relative_source_path( + path = self.get_relative_source_path( # type: ignore os.path.join(self.relative_dir, path) ) return self._context[key].get(path, None) @@ -324,7 +333,7 @@ class Content: linked_content = _get_linked_content(key, value) if linked_content: if what == "attach": - linked_content.attach_to(self) + linked_content.attach_to(self) # type: ignore origin = joiner(siteurl, linked_content.url) origin = origin.replace("\\", "/") # for Windows paths. else: @@ -359,7 +368,7 @@ class Content: return "".join((m.group("markup"), m.group("quote"), origin, m.group("quote"))) - def _get_intrasite_link_regex(self): + def _get_intrasite_link_regex(self) -> re.Pattern: intrasite_link_regex = self.settings["INTRASITE_LINK_REGEX"] regex = r""" (?P<[^\>]+ # match tag with all url-value attributes @@ -370,7 +379,7 @@ class Content: (?P=quote)""".format(intrasite_link_regex) return re.compile(regex, re.X) - def _update_content(self, content, siteurl): + def _update_content(self, content: str, siteurl: str) -> str: """Update the content attribute. Change all the relative paths of the content to relative paths @@ -386,7 +395,7 @@ class Content: hrefs = self._get_intrasite_link_regex() return hrefs.sub(lambda m: self._link_replacer(siteurl, m), content) - def get_static_links(self): + def get_static_links(self) -> Set[str]: static_links = set() hrefs = self._get_intrasite_link_regex() for m in hrefs.finditer(self._content): @@ -402,15 +411,15 @@ class Content: path = self.get_relative_source_path( os.path.join(self.relative_dir, path) ) - path = path.replace("%20", " ") + path = path.replace("%20", " ") # type: ignore static_links.add(path) return static_links - def get_siteurl(self): + def get_siteurl(self) -> str: return self._context.get("localsiteurl", "") @memoized - def get_content(self, siteurl): + def get_content(self, siteurl: str) -> str: if hasattr(self, "_get_content"): content = self._get_content() else: @@ -418,11 +427,11 @@ class Content: return self._update_content(content, siteurl) @property - def content(self): + def content(self) -> str: return self.get_content(self.get_siteurl()) @memoized - def get_summary(self, siteurl): + def get_summary(self, siteurl: str) -> str: """Returns the summary of an article. This is based on the summary metadata if set, otherwise truncate the @@ -441,10 +450,10 @@ class Content: ) @property - def summary(self): + def summary(self) -> str: return self.get_summary(self.get_siteurl()) - def _get_summary(self): + def _get_summary(self) -> str: """deprecated function to access summary""" logger.warning( @@ -454,34 +463,36 @@ class Content: return self.summary @summary.setter - def summary(self, value): + def summary(self, value: str): """Dummy function""" pass @property - def status(self): + def status(self) -> str: return self._status @status.setter - def status(self, value): + def status(self, value: str) -> None: # TODO maybe typecheck self._status = value.lower() @property - def url(self): + def url(self) -> str: return self.get_url_setting("url") @property - def save_as(self): + def save_as(self) -> str: return self.get_url_setting("save_as") - def _get_template(self): + def _get_template(self) -> str: if hasattr(self, "template") and self.template is not None: return self.template else: return self.default_template - def get_relative_source_path(self, source_path=None): + def get_relative_source_path( + self, source_path: Optional[str] = None + ) -> Optional[str]: """Return the relative path (from the content path) to the given source_path. @@ -501,7 +512,7 @@ class Content: ) @property - def relative_dir(self): + def relative_dir(self) -> str: return posixize_path( os.path.dirname( os.path.relpath( @@ -511,7 +522,7 @@ class Content: ) ) - def refresh_metadata_intersite_links(self): + def refresh_metadata_intersite_links(self) -> None: for key in self.settings["FORMATTED_FIELDS"]: if key in self.metadata and key != "summary": value = self._update_content(self.metadata[key], self.get_siteurl()) @@ -534,7 +545,7 @@ class Page(Content): default_status = "published" default_template = "page" - def _expand_settings(self, key): + def _expand_settings(self, key: str) -> str: klass = "draft_page" if self.status == "draft" else None return super()._expand_settings(key, klass) @@ -561,7 +572,7 @@ class Article(Content): if not hasattr(self, "date") and self.status == "draft": self.date = datetime.datetime.max.replace(tzinfo=self.timezone) - def _expand_settings(self, key): + def _expand_settings(self, key: str) -> str: klass = "draft" if self.status == "draft" else "article" return super()._expand_settings(key, klass) @@ -571,7 +582,7 @@ class Static(Content): default_status = "published" default_template = None - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._output_location_referenced = False @@ -588,18 +599,18 @@ class Static(Content): return None @property - def url(self): + def url(self) -> str: # Note when url has been referenced, so we can avoid overriding it. self._output_location_referenced = True return super().url @property - def save_as(self): + def save_as(self) -> str: # Note when save_as has been referenced, so we can avoid overriding it. self._output_location_referenced = True return super().save_as - def attach_to(self, content): + def attach_to(self, content: Content) -> None: """Override our output directory with that of the given content object.""" # Determine our file's new output path relative to the linking @@ -624,7 +635,7 @@ class Static(Content): new_url = path_to_url(new_save_as) - def _log_reason(reason): + def _log_reason(reason: str) -> None: logger.warning( "The {attach} link in %s cannot relocate " "%s because %s. Falling back to " From e4807316ae9338f05701a70d216687a94fb796d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Ricks?= Date: Thu, 18 Jan 2024 09:18:00 +0100 Subject: [PATCH 021/147] Add type hints for utils module Types make it easier to understand the code and improve autocompletion in IDEs. --- pelican/utils.py | 143 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 46 deletions(-) diff --git a/pelican/utils.py b/pelican/utils.py index eda53d3f..5f161667 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import datetime import fnmatch import locale @@ -16,6 +18,21 @@ from html import entities from html.parser import HTMLParser from itertools import groupby from operator import attrgetter +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Collection, + Dict, + Generator, + Iterable, + List, + Optional, + Sequence, + Tuple, + Type, + Union, +) import dateutil.parser @@ -27,11 +44,15 @@ from markupsafe import Markup import watchfiles +if TYPE_CHECKING: + from pelican.contents import Content + from pelican.readers import Readers + from pelican.settings import Settings logger = logging.getLogger(__name__) -def sanitised_join(base_directory, *parts): +def sanitised_join(base_directory: str, *parts: str) -> str: joined = posixize_path(os.path.abspath(os.path.join(base_directory, *parts))) base = posixize_path(os.path.abspath(base_directory)) if not joined.startswith(base): @@ -40,7 +61,7 @@ def sanitised_join(base_directory, *parts): return joined -def strftime(date, date_format): +def strftime(date: datetime.datetime, date_format: str) -> str: """ Enhanced replacement for built-in strftime with zero stripping @@ -109,10 +130,10 @@ class DateFormatter: defined in LOCALE setting """ - def __init__(self): + def __init__(self) -> None: self.locale = locale.setlocale(locale.LC_TIME) - def __call__(self, date, date_format): + def __call__(self, date: datetime.datetime, date_format: str) -> str: # on OSX, encoding from LC_CTYPE determines the unicode output in PY3 # make sure it's same as LC_TIME with temporary_locale(self.locale, locale.LC_TIME), temporary_locale( @@ -131,11 +152,11 @@ class memoized: """ - def __init__(self, func): + def __init__(self, func: Callable) -> None: self.func = func - self.cache = {} + self.cache: Dict[Any, Any] = {} - def __call__(self, *args): + def __call__(self, *args) -> Any: if not isinstance(args, Hashable): # uncacheable. a list, for instance. # better to not cache than blow up. @@ -147,17 +168,23 @@ class memoized: self.cache[args] = value return value - def __repr__(self): + def __repr__(self) -> Optional[str]: return self.func.__doc__ - def __get__(self, obj, objtype): + def __get__(self, obj: Any, objtype): """Support instance methods.""" fn = partial(self.__call__, obj) fn.cache = self.cache return fn -def deprecated_attribute(old, new, since=None, remove=None, doc=None): +def deprecated_attribute( + old: str, + new: str, + since: Tuple[int, ...], + remove: Optional[Tuple[int, ...]] = None, + doc: Optional[str] = None, +): """Attribute deprecation decorator for gentle upgrades For example: @@ -198,7 +225,7 @@ def deprecated_attribute(old, new, since=None, remove=None, doc=None): return decorator -def get_date(string): +def get_date(string: str) -> datetime.datetime: """Return a datetime object from a string. If no format matches the given date, raise a ValueError. @@ -212,7 +239,9 @@ def get_date(string): @contextmanager -def pelican_open(filename, mode="r", strip_crs=(sys.platform == "win32")): +def pelican_open( + filename: str, mode: str = "r", strip_crs: bool = (sys.platform == "win32") +) -> Generator[str, None, None]: """Open a file and return its content""" # utf-8-sig will clear any BOM if present @@ -221,7 +250,12 @@ def pelican_open(filename, mode="r", strip_crs=(sys.platform == "win32")): yield content -def slugify(value, regex_subs=(), preserve_case=False, use_unicode=False): +def slugify( + value: str, + regex_subs: Iterable[Tuple[str, str]] = (), + preserve_case: bool = False, + use_unicode: bool = False, +) -> str: """ Normalizes string, converts to lowercase, removes non-alpha characters, and converts spaces to hyphens. @@ -233,9 +267,10 @@ def slugify(value, regex_subs=(), preserve_case=False, use_unicode=False): """ import unicodedata + import unidecode - def normalize_unicode(text): + def normalize_unicode(text: str) -> str: # normalize text by compatibility composition # see: https://en.wikipedia.org/wiki/Unicode_equivalence return unicodedata.normalize("NFKC", text) @@ -262,7 +297,9 @@ def slugify(value, regex_subs=(), preserve_case=False, use_unicode=False): return value.strip() -def copy(source, destination, ignores=None): +def copy( + source: str, destination: str, ignores: Optional[Iterable[str]] = None +) -> None: """Recursively copy source into destination. If source is a file, destination has to be a file as well. @@ -334,7 +371,7 @@ def copy(source, destination, ignores=None): ) -def copy_file(source, destination): +def copy_file(source: str, destination: str) -> None: """Copy a file""" try: shutil.copyfile(source, destination) @@ -344,7 +381,7 @@ def copy_file(source, destination): ) -def clean_output_dir(path, retention): +def clean_output_dir(path: str, retention: Iterable[str]) -> None: """Remove all files from output directory except those in retention list""" if not os.path.exists(path): @@ -381,24 +418,24 @@ def clean_output_dir(path, retention): logger.error("Unable to delete %s, file type unknown", file) -def get_relative_path(path): +def get_relative_path(path: str) -> str: """Return the relative path from the given path to the root path.""" components = split_all(path) - if len(components) <= 1: + if components is None or len(components) <= 1: return os.curdir else: parents = [os.pardir] * (len(components) - 1) return os.path.join(*parents) -def path_to_url(path): +def path_to_url(path: str) -> str: """Return the URL corresponding to a given path.""" if path is not None: path = posixize_path(path) return path -def posixize_path(rel_path): +def posixize_path(rel_path: str) -> str: """Use '/' as path separator, so that source references, like '{static}/foo/bar.jpg' or 'extras/favicon.ico', will work on Windows as well as on Mac and Linux.""" @@ -427,20 +464,20 @@ class _HTMLWordTruncator(HTMLParser): _singlets = ("br", "col", "link", "base", "img", "param", "area", "hr", "input") class TruncationCompleted(Exception): - def __init__(self, truncate_at): + def __init__(self, truncate_at: int) -> None: super().__init__(truncate_at) self.truncate_at = truncate_at - def __init__(self, max_words): + def __init__(self, max_words: int) -> None: super().__init__(convert_charrefs=False) self.max_words = max_words self.words_found = 0 self.open_tags = [] self.last_word_end = None - self.truncate_at = None + self.truncate_at: Optional[int] = None - def feed(self, *args, **kwargs): + def feed(self, *args, **kwargs) -> None: try: super().feed(*args, **kwargs) except self.TruncationCompleted as exc: @@ -448,29 +485,29 @@ class _HTMLWordTruncator(HTMLParser): else: self.truncate_at = None - def getoffset(self): + def getoffset(self) -> int: line_start = 0 lineno, line_offset = self.getpos() for i in range(lineno - 1): line_start = self.rawdata.index("\n", line_start) + 1 return line_start + line_offset - def add_word(self, word_end): + def add_word(self, word_end: int) -> None: self.words_found += 1 self.last_word_end = None if self.words_found == self.max_words: raise self.TruncationCompleted(word_end) - def add_last_word(self): + def add_last_word(self) -> None: if self.last_word_end is not None: self.add_word(self.last_word_end) - def handle_starttag(self, tag, attrs): + def handle_starttag(self, tag: str, attrs: Any) -> None: self.add_last_word() if tag not in self._singlets: self.open_tags.insert(0, tag) - def handle_endtag(self, tag): + def handle_endtag(self, tag: str) -> None: self.add_last_word() try: i = self.open_tags.index(tag) @@ -481,7 +518,7 @@ class _HTMLWordTruncator(HTMLParser): # all unclosed intervening start tags with omitted end tags del self.open_tags[: i + 1] - def handle_data(self, data): + def handle_data(self, data: str) -> None: word_end = 0 offset = self.getoffset() @@ -499,7 +536,7 @@ class _HTMLWordTruncator(HTMLParser): if word_end < len(data): self.add_last_word() - def _handle_ref(self, name, char): + def _handle_ref(self, name: str, char: str) -> None: """ Called by handle_entityref() or handle_charref() when a ref like `—`, `—`, or `—` is found. @@ -543,7 +580,7 @@ class _HTMLWordTruncator(HTMLParser): else: self.add_last_word() - def handle_entityref(self, name): + def handle_entityref(self, name: str) -> None: """ Called when an entity ref like '—' is found @@ -556,7 +593,7 @@ class _HTMLWordTruncator(HTMLParser): char = "" self._handle_ref(name, char) - def handle_charref(self, name): + def handle_charref(self, name: str) -> None: """ Called when a char ref like '—' or '—' is found @@ -574,7 +611,7 @@ class _HTMLWordTruncator(HTMLParser): self._handle_ref("#" + name, char) -def truncate_html_words(s, num, end_text="…"): +def truncate_html_words(s: str, num: int, end_text: str = "…") -> str: """Truncates HTML to a certain number of words. (not counting tags and comments). Closes opened tags if they were correctly @@ -600,7 +637,10 @@ def truncate_html_words(s, num, end_text="…"): return out -def process_translations(content_list, translation_id=None): +def process_translations( + content_list: List[Content], + translation_id: Optional[Union[str, Collection[str]]] = None, +) -> Tuple[List[Content], List[Content]]: """Finds translations and returns them. For each content_list item, populates the 'translations' attribute, and @@ -658,7 +698,7 @@ def process_translations(content_list, translation_id=None): return index, translations -def get_original_items(items, with_str): +def get_original_items(items: List[Content], with_str: str) -> List[Content]: def _warn_source_paths(msg, items, *extra): args = [len(items)] args.extend(extra) @@ -698,7 +738,10 @@ def get_original_items(items, with_str): return original_items -def order_content(content_list, order_by="slug"): +def order_content( + content_list: List[Content], + order_by: Union[str, Callable[[Content], Any], None] = "slug", +) -> List[Content]: """Sorts content. order_by can be a string of an attribute or sorting function. If order_by @@ -758,7 +801,11 @@ def order_content(content_list, order_by="slug"): return content_list -def wait_for_changes(settings_file, reader_class, settings): +def wait_for_changes( + settings_file: str, + reader_class: Type["Readers"], + settings: "Settings", +): content_path = settings.get("PATH", "") theme_path = settings.get("THEME", "") ignore_files = { @@ -788,13 +835,15 @@ def wait_for_changes(settings_file, reader_class, settings): return next( watchfiles.watch( *watching_paths, - watch_filter=watchfiles.DefaultFilter(ignore_entity_patterns=ignore_files), + watch_filter=watchfiles.DefaultFilter(ignore_entity_patterns=ignore_files), # type: ignore rust_timeout=0, ) ) -def set_date_tzinfo(d, tz_name=None): +def set_date_tzinfo( + d: datetime.datetime, tz_name: Optional[str] = None +) -> datetime.datetime: """Set the timezone for dates that don't have tzinfo""" if tz_name and not d.tzinfo: timezone = ZoneInfo(tz_name) @@ -805,11 +854,11 @@ def set_date_tzinfo(d, tz_name=None): return d -def mkdir_p(path): +def mkdir_p(path: str) -> None: os.makedirs(path, exist_ok=True) -def split_all(path): +def split_all(path: Union[str, pathlib.Path, None]) -> Optional[Sequence[str]]: """Split a path into a list of components While os.path.split() splits a single component off the back of @@ -840,12 +889,12 @@ def split_all(path): ) -def path_to_file_url(path): +def path_to_file_url(path: str) -> str: """Convert file-system path to file:// URL""" return urllib.parse.urljoin("file://", urllib.request.pathname2url(path)) -def maybe_pluralize(count, singular, plural): +def maybe_pluralize(count: int, singular: str, plural: str) -> str: """ Returns a formatted string containing count and plural if count is not 1 Returns count and singular if count is 1 @@ -862,7 +911,9 @@ def maybe_pluralize(count, singular, plural): @contextmanager -def temporary_locale(temp_locale=None, lc_category=locale.LC_ALL): +def temporary_locale( + temp_locale: Optional[str] = None, lc_category: int = locale.LC_ALL +) -> Generator[None, None, None]: """ Enable code to run in a context with a temporary locale Resets the locale back when exiting context. From c36ab075269771834b5e05e4d1586d050743d457 Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Fri, 26 Jan 2024 16:31:22 -0700 Subject: [PATCH 022/147] write back to `._summary` --- pelican/contents.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pelican/contents.py b/pelican/contents.py index 27b8bbc3..e0629e2a 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -519,7 +519,7 @@ class Content: setattr(self, key.lower(), value) # _summary is an internal variable that some plugins may be writing to, - # so ensure changes to it are picked up + # so ensure changes to it are picked up, and write summary back to it if "summary" in self.settings["FORMATTED_FIELDS"]: if hasattr(self, "_summary"): self.metadata["summary"] = self._summary @@ -528,8 +528,6 @@ class Content: self.metadata["summary"] = self._update_content( self.metadata["summary"], self.get_siteurl() ) - - if hasattr(self, "_summary") and "summary" in self.metadata: self._summary = self.metadata["summary"] From f1f2ceccc757d9743dde39f626eccf05e3e9a5b0 Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Sat, 27 Jan 2024 10:47:54 -0700 Subject: [PATCH 023/147] Warning/error logging: be explicit in how the `stacklevel` variable is handled --- pelican/log.py | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/pelican/log.py b/pelican/log.py index 6a8fcdf1..ef49d280 100644 --- a/pelican/log.py +++ b/pelican/log.py @@ -85,19 +85,39 @@ class FatalLogger(LimitLogger): warnings_fatal = False errors_fatal = False - # adding `stacklevel=2` means that the displayed filename and line number - # will match the "original" calling location, rather than the wrapper here - def warning(self, *args, **kwargs): - if "stacklevel" not in kwargs.keys(): - kwargs["stacklevel"] = 2 - super().warning(*args, **kwargs) + def warning(self, *args, stacklevel=1, **kwargs): + """ + Displays a logging warning. + + Wrapping it here allows Pelican to filter warnings, and conditionally + make warnings fatal. + + Args: + stacklevel (int): the stacklevel that would be used to display the + calling location, except for this function. Adjusting the + stacklevel allows you to see the "true" calling location of the + warning, rather than this wrapper location. + """ + stacklevel += 1 + super().warning(*args, stacklevel=stacklevel, **kwargs) if FatalLogger.warnings_fatal: raise RuntimeError("Warning encountered") - def error(self, *args, **kwargs): - if "stacklevel" not in kwargs.keys(): - kwargs["stacklevel"] = 2 - super().error(*args, **kwargs) + def error(self, *args, stacklevel=1, **kwargs): + """ + Displays a logging error. + + Wrapping it here allows Pelican to filter errors, and conditionally + make errors non-fatal. + + Args: + stacklevel (int): the stacklevel that would be used to display the + calling location, except for this function. Adjusting the + stacklevel allows you to see the "true" calling location of the + error, rather than this wrapper location. + """ + stacklevel += 1 + super().error(*args, stacklevel=stacklevel, **kwargs) if FatalLogger.errors_fatal: raise RuntimeError("Error encountered") From 1f14606f8339385c5176ba05adca4664a3ad8868 Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Sat, 27 Jan 2024 10:51:35 -0700 Subject: [PATCH 024/147] On failing to load a plugin, show the stacktrace is pelican is run in debug mode --- pelican/__init__.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index 40251887..68f3e553 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -80,8 +80,14 @@ class Pelican: plugin.register() self.plugins.append(plugin) except Exception as e: - logger.error("Cannot register plugin `%s`\n%s", name, e, stacklevel=3) - print(e.stacktrace) + logger.error( + "Cannot register plugin `%s`\n%s", + name, + e, + stacklevel=2, + ) + if self.settings.get("DEBUG", False): + console.print_exception() self.settings["PLUGINS"] = [get_plugin_name(p) for p in self.plugins] From 7c7c9355b6c27122dbff6446cd366017f81eb0f2 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Tue, 12 Mar 2024 11:57:46 +0100 Subject: [PATCH 025/147] Pin Ruff to major semantic version 0.1.x Upgrading to 0.3.0+ requires code style changes to the code base. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c8bbe985..eb1884a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,7 +95,7 @@ dev = [ "pytest-xdist>=3.4.0", "tox>=4.11.3", "invoke>=2.2.0", - "ruff>=0.1.5", + "ruff>=0.1.5,<0.2.0", "tomli>=2.0.1; python_version < \"3.11\"", ] From 74541381848f1d65ec64463469b5980ba0646617 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Tue, 12 Mar 2024 12:05:09 +0100 Subject: [PATCH 026/147] Update `setup-python` & `setup-pdm` GitHub Actions --- .github/workflows/main.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index cd646522..8cd63cc7 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} cache: "pip" @@ -53,7 +53,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: pdm-project/setup-pdm@v3 + - uses: pdm-project/setup-pdm@v4 with: python-version: "3.11" cache: true @@ -71,7 +71,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: pdm-project/setup-pdm@v3 + - uses: pdm-project/setup-pdm@v4 with: python-version: "3.11" cache: true @@ -90,7 +90,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.11" cache: "pip" @@ -122,7 +122,7 @@ jobs: token: ${{ secrets.GH_TOKEN }} - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: "3.11" From fabc40927750f52f11f27695e89ff76c0863a79f Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Tue, 12 Mar 2024 12:18:11 +0100 Subject: [PATCH 027/147] Update more GitHub Actions to resolve warnings --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8cd63cc7..4c0127df 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -64,7 +64,7 @@ jobs: - name: Run linters run: pdm lint --diff - name: Run pre-commit checks on all files - uses: pre-commit/action@v3.0.0 + uses: pre-commit/action@v3.0.1 build: name: Test build @@ -100,7 +100,7 @@ jobs: - name: Check run: tox -e docs - name: cache the docs for inspection - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: docs path: docs/_build/html/ From b87308cfaaa269c44784cda69855ecaf298f9f5e Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 27 Mar 2024 08:25:48 +0100 Subject: [PATCH 028/147] Update Ruff dependency version --- .pre-commit-config.yaml | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 333bc3c0..d6cfac07 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: - id: forbid-new-submodules - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.5 + rev: v0.1.15 hooks: - id: ruff - id: ruff-format diff --git a/pyproject.toml b/pyproject.toml index eb1884a9..2f7d677c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -95,7 +95,7 @@ dev = [ "pytest-xdist>=3.4.0", "tox>=4.11.3", "invoke>=2.2.0", - "ruff>=0.1.5,<0.2.0", + "ruff>=0.1.15,<0.2.0", "tomli>=2.0.1; python_version < \"3.11\"", ] From 94bcd41f27d7f38a9dbd0847c6166e91a66d2090 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 27 Mar 2024 08:26:55 +0100 Subject: [PATCH 029/147] Ignore Sphinx 7.2.x package install warnings Sphinx 7.2+ requires Python 3.9+, which results in annoying warnings since we still support Python 3.8.x. --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 2f7d677c..3ca06df4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,6 +69,7 @@ changelog-header = "###############" version-header = "=" [tool.pdm] +ignore_package_warnings = ["sphinx"] [tool.pdm.scripts] docbuild = "invoke docbuild" From 666b962eb67369a2de45362b08c74524b5d49c57 Mon Sep 17 00:00:00 2001 From: Deniz Turgut Date: Fri, 19 Apr 2024 08:51:07 -0700 Subject: [PATCH 030/147] workaround Turkish locale issue --- pelican/utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pelican/utils.py b/pelican/utils.py index 5f161667..86698aee 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -132,6 +132,10 @@ class DateFormatter: def __init__(self) -> None: self.locale = locale.setlocale(locale.LC_TIME) + # python has issue with Turkish_Türkiye.1254 locale, replace it to + # something accepted: Turkish + if self.locale == "Turkish_Türkiye.1254": + self.locale = "Turkish" def __call__(self, date: datetime.datetime, date_format: str) -> str: # on OSX, encoding from LC_CTYPE determines the unicode output in PY3 @@ -922,6 +926,10 @@ def temporary_locale( class to use the C locale. """ orig_locale = locale.setlocale(lc_category) + # python has issue with Turkish_Türkiye.1254 locale, replace it to + # something accepted: Turkish + if orig_locale == "Turkish_Türkiye.1254": + orig_locale = "Turkish" if temp_locale: locale.setlocale(lc_category, temp_locale) yield From 0b5934a1fa56bb7ca9b0b0011e35f9043afc6ce9 Mon Sep 17 00:00:00 2001 From: GiovanH Date: Fri, 19 Apr 2024 13:54:27 -0500 Subject: [PATCH 031/147] Feature: Add setting to append `ref` parameter to links in feeds (#3249) --- docs/settings.rst | 5 +++++ pelican/settings.py | 1 + pelican/writers.py | 3 +++ 3 files changed, 9 insertions(+) diff --git a/docs/settings.rst b/docs/settings.rst index e9edffde..4ae608c6 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -1008,6 +1008,11 @@ the ``TAG_FEED_ATOM`` and ``TAG_FEED_RSS`` settings: to ``False``, the full content will be included instead. This setting doesn't affect Atom feeds, only RSS ones. +.. data:: FEED_APPEND_REF = False + + If set to ``True``, ``?ref=feed`` will be appended to links in generated + feeds for the purpose of referrer tracking. + If you don't want to generate some or any of these feeds, set the above variables to ``None``. diff --git a/pelican/settings.py b/pelican/settings.py index 29051ddb..47457ec1 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -52,6 +52,7 @@ DEFAULT_CONFIG = { "TRANSLATION_FEED_ATOM": "feeds/all-{lang}.atom.xml", "FEED_MAX_ITEMS": 100, "RSS_FEED_SUMMARY_ONLY": True, + "FEED_APPEND_REF": False, "SITEURL": "", "SITENAME": "A Pelican Blog", "DISPLAY_PAGES_ON_MENU": True, diff --git a/pelican/writers.py b/pelican/writers.py index d405fc88..1c41b4ee 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -53,6 +53,9 @@ class Writer: title = Markup(item.title).striptags() link = self.urljoiner(self.site_url, item.url) + if self.settings["FEED_APPEND_REF"]: + link = link + "?ref=feed" + if isinstance(feed, Rss201rev2Feed): # RSS feeds use a single tag called 'description' for both the full # content and the summary From e4d7f0a9d95cf2816e4c0b2b59849f49766e05dc Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 29 May 2024 07:28:22 +0200 Subject: [PATCH 032/147] Docs: GitHub Pages workflow not officially supported --- .github/workflows/github_pages.yml | 1 + docs/tips.rst | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/github_pages.yml b/.github/workflows/github_pages.yml index eb9e955f..f4a01b92 100644 --- a/.github/workflows/github_pages.yml +++ b/.github/workflows/github_pages.yml @@ -1,3 +1,4 @@ +# Workflow for publishing to GitHub Pages. **NO OFFICIAL SUPPORT PROVIDED.** name: Deploy to GitHub Pages on: workflow_call: diff --git a/docs/tips.rst b/docs/tips.rst index 904e5ee7..3344900d 100644 --- a/docs/tips.rst +++ b/docs/tips.rst @@ -126,8 +126,9 @@ branch of your GitHub repository:: Publishing to GitHub Pages Using a Custom GitHub Actions Workflow ----------------------------------------------------------------- -Pelican comes with a `custom workflow `_ -for publishing a Pelican site. To use it: +Pelican-powered sites can be published to GitHub Pages via a `custom workflow +`_. +**No official support is provided** for this community-submitted workflow. To use it: 1. Enable GitHub Pages in your repo: go to **Settings → Pages** and choose **GitHub Actions** for the **Source** setting. From 1001dcb6096d315bc460571c5f43ea88a33e1e18 Mon Sep 17 00:00:00 2001 From: boxydog Date: Wed, 29 May 2024 16:36:20 -0500 Subject: [PATCH 033/147] Fix test_deprecated_attribute failures in github tests --- pelican/tests/test_utils.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index 22dd8e38..bd3f0d00 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -23,9 +23,17 @@ from pelican.tests.support import ( from pelican.writers import Writer -class TestUtils(LoggedTestCase): +class ClassDeprAttr: _new_attribute = "new_value" + @utils.deprecated_attribute( + old="_old_attribute", new="_new_attribute", since=(3, 1, 0), remove=(4, 1, 3) + ) + def _old_attribute(): + return None + + +class TestUtils(LoggedTestCase): def setUp(self): super().setUp() self.temp_output = mkdtemp(prefix="pelicantests.") @@ -34,15 +42,10 @@ class TestUtils(LoggedTestCase): super().tearDown() shutil.rmtree(self.temp_output) - @utils.deprecated_attribute( - old="_old_attribute", new="_new_attribute", since=(3, 1, 0), remove=(4, 1, 3) - ) - def _old_attribute(): - return None - def test_deprecated_attribute(self): - value = self._old_attribute - self.assertEqual(value, self._new_attribute) + test_class = ClassDeprAttr() + value = test_class._old_attribute + self.assertEqual(value, test_class._new_attribute) self.assertLogCountEqual( count=1, msg=( From 4f46fedd731664547fc2b5e61f1d8d2c157d2dd3 Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 09:02:23 -0500 Subject: [PATCH 034/147] More Ruff checks, and make it fix --- .pre-commit-config.yaml | 2 +- pyproject.toml | 99 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d6cfac07..0e65a965 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: rev: v0.1.15 hooks: - id: ruff + args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - args: ["--check"] exclude: ^pelican/tests/output/ diff --git a/pyproject.toml b/pyproject.toml index 3ca06df4..39694ffc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -111,3 +111,102 @@ source-includes = [ [build-system] requires = ["pdm-backend"] build-backend = "pdm.backend" + + +[tool.ruff.lint] +# see https://docs.astral.sh/ruff/configuration/#using-pyprojecttoml +# "F" contains autoflake, see https://github.com/astral-sh/ruff/issues/1647 +# add more rules +select = [ + # default Ruff checkers as of ruff 0.1.3: E4, E7, E9, F + "E4", + "E7", + "E9", + "F", # pyflakes + + # the rest in alphabetical order: + # TODO: "A", # flake8-builtins + # TODO: "ARG", # flake8-unused-arguments + "B", # flake8-bugbear + # TODO: "BLE", # flake8-blind-except + # TODO: Do I want "COM", # flake8-commas + "C4", # flake8-comprehensions + # TODO: "DJ", # flake8-django + # TODO: "DTZ", # flake8-datetimez + # TODO: "EM", # flake8-errmsg + "EXE", # flake8-executable + # TODO: "FURB", # refurb + # TODO: "FBT", # flake8-boolean-trap + # TODO: "G", # flake8-logging-format + "I", # isort + "ICN", # flake8-import-conventions + "INP", # flake8-no-pep420 + # TODO: "INT", # flake8-gettext + "ISC", # flake8-implicit-str-concat + # TODO: "LOG", # flake8-logging + "PERF", # perflint + "PIE", # flake8-pie + "PL", # pylint + "PYI", # flake8-pyi + # TODO: "RET", # flake8-return + "RSE", # flake8-raise + "RUF", + # TODO: "SIM", # flake8-simplify + "SLF", # flake8-self + "SLOT", # flake8-slots + "TID", # flake8-tidy-imports + "UP", # pyupgrade + "Q", # flake8-quotes + "TCH", # flake8-type-checking + "T10", # flake8-debugger + "T20", # flake8-print + # TODO: "S", # flake8-bandit + "YTT", # flake8-2020 + # TODO: add more flake8 rules + ] + +ignore = [ + # suppression in order of # of violations in Dec 2023: + "B007", # unused-loop-control-variable + "T201", # print + "PLW2901", # redefined-loop-name + "SLF001", # private-member-access + "RUF001", # ambiguous-unicode-character-string + "PLR2004", # magic-value-comparison + "PLR0912", # too-many-branches + "PLR0913", # too-many-arguments + "RUF005", # collection-literal-concatenation + "RUF012", # mutable-class-default + "PLR0915", # too-many-statements + "INP001", # implicit-namespace-package + "RUF015", # unnecessary-iterable-allocation-for-first-element + "PLR1722", # sys-exit-alias + "ISC001", # single-line-implicit-string-concatenation + "C408", # unnecessary-collection-call + "B904", # raise-without-from-inside-except + "UP007", # use `|` operator for union type annotations (PEP 604) + "UP031", # printf-string-formatting + "PLR5501", # collapsible-else-if + "PERF203", # try-except-in-loop + "B006", # mutable-argument-default + "PLR1714", # repeated-equality-comparison + "PERF401", # manual-list-comprehension + # TODO: these only have one violation each in Dec 2023: + "SLOT000", # no-slots-in-str-subclass + "PYI024", # collections-named-tuple + "PLW0603", # global-statement + "PIE800", # unnecessary-spread + "ISC003", # explicit-string-concatenation + "EXE002", # shebang-missing-executable-file + "C401", # unnecessary-generator-set + "C416", # unnecessary `list` comprehension + "B028", # no-explicit-stacklevel + "B008", # function-call-in-default-argument +] + +[tool.ruff.lint.extend-per-file-ignores] + +"pelican/__init__.py" = [ + # allow imports after a call to a function, see the file + "E402" +] From 6d8597addb17d5fa3027ead91427939e8e4e89ec Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 09:05:36 -0500 Subject: [PATCH 035/147] The ruff and ruff-format fixes --- pelican/__init__.py | 8 ++--- pelican/__main__.py | 1 - pelican/contents.py | 13 ++++--- pelican/plugins/_utils.py | 1 - pelican/plugins/signals.py | 2 +- pelican/readers.py | 4 +-- pelican/rstdirectives.py | 1 - pelican/settings.py | 6 ++-- pelican/tests/build_test/test_build_files.py | 2 +- pelican/tests/support.py | 4 +-- pelican/tests/test_cache.py | 1 - pelican/tests/test_contents.py | 2 -- pelican/tests/test_generators.py | 2 +- pelican/tests/test_importer.py | 14 ++++---- pelican/tests/test_paginator.py | 1 - pelican/tests/test_plugins.py | 2 +- pelican/tests/test_readers.py | 1 - pelican/tests/test_settings.py | 1 - pelican/tools/pelican_import.py | 1 - pelican/tools/pelican_quickstart.py | 6 ++-- pelican/tools/pelican_themes.py | 14 ++------ pelican/urlwrappers.py | 2 +- pelican/utils.py | 37 +++++++++----------- pelican/writers.py | 1 - 24 files changed, 48 insertions(+), 79 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index 2fd69f1b..aef4b124 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -19,10 +19,10 @@ __path__ = extend_path(__path__, __name__) # pelican.log has to be the first pelican module to be loaded # because logging.setLoggerClass has to be called before logging.getLogger -from pelican.log import console +from pelican.log import console # noqa: I001 from pelican.log import init as init_logging from pelican.generators import ( - ArticlesGenerator, # noqa: I100 + ArticlesGenerator, PagesGenerator, SourceFileGenerator, StaticGenerator, @@ -354,8 +354,8 @@ def parse_arguments(argv=None): "--settings", dest="settings", help="The settings of the application, this is " - "automatically set to {} if a file exists with this " - "name.".format(DEFAULT_CONFIG_NAME), + f"automatically set to {DEFAULT_CONFIG_NAME} if a file exists with this " + "name.", ) parser.add_argument( diff --git a/pelican/__main__.py b/pelican/__main__.py index 17aead3b..41a1f712 100644 --- a/pelican/__main__.py +++ b/pelican/__main__.py @@ -4,6 +4,5 @@ python -m pelican module entry point to run via python -m from . import main - if __name__ == "__main__": main() diff --git a/pelican/contents.py b/pelican/contents.py index c640df69..9532c523 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -17,6 +17,9 @@ except ModuleNotFoundError: from pelican.plugins import signals from pelican.settings import DEFAULT_CONFIG, Settings + +# Import these so that they're available when you import from pelican.contents. +from pelican.urlwrappers import Author, Category, Tag, URLWrapper # NOQA from pelican.utils import ( deprecated_attribute, memoized, @@ -28,9 +31,6 @@ from pelican.utils import ( truncate_html_words, ) -# Import these so that they're available when you import from pelican.contents. -from pelican.urlwrappers import Author, Category, Tag, URLWrapper # NOQA - logger = logging.getLogger(__name__) @@ -370,13 +370,13 @@ class Content: def _get_intrasite_link_regex(self) -> re.Pattern: intrasite_link_regex = self.settings["INTRASITE_LINK_REGEX"] - regex = r""" + regex = rf""" (?P<[^\>]+ # match tag with all url-value attributes (?:href|src|poster|data|cite|formaction|action|content)\s*=\s*) (?P["\']) # require value to be quoted - (?P{}(?P.*?)) # the url value - (?P=quote)""".format(intrasite_link_regex) + (?P{intrasite_link_regex}(?P.*?)) # the url value + (?P=quote)""" return re.compile(regex, re.X) def _update_content(self, content: str, siteurl: str) -> str: @@ -465,7 +465,6 @@ class Content: @summary.setter def summary(self, value: str): """Dummy function""" - pass @property def status(self) -> str: diff --git a/pelican/plugins/_utils.py b/pelican/plugins/_utils.py index 805ed049..9dfc8f81 100644 --- a/pelican/plugins/_utils.py +++ b/pelican/plugins/_utils.py @@ -6,7 +6,6 @@ import logging import pkgutil import sys - logger = logging.getLogger(__name__) diff --git a/pelican/plugins/signals.py b/pelican/plugins/signals.py index 27177367..c36f595d 100644 --- a/pelican/plugins/signals.py +++ b/pelican/plugins/signals.py @@ -1,4 +1,4 @@ -from blinker import signal, Signal +from blinker import Signal, signal from ordered_set import OrderedSet # Signals will call functions in the order of connection, i.e. plugin order diff --git a/pelican/readers.py b/pelican/readers.py index 60b9765a..e9b07582 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -22,7 +22,7 @@ from pelican.utils import get_date, pelican_open, posixize_path try: from markdown import Markdown except ImportError: - Markdown = False # NOQA + Markdown = False # Metadata processors have no way to discard an unwanted value, so we have # them return this value instead to signal that it should be discarded later. @@ -607,8 +607,8 @@ class Readers(FileStampDataCacher): # eventually filter the content with typogrify if asked so if self.settings["TYPOGRIFY"]: - from typogrify.filters import typogrify import smartypants + from typogrify.filters import typogrify typogrify_dashes = self.settings["TYPOGRIFY_DASHES"] if typogrify_dashes == "oldschool": diff --git a/pelican/rstdirectives.py b/pelican/rstdirectives.py index 0a549424..41bfc3d2 100644 --- a/pelican/rstdirectives.py +++ b/pelican/rstdirectives.py @@ -2,7 +2,6 @@ import re from docutils import nodes, utils from docutils.parsers.rst import Directive, directives, roles - from pygments import highlight from pygments.formatters import HtmlFormatter from pygments.lexers import TextLexer, get_lexer_by_name diff --git a/pelican/settings.py b/pelican/settings.py index 47457ec1..2cd6fb00 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -267,9 +267,7 @@ def _printf_s_to_format_field(printf_string: str, format_field: str) -> str: TEST_STRING = "PELICAN_PRINTF_S_DEPRECATION" expected = printf_string % TEST_STRING - result = printf_string.replace("{", "{{").replace("}", "}}") % "{{{}}}".format( - format_field - ) + result = printf_string.replace("{", "{{").replace("}", "}}") % f"{{{format_field}}}" if result.format(**{format_field: TEST_STRING}) != expected: raise ValueError(f"Failed to safely replace %s with {{{format_field}}}") @@ -412,7 +410,7 @@ def handle_deprecated_settings(settings: Settings) -> Settings: ) logger.warning(message) if old_values.get("SLUG"): - for f in {"CATEGORY", "TAG"}: + for f in ("CATEGORY", "TAG"): if old_values.get(f): old_values[f] = old_values["SLUG"] + old_values[f] old_values["AUTHOR"] = old_values.get("AUTHOR", []) diff --git a/pelican/tests/build_test/test_build_files.py b/pelican/tests/build_test/test_build_files.py index 9aad990d..c80253db 100644 --- a/pelican/tests/build_test/test_build_files.py +++ b/pelican/tests/build_test/test_build_files.py @@ -1,6 +1,6 @@ -from re import match import tarfile from pathlib import Path +from re import match from zipfile import ZipFile import pytest diff --git a/pelican/tests/support.py b/pelican/tests/support.py index 16060441..f43468b2 100644 --- a/pelican/tests/support.py +++ b/pelican/tests/support.py @@ -261,9 +261,7 @@ class LoggedTestCase(unittest.TestCase): self.assertEqual( actual, count, - msg="expected {} occurrences of {!r}, but found {}".format( - count, msg, actual - ), + msg=f"expected {count} occurrences of {msg!r}, but found {actual}", ) diff --git a/pelican/tests/test_cache.py b/pelican/tests/test_cache.py index 6dc91b2c..a1bbc559 100644 --- a/pelican/tests/test_cache.py +++ b/pelican/tests/test_cache.py @@ -6,7 +6,6 @@ from unittest.mock import MagicMock from pelican.generators import ArticlesGenerator, PagesGenerator from pelican.tests.support import get_context, get_settings, unittest - CUR_DIR = os.path.dirname(__file__) CONTENT_DIR = os.path.join(CUR_DIR, "content") diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py index 9dc7b70d..89219029 100644 --- a/pelican/tests/test_contents.py +++ b/pelican/tests/test_contents.py @@ -13,7 +13,6 @@ from pelican.settings import DEFAULT_CONFIG from pelican.tests.support import LoggedTestCase, get_context, get_settings, unittest from pelican.utils import path_to_url, posixize_path, truncate_html_words - # generate one paragraph, enclosed with

TEST_CONTENT = str(generate_lorem_ipsum(n=1)) TEST_SUMMARY = generate_lorem_ipsum(n=1, html=False) @@ -297,7 +296,6 @@ class TestPage(TestBase): def test_signal(self): def receiver_test_function(sender): receiver_test_function.has_been_called = True - pass receiver_test_function.has_been_called = False diff --git a/pelican/tests/test_generators.py b/pelican/tests/test_generators.py index 8c257b55..920d9061 100644 --- a/pelican/tests/test_generators.py +++ b/pelican/tests/test_generators.py @@ -13,11 +13,11 @@ from pelican.generators import ( TemplatePagesGenerator, ) from pelican.tests.support import ( + TestCaseWithCLocale, can_symlink, get_context, get_settings, unittest, - TestCaseWithCLocale, ) from pelican.writers import Writer diff --git a/pelican/tests/test_importer.py b/pelican/tests/test_importer.py index 916c1183..469184cd 100644 --- a/pelican/tests/test_importer.py +++ b/pelican/tests/test_importer.py @@ -5,11 +5,11 @@ from unittest.mock import patch from pelican.settings import DEFAULT_CONFIG from pelican.tests.support import ( + TestCaseWithCLocale, mute, skipIfNoExecutable, temporary_folder, unittest, - TestCaseWithCLocale, ) from pelican.tools.pelican_import import ( blogger2fields, @@ -19,12 +19,12 @@ from pelican.tools.pelican_import import ( download_attachments, fields2pelican, get_attachments, - tumblr2fields, - wp2fields, + medium_slug, mediumpost2fields, mediumposts2fields, strip_medium_post_content, - medium_slug, + tumblr2fields, + wp2fields, ) from pelican.utils import path_to_file_url, slugify @@ -41,7 +41,7 @@ WORDPRESS_DECODED_CONTENT_SAMPLE = os.path.join( try: from bs4 import BeautifulSoup except ImportError: - BeautifulSoup = False # NOQA + BeautifulSoup = False try: import bs4.builder._lxml as LXML @@ -532,9 +532,7 @@ class TestWordpressXMLAttachements(TestCaseWithCLocale): self.assertEqual(self.attachments[post], {expected_invalid}) else: self.fail( - "all attachments should match to a " "filename or None, {}".format( - post - ) + "all attachments should match to a " f"filename or None, {post}" ) def test_download_attachments(self): diff --git a/pelican/tests/test_paginator.py b/pelican/tests/test_paginator.py index 2160421f..6a7dbe02 100644 --- a/pelican/tests/test_paginator.py +++ b/pelican/tests/test_paginator.py @@ -7,7 +7,6 @@ from pelican.paginator import Paginator from pelican.settings import DEFAULT_CONFIG from pelican.tests.support import get_settings, unittest - # generate one paragraph, enclosed with

TEST_CONTENT = str(generate_lorem_ipsum(n=1)) TEST_SUMMARY = generate_lorem_ipsum(n=1, html=False) diff --git a/pelican/tests/test_plugins.py b/pelican/tests/test_plugins.py index 55fa8a6a..69a0384c 100644 --- a/pelican/tests/test_plugins.py +++ b/pelican/tests/test_plugins.py @@ -1,7 +1,6 @@ import os from contextlib import contextmanager -import pelican.tests.dummy_plugins.normal_plugin.normal_plugin as normal_plugin from pelican.plugins._utils import ( get_namespace_plugins, get_plugin_name, @@ -9,6 +8,7 @@ from pelican.plugins._utils import ( plugin_enabled, ) from pelican.plugins.signals import signal +from pelican.tests.dummy_plugins.normal_plugin import normal_plugin from pelican.tests.support import unittest diff --git a/pelican/tests/test_readers.py b/pelican/tests/test_readers.py index 04049894..e49c8b74 100644 --- a/pelican/tests/test_readers.py +++ b/pelican/tests/test_readers.py @@ -5,7 +5,6 @@ from pelican import readers from pelican.tests.support import get_settings, unittest from pelican.utils import SafeDatetime - CUR_DIR = os.path.dirname(__file__) CONTENT_PATH = os.path.join(CUR_DIR, "content") diff --git a/pelican/tests/test_settings.py b/pelican/tests/test_settings.py index f370f7eb..84f7a5c9 100644 --- a/pelican/tests/test_settings.py +++ b/pelican/tests/test_settings.py @@ -3,7 +3,6 @@ import locale import os from os.path import abspath, dirname, join - from pelican.settings import ( DEFAULT_CONFIG, DEFAULT_THEME, diff --git a/pelican/tools/pelican_import.py b/pelican/tools/pelican_import.py index eb343860..3e1f31db 100755 --- a/pelican/tools/pelican_import.py +++ b/pelican/tools/pelican_import.py @@ -22,7 +22,6 @@ from pelican.log import init from pelican.settings import DEFAULT_CONFIG from pelican.utils import SafeDatetime, slugify - logger = logging.getLogger(__name__) diff --git a/pelican/tools/pelican_quickstart.py b/pelican/tools/pelican_quickstart.py index a4dc98e1..c00a252c 100755 --- a/pelican/tools/pelican_quickstart.py +++ b/pelican/tools/pelican_quickstart.py @@ -169,7 +169,7 @@ def ask_timezone(question, default, tzurl): r = tz_dict[r] break else: - print("Please enter a valid time zone:\n" " (check [{}])".format(tzurl)) + print("Please enter a valid time zone:\n" f" (check [{tzurl}])") return r @@ -205,14 +205,14 @@ def main(): args = parser.parse_args() print( - """Welcome to pelican-quickstart v{v}. + f"""Welcome to pelican-quickstart v{__version__}. This script will help you create a new Pelican-based website. Please answer the following questions so this script can generate the files needed by Pelican. - """.format(v=__version__) + """ ) project = os.path.join(os.environ.get("VIRTUAL_ENV", os.curdir), ".project") diff --git a/pelican/tools/pelican_themes.py b/pelican/tools/pelican_themes.py index c5b49b9f..fa59b8fd 100755 --- a/pelican/tools/pelican_themes.py +++ b/pelican/tools/pelican_themes.py @@ -240,15 +240,11 @@ def install(path, v=False, u=False): except OSError as e: err( "Cannot change permissions of files " - "or directory in `{r}':\n{e}".format(r=theme_path, e=str(e)), + f"or directory in `{theme_path}':\n{e!s}", die=False, ) except Exception as e: - err( - "Cannot copy `{p}' to `{t}':\n{e}".format( - p=path, t=theme_path, e=str(e) - ) - ) + err(f"Cannot copy `{path}' to `{theme_path}':\n{e!s}") def symlink(path, v=False): @@ -268,11 +264,7 @@ def symlink(path, v=False): try: os.symlink(path, theme_path) except Exception as e: - err( - "Cannot link `{p}' to `{t}':\n{e}".format( - p=path, t=theme_path, e=str(e) - ) - ) + err(f"Cannot link `{path}' to `{theme_path}':\n{e!s}") def is_broken_link(path): diff --git a/pelican/urlwrappers.py b/pelican/urlwrappers.py index 6d705d4c..4ed385f9 100644 --- a/pelican/urlwrappers.py +++ b/pelican/urlwrappers.py @@ -98,7 +98,7 @@ class URLWrapper: return self.name def __repr__(self): - return f"<{type(self).__name__} {repr(self._name)}>" + return f"<{type(self).__name__} {self._name!r}>" def _from_settings(self, key, get_page_name=False): """Returns URL information as defined in settings. diff --git a/pelican/utils.py b/pelican/utils.py index 86698aee..7017c458 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -23,14 +23,10 @@ from typing import ( Any, Callable, Collection, - Dict, Generator, Iterable, - List, Optional, Sequence, - Tuple, - Type, Union, ) @@ -40,9 +36,8 @@ try: from zoneinfo import ZoneInfo except ModuleNotFoundError: from backports.zoneinfo import ZoneInfo -from markupsafe import Markup - import watchfiles +from markupsafe import Markup if TYPE_CHECKING: from pelican.contents import Content @@ -158,7 +153,7 @@ class memoized: def __init__(self, func: Callable) -> None: self.func = func - self.cache: Dict[Any, Any] = {} + self.cache: dict[Any, Any] = {} def __call__(self, *args) -> Any: if not isinstance(args, Hashable): @@ -185,8 +180,8 @@ class memoized: def deprecated_attribute( old: str, new: str, - since: Tuple[int, ...], - remove: Optional[Tuple[int, ...]] = None, + since: tuple[int, ...], + remove: Optional[tuple[int, ...]] = None, doc: Optional[str] = None, ): """Attribute deprecation decorator for gentle upgrades @@ -256,7 +251,7 @@ def pelican_open( def slugify( value: str, - regex_subs: Iterable[Tuple[str, str]] = (), + regex_subs: Iterable[tuple[str, str]] = (), preserve_case: bool = False, use_unicode: bool = False, ) -> str: @@ -642,9 +637,9 @@ def truncate_html_words(s: str, num: int, end_text: str = "…") -> str: def process_translations( - content_list: List[Content], + content_list: list[Content], translation_id: Optional[Union[str, Collection[str]]] = None, -) -> Tuple[List[Content], List[Content]]: +) -> tuple[list[Content], list[Content]]: """Finds translations and returns them. For each content_list item, populates the 'translations' attribute, and @@ -674,14 +669,14 @@ def process_translations( content_list.sort(key=attrgetter(*translation_id)) except TypeError: raise TypeError( - "Cannot unpack {}, 'translation_id' must be falsy, a" - " string or a collection of strings".format(translation_id) + f"Cannot unpack {translation_id}, 'translation_id' must be falsy, a" + " string or a collection of strings" ) except AttributeError: raise AttributeError( - "Cannot use {} as 'translation_id', there " + f"Cannot use {translation_id} as 'translation_id', there " "appear to be items without these metadata " - "attributes".format(translation_id) + "attributes" ) for id_vals, items in groupby(content_list, attrgetter(*translation_id)): @@ -702,7 +697,7 @@ def process_translations( return index, translations -def get_original_items(items: List[Content], with_str: str) -> List[Content]: +def get_original_items(items: list[Content], with_str: str) -> list[Content]: def _warn_source_paths(msg, items, *extra): args = [len(items)] args.extend(extra) @@ -743,9 +738,9 @@ def get_original_items(items: List[Content], with_str: str) -> List[Content]: def order_content( - content_list: List[Content], + content_list: list[Content], order_by: Union[str, Callable[[Content], Any], None] = "slug", -) -> List[Content]: +) -> list[Content]: """Sorts content. order_by can be a string of an attribute or sorting function. If order_by @@ -807,8 +802,8 @@ def order_content( def wait_for_changes( settings_file: str, - reader_class: Type["Readers"], - settings: "Settings", + reader_class: type[Readers], + settings: Settings, ): content_path = settings.get("PATH", "") theme_path = settings.get("THEME", "") diff --git a/pelican/writers.py b/pelican/writers.py index 1c41b4ee..746811e1 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -4,7 +4,6 @@ from posixpath import join as posix_join from urllib.parse import urljoin from feedgenerator import Atom1Feed, Rss201rev2Feed, get_tag_uri - from markupsafe import Markup from pelican.paginator import Paginator From c46063cfc39dcde030f30ffaaf8896899805c5c8 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Thu, 30 May 2024 16:42:09 +0200 Subject: [PATCH 036/147] Ignore latest Ruff fixes in `git blame` --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 0d92c9d9..bccdab76 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -5,3 +5,5 @@ cabdb26cee66e1173cf16cb31d3fe5f9fa4392e7 ecd598f293161a52564aa6e8dfdcc8284dc93970 # Apply Ruff and pyupgrade to Jinja templates db241feaa445375dc05e189e69287000ffe5fa8e +# Change pre-commit to run ruff and ruff-format with fixes +6d8597addb17d5fa3027ead91427939e8e4e89ec From 39c964450ce5e1dd2987561f475374790f02c6c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Pit-Claudel?= Date: Thu, 30 May 2024 17:13:27 +0200 Subject: [PATCH 037/147] Choose logging handler via `--log-handler` CLI option (#3293) --- pelican/__init__.py | 16 +++++++++++++++- pelican/log.py | 9 +++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index aef4b124..8a880584 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -19,7 +19,7 @@ __path__ = extend_path(__path__, __name__) # pelican.log has to be the first pelican module to be loaded # because logging.setLoggerClass has to be called before logging.getLogger -from pelican.log import console # noqa: I001 +from pelican.log import console, DEFAULT_LOG_HANDLER # noqa: I001 from pelican.log import init as init_logging from pelican.generators import ( ArticlesGenerator, @@ -455,6 +455,17 @@ def parse_arguments(argv=None): ), ) + LOG_HANDLERS = {"plain": None, "rich": DEFAULT_LOG_HANDLER} + parser.add_argument( + "--log-handler", + default="rich", + choices=LOG_HANDLERS, + help=( + "Which handler to use to format log messages. " + "The `rich` handler prints output in columns." + ), + ) + parser.add_argument( "--logs-dedup-min-level", default="WARNING", @@ -509,6 +520,8 @@ def parse_arguments(argv=None): if args.bind is not None and not args.listen: logger.warning("--bind without --listen has no effect") + args.log_handler = LOG_HANDLERS[args.log_handler] + return args @@ -631,6 +644,7 @@ def main(argv=None): level=args.verbosity, fatal=args.fatal, name=__name__, + handler=args.log_handler, logs_dedup_min_level=logs_dedup_min_level, ) diff --git a/pelican/log.py b/pelican/log.py index ef49d280..edf2f182 100644 --- a/pelican/log.py +++ b/pelican/log.py @@ -126,11 +126,13 @@ logging.setLoggerClass(FatalLogger) # force root logger to be of our preferred class logging.getLogger().__class__ = FatalLogger +DEFAULT_LOG_HANDLER = RichHandler(console=console) + def init( level=None, fatal="", - handler=RichHandler(console=console), + handler=DEFAULT_LOG_HANDLER, name=None, logs_dedup_min_level=None, ): @@ -139,7 +141,10 @@ def init( LOG_FORMAT = "%(message)s" logging.basicConfig( - level=level, format=LOG_FORMAT, datefmt="[%H:%M:%S]", handlers=[handler] + level=level, + format=LOG_FORMAT, + datefmt="[%H:%M:%S]", + handlers=[handler] if handler else [], ) logger = logging.getLogger(name) From 800f22b3ba2139c267d44c45b681461294262b7d Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 10:49:57 -0500 Subject: [PATCH 038/147] Upgrade ruff to v0.4.6, pre-commit-hooks to v4.6.0 --- .pre-commit-config.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0e65a965..626ea299 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # See https://pre-commit.com/hooks.html for info on hooks repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.5.0 + rev: v4.6.0 hooks: - id: check-added-large-files - id: check-ast @@ -14,7 +14,7 @@ repos: - id: forbid-new-submodules - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.15 + rev: v0.4.6 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] From 0bd02c00c078fe041b65fbf4eab13601bb42676d Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 10:53:38 -0500 Subject: [PATCH 039/147] Ruff v0.4.6 auto-fixes --- pelican/__init__.py | 10 +--------- pelican/settings.py | 5 +---- pelican/tests/test_generators.py | 12 ++++++------ pelican/utils.py | 18 +++++++++--------- pelican/writers.py | 2 +- 5 files changed, 18 insertions(+), 29 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index 8a880584..d63f88c3 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -193,15 +193,7 @@ class Pelican: ) console.print( - "Done: Processed {}, {}, {}, {}, {} and {} in {:.2f} seconds.".format( - pluralized_articles, - pluralized_drafts, - pluralized_hidden_articles, - pluralized_pages, - pluralized_hidden_pages, - pluralized_draft_pages, - time.time() - start_time, - ) + f"Done: Processed {pluralized_articles}, {pluralized_drafts}, {pluralized_hidden_articles}, {pluralized_pages}, {pluralized_hidden_pages} and {pluralized_draft_pages} in {time.time() - start_time:.2f} seconds." ) def _get_generator_classes(self): diff --git a/pelican/settings.py b/pelican/settings.py index 2cd6fb00..0585b3be 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -322,10 +322,7 @@ def handle_deprecated_settings(settings: Settings) -> Settings: "EXTRA_TEMPLATES_PATHS is deprecated use " "THEME_TEMPLATES_OVERRIDES instead." ) - if ( - "THEME_TEMPLATES_OVERRIDES" in settings - and settings["THEME_TEMPLATES_OVERRIDES"] - ): + if settings.get("THEME_TEMPLATES_OVERRIDES"): raise Exception( "Setting both EXTRA_TEMPLATES_PATHS and " "THEME_TEMPLATES_OVERRIDES is not permitted. Please move to " diff --git a/pelican/tests/test_generators.py b/pelican/tests/test_generators.py index 920d9061..e739e180 100644 --- a/pelican/tests/test_generators.py +++ b/pelican/tests/test_generators.py @@ -597,9 +597,9 @@ class TestArticlesGenerator(unittest.TestCase): self.assertEqual(expected, abbreviated_archives) # Day archives enabled: - settings[ - "DAY_ARCHIVE_SAVE_AS" - ] = "posts/{date:%Y}/{date:%b}/{date:%d}/index.html" + settings["DAY_ARCHIVE_SAVE_AS"] = ( + "posts/{date:%Y}/{date:%b}/{date:%d}/index.html" + ) settings["DAY_ARCHIVE_URL"] = "posts/{date:%Y}/{date:%b}/{date:%d}/" context = get_context(settings) generator = ArticlesGenerator( @@ -737,9 +737,9 @@ class TestArticlesGenerator(unittest.TestCase): all_articles=generator.articles, ) - settings[ - "DAY_ARCHIVE_SAVE_AS" - ] = "posts/{date:%Y}/{date:%b}/{date:%d}/index.html" + settings["DAY_ARCHIVE_SAVE_AS"] = ( + "posts/{date:%Y}/{date:%b}/{date:%d}/index.html" + ) settings["DAY_ARCHIVE_URL"] = "posts/{date:%Y}/{date:%b}/{date:%d}/" context = get_context(settings) generator = ArticlesGenerator( diff --git a/pelican/utils.py b/pelican/utils.py index 7017c458..78e3e807 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -446,15 +446,15 @@ class _HTMLWordTruncator(HTMLParser): r"{DBC}|(\w[\w'-]*)".format( # DBC means CJK-like characters. An character can stand for a word. DBC=( - "([\u4E00-\u9FFF])|" # CJK Unified Ideographs - "([\u3400-\u4DBF])|" # CJK Unified Ideographs Extension A - "([\uF900-\uFAFF])|" # CJK Compatibility Ideographs - "([\U00020000-\U0002A6DF])|" # CJK Unified Ideographs Extension B - "([\U0002F800-\U0002FA1F])|" # CJK Compatibility Ideographs Supplement - "([\u3040-\u30FF])|" # Hiragana and Katakana - "([\u1100-\u11FF])|" # Hangul Jamo - "([\uAC00-\uD7FF])|" # Hangul Compatibility Jamo - "([\u3130-\u318F])" # Hangul Syllables + "([\u4e00-\u9fff])|" # CJK Unified Ideographs + "([\u3400-\u4dbf])|" # CJK Unified Ideographs Extension A + "([\uf900-\ufaff])|" # CJK Compatibility Ideographs + "([\U00020000-\U0002a6df])|" # CJK Unified Ideographs Extension B + "([\U0002f800-\U0002fa1f])|" # CJK Compatibility Ideographs Supplement + "([\u3040-\u30ff])|" # Hiragana and Katakana + "([\u1100-\u11ff])|" # Hangul Jamo + "([\uac00-\ud7ff])|" # Hangul Compatibility Jamo + "([\u3130-\u318f])" # Hangul Syllables ) ), re.UNICODE, diff --git a/pelican/writers.py b/pelican/writers.py index 746811e1..cce01b58 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -27,7 +27,7 @@ class Writer: self._overridden_files = set() # See Content._link_replacer for details - if "RELATIVE_URLS" in self.settings and self.settings["RELATIVE_URLS"]: + if self.settings.get("RELATIVE_URLS"): self.urljoiner = posix_join else: self.urljoiner = lambda base, url: urljoin( From 54ac03fca6f1d999f61d2f4119dafe156e1a24d8 Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 10:56:06 -0500 Subject: [PATCH 040/147] change ruff version in pyproject.toml --- .pre-commit-config.yaml | 1 + pyproject.toml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 626ea299..a3e7ab17 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,7 @@ repos: - id: forbid-new-submodules - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit + # ruff version should match the one in pyproject.toml rev: v0.4.6 hooks: - id: ruff diff --git a/pyproject.toml b/pyproject.toml index 39694ffc..c84c35b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -96,7 +96,8 @@ dev = [ "pytest-xdist>=3.4.0", "tox>=4.11.3", "invoke>=2.2.0", - "ruff>=0.1.15,<0.2.0", + # ruff version should match the one in .pre-commit-config.yaml + "ruff==0.4.6", "tomli>=2.0.1; python_version < \"3.11\"", ] From 9d46a94d6d1643258af6246706c0e82c86deb1b1 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Thu, 30 May 2024 19:15:56 +0200 Subject: [PATCH 041/147] Ignore Ruff 0.4.x fixes in `git blame` --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index bccdab76..2809b658 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -7,3 +7,5 @@ ecd598f293161a52564aa6e8dfdcc8284dc93970 db241feaa445375dc05e189e69287000ffe5fa8e # Change pre-commit to run ruff and ruff-format with fixes 6d8597addb17d5fa3027ead91427939e8e4e89ec +# Upgrade Ruff from 0.1.x to 0.4.x +0bd02c00c078fe041b65fbf4eab13601bb42676d From b6d3b6589935f8e2ea6d01e2ff6f8ee3a308af8c Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 10:33:40 -0500 Subject: [PATCH 042/147] More ruff checks --- pyproject.toml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c84c35b0..5546d1cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -190,19 +190,10 @@ ignore = [ "PLR5501", # collapsible-else-if "PERF203", # try-except-in-loop "B006", # mutable-argument-default - "PLR1714", # repeated-equality-comparison - "PERF401", # manual-list-comprehension # TODO: these only have one violation each in Dec 2023: "SLOT000", # no-slots-in-str-subclass "PYI024", # collections-named-tuple - "PLW0603", # global-statement "PIE800", # unnecessary-spread - "ISC003", # explicit-string-concatenation - "EXE002", # shebang-missing-executable-file - "C401", # unnecessary-generator-set - "C416", # unnecessary `list` comprehension - "B028", # no-explicit-stacklevel - "B008", # function-call-in-default-argument ] [tool.ruff.lint.extend-per-file-ignores] From 9d30c5608a58d202b1c02d55651e6ac746bfb173 Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 10:33:50 -0500 Subject: [PATCH 043/147] Code changes for more ruff checks --- pelican/server.py | 7 +++---- pelican/settings.py | 2 +- pelican/tests/test_importer.py | 29 ++++++++++++++--------------- pelican/tests/test_testsuite.py | 2 +- samples/pelican.conf.py | 0 5 files changed, 19 insertions(+), 21 deletions(-) mode change 100755 => 100644 samples/pelican.conf.py diff --git a/pelican/server.py b/pelican/server.py index 61729bf1..71cd2d81 100644 --- a/pelican/server.py +++ b/pelican/server.py @@ -32,19 +32,18 @@ def parse_arguments(): "--cert", default="./cert.pem", nargs="?", - help="Path to certificate file. " + "Relative to current directory", + help="Path to certificate file. Relative to current directory", ) parser.add_argument( "--key", default="./key.pem", nargs="?", - help="Path to certificate key file. " + "Relative to current directory", + help="Path to certificate key file. Relative to current directory", ) parser.add_argument( "--path", default=".", - help="Path to pelican source directory to serve. " - + "Relative to current directory", + help="Path to pelican source directory to serve. Relative to current directory", ) return parser.parse_args() diff --git a/pelican/settings.py b/pelican/settings.py index 0585b3be..ea6fae77 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -223,7 +223,7 @@ def read_settings( # parameters to docutils directive handlers, so we have to have a # variable here that we'll import from within Pygments.run (see # rstdirectives.py) to see what the user defaults were. - global PYGMENTS_RST_OPTIONS + global PYGMENTS_RST_OPTIONS # noqa: PLW0603 PYGMENTS_RST_OPTIONS = settings.get("PYGMENTS_RST_OPTIONS", None) return settings diff --git a/pelican/tests/test_importer.py b/pelican/tests/test_importer.py index 469184cd..e69e321f 100644 --- a/pelican/tests/test_importer.py +++ b/pelican/tests/test_importer.py @@ -152,11 +152,12 @@ class TestWordpressXmlImporter(TestCaseWithCLocale): def test_dircat(self): silent_f2p = mute(True)(fields2pelican) - test_posts = [] - for post in self.posts: - # check post kind - if len(post[5]) > 0: # Has a category - test_posts.append(post) + test_posts = [ + post + for post in self.posts + # check post has a category + if len(post[5]) > 0 + ] with temporary_folder() as temp: fnames = list(silent_f2p(test_posts, "markdown", temp, dircat=True)) subs = DEFAULT_CONFIG["SLUG_REGEX_SUBSTITUTIONS"] @@ -185,7 +186,7 @@ class TestWordpressXmlImporter(TestCaseWithCLocale): kind, format, ) in self.posts: - if kind == "page" or kind == "article": + if kind in {"page", "article"}: pass else: pages_data.append((title, fname)) @@ -206,7 +207,7 @@ class TestWordpressXmlImporter(TestCaseWithCLocale): kind, format, ) in self.custposts: - if kind == "article" or kind == "page": + if kind in {"page", "article"}: pass else: cust_data.append((title, kind)) @@ -266,11 +267,12 @@ class TestWordpressXmlImporter(TestCaseWithCLocale): def test_wp_custpost_true_dirpage_false(self): # pages should only be put in their own directory when dirpage = True silent_f2p = mute(True)(fields2pelican) - test_posts = [] - for post in self.custposts: + test_posts = [ + post + for post in self.custposts # check post kind - if post[8] == "page": - test_posts.append(post) + if post[8] == "page" + ] with temporary_folder() as temp: fnames = list( silent_f2p( @@ -748,10 +750,7 @@ class TestMediumImporter(TestCaseWithCLocale): def test_mediumposts2field(self): """Parse all posts in an export directory""" - posts = [ - fields - for fields in mediumposts2fields(f"{self.test_content_root}/medium_posts") - ] + posts = list(mediumposts2fields(f"{self.test_content_root}/medium_posts")) self.assertEqual(1, len(posts)) self.assertEqual(self.post_tuple, posts[0]) diff --git a/pelican/tests/test_testsuite.py b/pelican/tests/test_testsuite.py index a9a0c200..938d2bdf 100644 --- a/pelican/tests/test_testsuite.py +++ b/pelican/tests/test_testsuite.py @@ -6,4 +6,4 @@ from pelican.tests.support import unittest class TestSuiteTest(unittest.TestCase): def test_error_on_warning(self): with self.assertRaises(UserWarning): - warnings.warn("test warning") + warnings.warn("test warning") # noqa: B028 diff --git a/samples/pelican.conf.py b/samples/pelican.conf.py old mode 100755 new mode 100644 From 144b2edf88026a764b1978f4cb0f27e150d1334e Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Thu, 30 May 2024 19:40:45 +0200 Subject: [PATCH 044/147] Ignore more Ruff fixes in `git blame` --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 2809b658..fddd0764 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -9,3 +9,5 @@ db241feaa445375dc05e189e69287000ffe5fa8e 6d8597addb17d5fa3027ead91427939e8e4e89ec # Upgrade Ruff from 0.1.x to 0.4.x 0bd02c00c078fe041b65fbf4eab13601bb42676d +# Apply more Ruff checks to code +9d30c5608a58d202b1c02d55651e6ac746bfb173 From 3624bcdbf41f570471d24d59dc7ccb24f536e3fe Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 13:18:03 -0500 Subject: [PATCH 045/147] More ruff fixes: stop ignoring C408, UP007, PLR5501, B006 --- pyproject.toml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5546d1cf..b7e39a4a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -182,14 +182,17 @@ ignore = [ "INP001", # implicit-namespace-package "RUF015", # unnecessary-iterable-allocation-for-first-element "PLR1722", # sys-exit-alias + # ruff-format wants us to ignore ISC001. I don't love that, but okay. + # "warning: The following rules may cause conflicts when used with the formatter: + # `ISC001`. To avoid unexpected behavior, we recommend disabling these rules, + # either by removing them from the `select` or `extend-select` configuration, + # or adding them to the `ignore` configuration." "ISC001", # single-line-implicit-string-concatenation - "C408", # unnecessary-collection-call "B904", # raise-without-from-inside-except - "UP007", # use `|` operator for union type annotations (PEP 604) "UP031", # printf-string-formatting - "PLR5501", # collapsible-else-if + # PERF203 has minimal performance impact, and you have to catch the exception + # inside the loop if you want to ignore it, so let's ignore PERF203. "PERF203", # try-except-in-loop - "B006", # mutable-argument-default # TODO: these only have one violation each in Dec 2023: "SLOT000", # no-slots-in-str-subclass "PYI024", # collections-named-tuple From 7577dd7603f7cb3a09922d1edb65b6eafb6e2ac7 Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 13:21:12 -0500 Subject: [PATCH 046/147] More ruff fixes in files: stop ignoring C408, UP007, PLR5501, B006 --- pelican/__init__.py | 6 +++--- pelican/contents.py | 4 ++-- pelican/generators.py | 6 ++++-- pelican/paginator.py | 5 ++--- pelican/readers.py | 4 ++-- pelican/rstdirectives.py | 2 +- pelican/settings.py | 8 +++---- pelican/tests/test_contents.py | 28 ++++++++++++------------ pelican/tests/test_importer.py | 12 +++++------ pelican/tests/test_readers.py | 2 +- pelican/tests/test_utils.py | 4 ++-- pelican/tools/pelican_import.py | 4 ++-- pelican/tools/pelican_quickstart.py | 27 ++++++++++++----------- pelican/urlwrappers.py | 7 +++--- pelican/utils.py | 33 ++++++++++++----------------- pelican/writers.py | 2 +- 16 files changed, 72 insertions(+), 82 deletions(-) diff --git a/pelican/__init__.py b/pelican/__init__.py index d63f88c3..ab6b0225 100644 --- a/pelican/__init__.py +++ b/pelican/__init__.py @@ -417,7 +417,7 @@ def parse_arguments(argv=None): "--relative-urls", dest="relative_paths", action="store_true", - help="Use relative urls in output, " "useful for site development", + help="Use relative urls in output, useful for site development", ) parser.add_argument( @@ -433,7 +433,7 @@ def parse_arguments(argv=None): "--ignore-cache", action="store_true", dest="ignore_cache", - help="Ignore content cache " "from previous runs by not loading cache files.", + help="Ignore content cache from previous runs by not loading cache files.", ) parser.add_argument( @@ -488,7 +488,7 @@ def parse_arguments(argv=None): "-b", "--bind", dest="bind", - help="IP to bind to when serving files via HTTP " "(default: 127.0.0.1)", + help="IP to bind to when serving files via HTTP (default: 127.0.0.1)", ) parser.add_argument( diff --git a/pelican/contents.py b/pelican/contents.py index 9532c523..21c66296 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -72,7 +72,7 @@ class Content: self._context = context self.translations = [] - local_metadata = dict() + local_metadata = {} local_metadata.update(metadata) # set metadata as attributes @@ -357,7 +357,7 @@ class Content: origin = joiner(siteurl, Author(path, self.settings).url) else: logger.warning( - "Replacement Indicator '%s' not recognized, " "skipping replacement", + "Replacement Indicator '%s' not recognized, skipping replacement", what, ) diff --git a/pelican/generators.py b/pelican/generators.py index 076c8d38..fdcc62ce 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -156,7 +156,7 @@ class Generator: return False - def get_files(self, paths, exclude=[], extensions=None): + def get_files(self, paths, exclude=None, extensions=None): """Return a list of files to use, based on rules :param paths: the list pf paths to search (relative to self.path) @@ -164,6 +164,8 @@ class Generator: :param extensions: the list of allowed extensions (if False, all extensions are allowed) """ + if exclude is None: + exclude = [] # backward compatibility for older generators if isinstance(paths, str): paths = [paths] @@ -1068,7 +1070,7 @@ class StaticGenerator(Generator): except OSError as err: if err.errno == errno.EXDEV: # 18: Invalid cross-device link logger.debug( - "Cross-device links not valid. " "Creating symbolic links instead." + "Cross-device links not valid. Creating symbolic links instead." ) self.fallback_to_symlinks = True self._link_staticfile(sc) diff --git a/pelican/paginator.py b/pelican/paginator.py index e1d50881..92cb26b1 100644 --- a/pelican/paginator.py +++ b/pelican/paginator.py @@ -131,9 +131,8 @@ class Page: if not self.has_next(): rule = p break - else: - if p.min_page <= self.number: - rule = p + elif p.min_page <= self.number: + rule = p if not rule: return "" diff --git a/pelican/readers.py b/pelican/readers.py index e9b07582..422f39fc 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -199,7 +199,7 @@ class RstReader(BaseReader): self._language_code = lang_code else: logger.warning( - "Docutils has no localization for '%s'." " Using 'en' instead.", + "Docutils has no localization for '%s'. Using 'en' instead.", lang_code, ) self._language_code = "en" @@ -320,7 +320,7 @@ class MarkdownReader(BaseReader): elif not DUPLICATES_DEFINITIONS_ALLOWED.get(name, True): if len(value) > 1: logger.warning( - "Duplicate definition of `%s` " "for %s. Using first one.", + "Duplicate definition of `%s` for %s. Using first one.", name, self._source_path, ) diff --git a/pelican/rstdirectives.py b/pelican/rstdirectives.py index 41bfc3d2..9022ac83 100644 --- a/pelican/rstdirectives.py +++ b/pelican/rstdirectives.py @@ -78,7 +78,7 @@ class abbreviation(nodes.Inline, nodes.TextElement): pass -def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): +def abbr_role(typ, rawtext, text, lineno, inliner, options=None, content=None): text = utils.unescape(text) m = _abbr_re.search(text) if m is None: diff --git a/pelican/settings.py b/pelican/settings.py index ea6fae77..214d88a3 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -447,7 +447,7 @@ def handle_deprecated_settings(settings: Settings) -> Settings: and not isinstance(settings[key], Path) and "%s" in settings[key] ): - logger.warning("%%s usage in %s is deprecated, use {lang} " "instead.", key) + logger.warning("%%s usage in %s is deprecated, use {lang} instead.", key) try: settings[key] = _printf_s_to_format_field(settings[key], "lang") except ValueError: @@ -470,7 +470,7 @@ def handle_deprecated_settings(settings: Settings) -> Settings: and not isinstance(settings[key], Path) and "%s" in settings[key] ): - logger.warning("%%s usage in %s is deprecated, use {slug} " "instead.", key) + logger.warning("%%s usage in %s is deprecated, use {slug} instead.", key) try: settings[key] = _printf_s_to_format_field(settings[key], "slug") except ValueError: @@ -614,7 +614,7 @@ def configure_settings(settings: Settings) -> Settings: if key in settings and not isinstance(settings[key], types): value = settings.pop(key) logger.warn( - "Detected misconfigured %s (%s), " "falling back to the default (%s)", + "Detected misconfigured %s (%s), falling back to the default (%s)", key, value, DEFAULT_CONFIG[key], @@ -676,7 +676,7 @@ def configure_settings(settings: Settings) -> Settings: if any(settings.get(k) for k in feed_keys): if not settings.get("SITEURL"): logger.warning( - "Feeds generated without SITEURL set properly may" " not be valid" + "Feeds generated without SITEURL set properly may not be valid" ) if "TIMEZONE" not in settings: diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py index 89219029..d248c3bb 100644 --- a/pelican/tests/test_contents.py +++ b/pelican/tests/test_contents.py @@ -314,7 +314,7 @@ class TestPage(TestBase): args["settings"] = settings # Tag - args["content"] = "A simple test, with a " 'link' + args["content"] = 'A simple test, with a link' page = Page(**args) content = page.get_content("http://notmyidea.org") self.assertEqual( @@ -326,9 +326,7 @@ class TestPage(TestBase): ) # Category - args["content"] = ( - "A simple test, with a " 'link' - ) + args["content"] = 'A simple test, with a link' page = Page(**args) content = page.get_content("http://notmyidea.org") self.assertEqual( @@ -350,7 +348,7 @@ class TestPage(TestBase): # Classic intrasite link via filename args["content"] = ( - "A simple test, with a " 'link' + 'A simple test, with a link' ) content = Page(**args).get_content("http://notmyidea.org") self.assertEqual( @@ -401,7 +399,7 @@ class TestPage(TestBase): # also test for summary in metadata parsed = ( - "A simple summary test, with a " 'link' + 'A simple summary test, with a link' ) linked = ( "A simple summary test, with a " @@ -594,7 +592,7 @@ class TestPage(TestBase): # An intrasite link via filename with %20 as a space args["content"] = ( - "A simple test, with a " 'link' + 'A simple test, with a link' ) content = Page(**args).get_content("http://notmyidea.org") self.assertEqual( @@ -834,10 +832,10 @@ class TestStatic(LoggedTestCase): otherdir_settings = self.settings.copy() otherdir_settings.update( - dict( - PAGE_SAVE_AS=os.path.join("otherpages", "{slug}.html"), - PAGE_URL="otherpages/{slug}.html", - ) + { + "PAGE_SAVE_AS": os.path.join("otherpages", "{slug}.html"), + "PAGE_URL": "otherpages/{slug}.html", + } ) otherdir_page = Page( content="other page", @@ -892,7 +890,7 @@ class TestStatic(LoggedTestCase): """ customstatic = Static( content=None, - metadata=dict(save_as="customfoo.jpg", url="customfoo.jpg"), + metadata={"save_as": "customfoo.jpg", "url": "customfoo.jpg"}, settings=self.settings, source_path=os.path.join("dir", "foo.jpg"), context=self.settings.copy(), @@ -1066,9 +1064,9 @@ class TestStatic(LoggedTestCase): static = Static( content=None, - metadata=dict( - status="draft", - ), + metadata={ + "status": "draft", + }, settings=self.settings, source_path=os.path.join("dir", "foo.jpg"), context=self.settings.copy(), diff --git a/pelican/tests/test_importer.py b/pelican/tests/test_importer.py index e69e321f..46d83432 100644 --- a/pelican/tests/test_importer.py +++ b/pelican/tests/test_importer.py @@ -71,7 +71,7 @@ class TestBloggerXmlImporter(TestCaseWithCLocale): ) comment_titles = {x[0] for x in test_posts if x[8] == "comment"} self.assertEqual( - {"Mishka, always a pleasure to read your " "adventures!..."}, comment_titles + {"Mishka, always a pleasure to read your adventures!..."}, comment_titles ) def test_recognise_status_with_correct_filename(self): @@ -478,7 +478,7 @@ class TestBuildHeader(unittest.TestCase): attachments=["output/test1", "output/test2"], ) self.assertEqual( - header, ("test\n####\n" ":attachments: output/test1, " "output/test2\n\n") + header, ("test\n####\n:attachments: output/test1, output/test2\n\n") ) def test_galleries_added_to_markdown_header(self): @@ -521,10 +521,10 @@ class TestWordpressXMLAttachements(TestCaseWithCLocale): self.assertEqual(self.attachments[post], expected) elif post == "with-excerpt": expected_invalid = ( - "http://thisurlisinvalid.notarealdomain/" "not_an_image.jpg" + "http://thisurlisinvalid.notarealdomain/not_an_image.jpg" ) expected_pelikan = ( - "http://en.wikipedia.org/wiki/" "File:Pelikan_Walvis_Bay.jpg" + "http://en.wikipedia.org/wiki/File:Pelikan_Walvis_Bay.jpg" ) self.assertEqual( self.attachments[post], {expected_invalid, expected_pelikan} @@ -533,9 +533,7 @@ class TestWordpressXMLAttachements(TestCaseWithCLocale): expected_invalid = "http://thisurlisinvalid.notarealdomain" self.assertEqual(self.attachments[post], {expected_invalid}) else: - self.fail( - "all attachments should match to a " f"filename or None, {post}" - ) + self.fail(f"all attachments should match to a filename or None, {post}") def test_download_attachments(self): real_file = os.path.join(CUR_DIR, "content/article.rst") diff --git a/pelican/tests/test_readers.py b/pelican/tests/test_readers.py index e49c8b74..928eb263 100644 --- a/pelican/tests/test_readers.py +++ b/pelican/tests/test_readers.py @@ -591,7 +591,7 @@ class MdReaderTest(ReaderTest): "modified": SafeDatetime(2012, 11, 1), "multiline": [ "Line Metadata should be handle properly.", - "See syntax of Meta-Data extension of " "Python Markdown package:", + "See syntax of Meta-Data extension of Python Markdown package:", "If a line is indented by 4 or more spaces,", "that line is assumed to be an additional line of the value", "for the previous keyword.", diff --git a/pelican/tests/test_utils.py b/pelican/tests/test_utils.py index bd3f0d00..6c25cf45 100644 --- a/pelican/tests/test_utils.py +++ b/pelican/tests/test_utils.py @@ -922,14 +922,14 @@ class TestSanitisedJoin(unittest.TestCase): def test_detect_parent_breakout(self): with self.assertRaisesRegex( RuntimeError, - "Attempted to break out of output directory to " "(.*?:)?/foo/test", + "Attempted to break out of output directory to (.*?:)?/foo/test", ): # (.*?:)? accounts for Windows root utils.sanitised_join("/foo/bar", "../test") def test_detect_root_breakout(self): with self.assertRaisesRegex( RuntimeError, - "Attempted to break out of output directory to " "(.*?:)?/test", + "Attempted to break out of output directory to (.*?:)?/test", ): # (.*?:)? accounts for Windows root utils.sanitised_join("/foo/bar", "/test") diff --git a/pelican/tools/pelican_import.py b/pelican/tools/pelican_import.py index 3e1f31db..c9742d54 100755 --- a/pelican/tools/pelican_import.py +++ b/pelican/tools/pelican_import.py @@ -1095,7 +1095,7 @@ def fields2pelican( if posts_require_pandoc: logger.error( - "Pandoc must be installed to import the following posts:" "\n {}".format( + "Pandoc must be installed to import the following posts:\n {}".format( "\n ".join(posts_require_pandoc) ) ) @@ -1232,7 +1232,7 @@ def main(): exit(error) if args.wp_attach and input_type != "wordpress": - error = "You must be importing a wordpress xml " "to use the --wp-attach option" + error = "You must be importing a wordpress xml to use the --wp-attach option" exit(error) if input_type == "blogger": diff --git a/pelican/tools/pelican_quickstart.py b/pelican/tools/pelican_quickstart.py index c00a252c..2f62e4bc 100755 --- a/pelican/tools/pelican_quickstart.py +++ b/pelican/tools/pelican_quickstart.py @@ -103,11 +103,10 @@ def ask(question, answer=str, default=None, length=None): break else: print("You must enter something") + elif length and len(r) != length: + print(f"Entry must be {length} characters long") else: - if length and len(r) != length: - print(f"Entry must be {length} characters long") - else: - break + break return r @@ -169,7 +168,7 @@ def ask_timezone(question, default, tzurl): r = tz_dict[r] break else: - print("Please enter a valid time zone:\n" f" (check [{tzurl}])") + print(f"Please enter a valid time zone:\n (check [{tzurl}])") return r @@ -253,7 +252,7 @@ needed by Pelican. default=True, ): CONF["siteurl"] = ask( - "What is your URL prefix? (see " "above example; no trailing slash)", + "What is your URL prefix? (see above example; no trailing slash)", str, CONF["siteurl"], ) @@ -266,7 +265,7 @@ needed by Pelican. if CONF["with_pagination"]: CONF["default_pagination"] = ask( - "How many articles per page " "do you want?", + "How many articles per page do you want?", int, CONF["default_pagination"], ) @@ -296,7 +295,7 @@ needed by Pelican. "What is your username on that server?", str, CONF["ftp_user"] ) CONF["ftp_target_dir"] = ask( - "Where do you want to put your " "web site on that server?", + "Where do you want to put your web site on that server?", str, CONF["ftp_target_dir"], ) @@ -314,7 +313,7 @@ needed by Pelican. "What is your username on that server?", str, CONF["ssh_user"] ) CONF["ssh_target_dir"] = ask( - "Where do you want to put your " "web site on that server?", + "Where do you want to put your web site on that server?", str, CONF["ssh_target_dir"], ) @@ -338,23 +337,23 @@ needed by Pelican. ) if ask( - "Do you want to upload your website using " "Rackspace Cloud Files?", + "Do you want to upload your website using Rackspace Cloud Files?", answer=bool, default=False, ): CONF["cloudfiles"] = (True,) CONF["cloudfiles_username"] = ask( - "What is your Rackspace " "Cloud username?", + "What is your Rackspace Cloud username?", str, CONF["cloudfiles_username"], ) CONF["cloudfiles_api_key"] = ask( - "What is your Rackspace " "Cloud API key?", + "What is your Rackspace Cloud API key?", str, CONF["cloudfiles_api_key"], ) CONF["cloudfiles_container"] = ask( - "What is the name of your " "Cloud Files container?", + "What is the name of your Cloud Files container?", str, CONF["cloudfiles_container"], ) @@ -384,7 +383,7 @@ needed by Pelican. except OSError as e: print(f"Error: {e}") - conf_python = dict() + conf_python = {} for key, value in CONF.items(): conf_python[key] = repr(value) render_jinja_template("pelicanconf.py.jinja2", conf_python, "pelicanconf.py") diff --git a/pelican/urlwrappers.py b/pelican/urlwrappers.py index 4ed385f9..8023613c 100644 --- a/pelican/urlwrappers.py +++ b/pelican/urlwrappers.py @@ -115,11 +115,10 @@ class URLWrapper: if not isinstance(value, str): logger.warning("%s is set to %s", setting, value) return value + elif get_page_name: + return os.path.splitext(value)[0].format(**self.as_dict()) else: - if get_page_name: - return os.path.splitext(value)[0].format(**self.as_dict()) - else: - return value.format(**self.as_dict()) + return value.format(**self.as_dict()) page_name = property( functools.partial(_from_settings, key="URL", get_page_name=True) diff --git a/pelican/utils.py b/pelican/utils.py index 78e3e807..b33eaa22 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -25,9 +25,7 @@ from typing import ( Collection, Generator, Iterable, - Optional, Sequence, - Union, ) import dateutil.parser @@ -167,7 +165,7 @@ class memoized: self.cache[args] = value return value - def __repr__(self) -> Optional[str]: + def __repr__(self) -> str | None: return self.func.__doc__ def __get__(self, obj: Any, objtype): @@ -181,8 +179,8 @@ def deprecated_attribute( old: str, new: str, since: tuple[int, ...], - remove: Optional[tuple[int, ...]] = None, - doc: Optional[str] = None, + remove: tuple[int, ...] | None = None, + doc: str | None = None, ): """Attribute deprecation decorator for gentle upgrades @@ -296,9 +294,7 @@ def slugify( return value.strip() -def copy( - source: str, destination: str, ignores: Optional[Iterable[str]] = None -) -> None: +def copy(source: str, destination: str, ignores: Iterable[str] | None = None) -> None: """Recursively copy source into destination. If source is a file, destination has to be a file as well. @@ -364,7 +360,7 @@ def copy( copy_file(src_path, dst_path) else: logger.warning( - "Skipped copy %s (not a file or " "directory) to %s", + "Skipped copy %s (not a file or directory) to %s", src_path, dst_path, ) @@ -474,7 +470,7 @@ class _HTMLWordTruncator(HTMLParser): self.words_found = 0 self.open_tags = [] self.last_word_end = None - self.truncate_at: Optional[int] = None + self.truncate_at: int | None = None def feed(self, *args, **kwargs) -> None: try: @@ -573,11 +569,10 @@ class _HTMLWordTruncator(HTMLParser): if self.last_word_end is None: if self._word_prefix_regex.match(char): self.last_word_end = ref_end + elif self._word_regex.match(char): + self.last_word_end = ref_end else: - if self._word_regex.match(char): - self.last_word_end = ref_end - else: - self.add_last_word() + self.add_last_word() def handle_entityref(self, name: str) -> None: """ @@ -638,7 +633,7 @@ def truncate_html_words(s: str, num: int, end_text: str = "…") -> str: def process_translations( content_list: list[Content], - translation_id: Optional[Union[str, Collection[str]]] = None, + translation_id: str | Collection[str] | None = None, ) -> tuple[list[Content], list[Content]]: """Finds translations and returns them. @@ -739,7 +734,7 @@ def get_original_items(items: list[Content], with_str: str) -> list[Content]: def order_content( content_list: list[Content], - order_by: Union[str, Callable[[Content], Any], None] = "slug", + order_by: str | Callable[[Content], Any] | None = "slug", ) -> list[Content]: """Sorts content. @@ -841,7 +836,7 @@ def wait_for_changes( def set_date_tzinfo( - d: datetime.datetime, tz_name: Optional[str] = None + d: datetime.datetime, tz_name: str | None = None ) -> datetime.datetime: """Set the timezone for dates that don't have tzinfo""" if tz_name and not d.tzinfo: @@ -857,7 +852,7 @@ def mkdir_p(path: str) -> None: os.makedirs(path, exist_ok=True) -def split_all(path: Union[str, pathlib.Path, None]) -> Optional[Sequence[str]]: +def split_all(path: str | pathlib.Path | None) -> Sequence[str] | None: """Split a path into a list of components While os.path.split() splits a single component off the back of @@ -911,7 +906,7 @@ def maybe_pluralize(count: int, singular: str, plural: str) -> str: @contextmanager def temporary_locale( - temp_locale: Optional[str] = None, lc_category: int = locale.LC_ALL + temp_locale: str | None = None, lc_category: int = locale.LC_ALL ) -> Generator[None, None, None]: """ Enable code to run in a context with a temporary locale diff --git a/pelican/writers.py b/pelican/writers.py index cce01b58..683ae30b 100644 --- a/pelican/writers.py +++ b/pelican/writers.py @@ -21,7 +21,7 @@ logger = logging.getLogger(__name__) class Writer: def __init__(self, output_path, settings=None): self.output_path = output_path - self.reminder = dict() + self.reminder = {} self.settings = settings or {} self._written_files = set() self._overridden_files = set() From 3569dede01cb3e7fe0b8813ebb9a8581d7895a93 Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Thu, 30 May 2024 21:40:27 +0200 Subject: [PATCH 047/147] Ignore more Ruff fixes in `git blame` --- .git-blame-ignore-revs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index fddd0764..2d787f0b 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -11,3 +11,5 @@ db241feaa445375dc05e189e69287000ffe5fa8e 0bd02c00c078fe041b65fbf4eab13601bb42676d # Apply more Ruff checks to code 9d30c5608a58d202b1c02d55651e6ac746bfb173 +# Apply yet more Ruff checks to code +7577dd7603f7cb3a09922d1edb65b6eafb6e2ac7 From 308af1912e02d1d6f2cb0a8c765fe58431f95f00 Mon Sep 17 00:00:00 2001 From: boxydog Date: Fri, 31 May 2024 07:21:13 -0500 Subject: [PATCH 048/147] Apply pre-commit filters to pelican/tests/output --- .pre-commit-config.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a3e7ab17..a6179814 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,5 +20,3 @@ repos: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format - -exclude: ^pelican/tests/output/ From 98bdd87dae1974f786971452a3edec51b630db4e Mon Sep 17 00:00:00 2001 From: boxydog Date: Fri, 31 May 2024 07:21:40 -0500 Subject: [PATCH 049/147] Apply pre-commit filters to the files in pelican/tests/output --- pelican/tests/output/basic/a-markdown-powered-article.html | 2 +- pelican/tests/output/basic/archives.html | 2 +- pelican/tests/output/basic/article-1.html | 2 +- pelican/tests/output/basic/article-2.html | 2 +- pelican/tests/output/basic/article-3.html | 2 +- pelican/tests/output/basic/author/alexis-metaireau.html | 2 +- pelican/tests/output/basic/authors.html | 2 +- pelican/tests/output/basic/categories.html | 2 +- pelican/tests/output/basic/category/bar.html | 2 +- pelican/tests/output/basic/category/cat1.html | 2 +- pelican/tests/output/basic/category/misc.html | 2 +- pelican/tests/output/basic/category/yeah.html | 2 +- .../output/basic/drafts/a-draft-article-without-date.html | 4 ++-- pelican/tests/output/basic/drafts/a-draft-article.html | 2 +- pelican/tests/output/basic/feeds/alexis-metaireau.atom.xml | 2 +- pelican/tests/output/basic/feeds/alexis-metaireau.rss.xml | 2 +- pelican/tests/output/basic/feeds/all-en.atom.xml | 2 +- pelican/tests/output/basic/feeds/all-fr.atom.xml | 2 +- pelican/tests/output/basic/feeds/all.atom.xml | 2 +- pelican/tests/output/basic/feeds/bar.atom.xml | 2 +- pelican/tests/output/basic/feeds/cat1.atom.xml | 2 +- pelican/tests/output/basic/feeds/misc.atom.xml | 2 +- pelican/tests/output/basic/feeds/yeah.atom.xml | 2 +- pelican/tests/output/basic/filename_metadata-example.html | 2 +- pelican/tests/output/basic/index.html | 2 +- pelican/tests/output/basic/oh-yeah-fr.html | 2 +- pelican/tests/output/basic/oh-yeah.html | 2 +- pelican/tests/output/basic/override/index.html | 4 ++-- .../tests/output/basic/pages/this-is-a-test-hidden-page.html | 4 ++-- pelican/tests/output/basic/pages/this-is-a-test-page.html | 4 ++-- pelican/tests/output/basic/second-article-fr.html | 2 +- pelican/tests/output/basic/second-article.html | 2 +- pelican/tests/output/basic/tag/bar.html | 2 +- pelican/tests/output/basic/tag/baz.html | 2 +- pelican/tests/output/basic/tag/foo.html | 2 +- pelican/tests/output/basic/tag/foobar.html | 2 +- pelican/tests/output/basic/tag/oh.html | 4 ++-- pelican/tests/output/basic/tag/yeah.html | 2 +- pelican/tests/output/basic/tags.html | 2 +- pelican/tests/output/basic/theme/css/reset.css | 2 +- .../output/basic/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt | 2 +- pelican/tests/output/basic/this-is-a-super-article.html | 2 +- pelican/tests/output/basic/unbelievable.html | 2 +- pelican/tests/output/custom/a-markdown-powered-article.html | 2 +- pelican/tests/output/custom/archives.html | 2 +- pelican/tests/output/custom/article-1.html | 2 +- pelican/tests/output/custom/article-2.html | 2 +- pelican/tests/output/custom/article-3.html | 2 +- pelican/tests/output/custom/author/alexis-metaireau.html | 2 +- pelican/tests/output/custom/author/alexis-metaireau2.html | 2 +- pelican/tests/output/custom/author/alexis-metaireau3.html | 2 +- pelican/tests/output/custom/authors.html | 2 +- pelican/tests/output/custom/categories.html | 2 +- pelican/tests/output/custom/category/bar.html | 2 +- pelican/tests/output/custom/category/cat1.html | 2 +- pelican/tests/output/custom/category/misc.html | 2 +- pelican/tests/output/custom/category/yeah.html | 2 +- .../output/custom/drafts/a-draft-article-without-date.html | 2 +- pelican/tests/output/custom/drafts/a-draft-article.html | 2 +- pelican/tests/output/custom/feeds/alexis-metaireau.atom.xml | 2 +- pelican/tests/output/custom/feeds/alexis-metaireau.rss.xml | 2 +- pelican/tests/output/custom/feeds/all-en.atom.xml | 2 +- pelican/tests/output/custom/feeds/all-fr.atom.xml | 2 +- pelican/tests/output/custom/feeds/all.atom.xml | 2 +- pelican/tests/output/custom/feeds/all.rss.xml | 2 +- pelican/tests/output/custom/feeds/bar.atom.xml | 2 +- pelican/tests/output/custom/feeds/bar.rss.xml | 2 +- pelican/tests/output/custom/feeds/cat1.atom.xml | 2 +- pelican/tests/output/custom/feeds/cat1.rss.xml | 2 +- pelican/tests/output/custom/feeds/misc.atom.xml | 2 +- pelican/tests/output/custom/feeds/misc.rss.xml | 2 +- pelican/tests/output/custom/feeds/yeah.atom.xml | 2 +- pelican/tests/output/custom/feeds/yeah.rss.xml | 2 +- pelican/tests/output/custom/filename_metadata-example.html | 2 +- pelican/tests/output/custom/index.html | 2 +- pelican/tests/output/custom/index2.html | 2 +- pelican/tests/output/custom/index3.html | 2 +- pelican/tests/output/custom/jinja2_template.html | 2 +- pelican/tests/output/custom/oh-yeah-fr.html | 2 +- pelican/tests/output/custom/oh-yeah.html | 2 +- pelican/tests/output/custom/override/index.html | 4 ++-- .../tests/output/custom/pages/this-is-a-test-hidden-page.html | 4 ++-- pelican/tests/output/custom/pages/this-is-a-test-page.html | 4 ++-- pelican/tests/output/custom/second-article-fr.html | 2 +- pelican/tests/output/custom/second-article.html | 2 +- pelican/tests/output/custom/tag/bar.html | 2 +- pelican/tests/output/custom/tag/baz.html | 2 +- pelican/tests/output/custom/tag/foo.html | 2 +- pelican/tests/output/custom/tag/foobar.html | 2 +- pelican/tests/output/custom/tag/oh.html | 4 ++-- pelican/tests/output/custom/tag/yeah.html | 2 +- pelican/tests/output/custom/tags.html | 2 +- pelican/tests/output/custom/theme/css/reset.css | 2 +- .../output/custom/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt | 2 +- pelican/tests/output/custom/this-is-a-super-article.html | 2 +- pelican/tests/output/custom/unbelievable.html | 2 +- pelican/tests/output/custom_locale/archives.html | 2 +- .../tests/output/custom_locale/author/alexis-metaireau.html | 2 +- .../tests/output/custom_locale/author/alexis-metaireau2.html | 2 +- .../tests/output/custom_locale/author/alexis-metaireau3.html | 2 +- pelican/tests/output/custom_locale/authors.html | 2 +- pelican/tests/output/custom_locale/categories.html | 2 +- pelican/tests/output/custom_locale/category/bar.html | 2 +- pelican/tests/output/custom_locale/category/cat1.html | 2 +- pelican/tests/output/custom_locale/category/misc.html | 2 +- pelican/tests/output/custom_locale/category/yeah.html | 2 +- .../custom_locale/drafts/a-draft-article-without-date.html | 2 +- .../tests/output/custom_locale/drafts/a-draft-article.html | 2 +- .../output/custom_locale/feeds/alexis-metaireau.atom.xml | 2 +- .../tests/output/custom_locale/feeds/alexis-metaireau.rss.xml | 2 +- pelican/tests/output/custom_locale/feeds/all-en.atom.xml | 2 +- pelican/tests/output/custom_locale/feeds/all-fr.atom.xml | 2 +- pelican/tests/output/custom_locale/feeds/all.atom.xml | 2 +- pelican/tests/output/custom_locale/feeds/all.rss.xml | 2 +- pelican/tests/output/custom_locale/feeds/bar.atom.xml | 2 +- pelican/tests/output/custom_locale/feeds/bar.rss.xml | 2 +- pelican/tests/output/custom_locale/feeds/cat1.atom.xml | 2 +- pelican/tests/output/custom_locale/feeds/cat1.rss.xml | 2 +- pelican/tests/output/custom_locale/feeds/misc.atom.xml | 2 +- pelican/tests/output/custom_locale/feeds/misc.rss.xml | 2 +- pelican/tests/output/custom_locale/feeds/yeah.atom.xml | 2 +- pelican/tests/output/custom_locale/feeds/yeah.rss.xml | 2 +- pelican/tests/output/custom_locale/index.html | 2 +- pelican/tests/output/custom_locale/index2.html | 2 +- pelican/tests/output/custom_locale/index3.html | 2 +- pelican/tests/output/custom_locale/jinja2_template.html | 2 +- pelican/tests/output/custom_locale/oh-yeah-fr.html | 2 +- pelican/tests/output/custom_locale/override/index.html | 4 ++-- .../custom_locale/pages/this-is-a-test-hidden-page.html | 4 ++-- .../tests/output/custom_locale/pages/this-is-a-test-page.html | 4 ++-- .../posts/2010/décembre/02/this-is-a-super-article/index.html | 2 +- .../posts/2010/octobre/15/unbelievable/index.html | 2 +- .../custom_locale/posts/2010/octobre/20/oh-yeah/index.html | 2 +- .../posts/2011/avril/20/a-markdown-powered-article/index.html | 2 +- .../custom_locale/posts/2011/février/17/article-1/index.html | 2 +- .../custom_locale/posts/2011/février/17/article-2/index.html | 2 +- .../custom_locale/posts/2011/février/17/article-3/index.html | 2 +- .../posts/2012/février/29/second-article/index.html | 2 +- .../2012/novembre/30/filename_metadata-example/index.html | 2 +- pelican/tests/output/custom_locale/second-article-fr.html | 2 +- pelican/tests/output/custom_locale/tag/bar.html | 2 +- pelican/tests/output/custom_locale/tag/baz.html | 2 +- pelican/tests/output/custom_locale/tag/foo.html | 2 +- pelican/tests/output/custom_locale/tag/foobar.html | 2 +- pelican/tests/output/custom_locale/tag/oh.html | 4 ++-- pelican/tests/output/custom_locale/tag/yeah.html | 2 +- pelican/tests/output/custom_locale/tags.html | 2 +- pelican/tests/output/custom_locale/theme/css/reset.css | 2 +- .../custom_locale/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt | 2 +- 149 files changed, 162 insertions(+), 162 deletions(-) diff --git a/pelican/tests/output/basic/a-markdown-powered-article.html b/pelican/tests/output/basic/a-markdown-powered-article.html index 0098ccac..3c2821f1 100644 --- a/pelican/tests/output/basic/a-markdown-powered-article.html +++ b/pelican/tests/output/basic/a-markdown-powered-article.html @@ -65,4 +65,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/archives.html b/pelican/tests/output/basic/archives.html index e3a6c7df..3218fe1d 100644 --- a/pelican/tests/output/basic/archives.html +++ b/pelican/tests/output/basic/archives.html @@ -67,4 +67,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/article-1.html b/pelican/tests/output/basic/article-1.html index 961ad390..91dcff19 100644 --- a/pelican/tests/output/basic/article-1.html +++ b/pelican/tests/output/basic/article-1.html @@ -64,4 +64,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/article-2.html b/pelican/tests/output/basic/article-2.html index e5389d35..e3ad5724 100644 --- a/pelican/tests/output/basic/article-2.html +++ b/pelican/tests/output/basic/article-2.html @@ -64,4 +64,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/article-3.html b/pelican/tests/output/basic/article-3.html index d23e5da2..2ec3f1e7 100644 --- a/pelican/tests/output/basic/article-3.html +++ b/pelican/tests/output/basic/article-3.html @@ -64,4 +64,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/author/alexis-metaireau.html b/pelican/tests/output/basic/author/alexis-metaireau.html index 12e05ec8..d682ab29 100644 --- a/pelican/tests/output/basic/author/alexis-metaireau.html +++ b/pelican/tests/output/basic/author/alexis-metaireau.html @@ -109,4 +109,4 @@ YEAH !

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/authors.html b/pelican/tests/output/basic/authors.html index cff1360b..86d2249a 100644 --- a/pelican/tests/output/basic/authors.html +++ b/pelican/tests/output/basic/authors.html @@ -49,4 +49,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/categories.html b/pelican/tests/output/basic/categories.html index cc54f4a3..86606fbe 100644 --- a/pelican/tests/output/basic/categories.html +++ b/pelican/tests/output/basic/categories.html @@ -52,4 +52,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/category/bar.html b/pelican/tests/output/basic/category/bar.html index 1f9c0d8d..c4f57bdd 100644 --- a/pelican/tests/output/basic/category/bar.html +++ b/pelican/tests/output/basic/category/bar.html @@ -65,4 +65,4 @@ YEAH !

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/category/cat1.html b/pelican/tests/output/basic/category/cat1.html index ca47821b..a291aae4 100644 --- a/pelican/tests/output/basic/category/cat1.html +++ b/pelican/tests/output/basic/category/cat1.html @@ -122,4 +122,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/category/misc.html b/pelican/tests/output/basic/category/misc.html index 58490001..fa786910 100644 --- a/pelican/tests/output/basic/category/misc.html +++ b/pelican/tests/output/basic/category/misc.html @@ -133,4 +133,4 @@ pelican.conf, it will …

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/category/yeah.html b/pelican/tests/output/basic/category/yeah.html index 815d42e4..caade72e 100644 --- a/pelican/tests/output/basic/category/yeah.html +++ b/pelican/tests/output/basic/category/yeah.html @@ -73,4 +73,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/drafts/a-draft-article-without-date.html b/pelican/tests/output/basic/drafts/a-draft-article-without-date.html index 5a2d367b..45bc00ec 100644 --- a/pelican/tests/output/basic/drafts/a-draft-article-without-date.html +++ b/pelican/tests/output/basic/drafts/a-draft-article-without-date.html @@ -34,7 +34,7 @@
- Published: + Published:

In misc.

@@ -65,4 +65,4 @@ listed anywhere else.

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/drafts/a-draft-article.html b/pelican/tests/output/basic/drafts/a-draft-article.html index a0bed241..9349064c 100644 --- a/pelican/tests/output/basic/drafts/a-draft-article.html +++ b/pelican/tests/output/basic/drafts/a-draft-article.html @@ -65,4 +65,4 @@ listed anywhere else.

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/alexis-metaireau.atom.xml b/pelican/tests/output/basic/feeds/alexis-metaireau.atom.xml index 8f9a85fa..a0306a0b 100644 --- a/pelican/tests/output/basic/feeds/alexis-metaireau.atom.xml +++ b/pelican/tests/output/basic/feeds/alexis-metaireau.atom.xml @@ -19,4 +19,4 @@ as well as <strong>inline markup</strong>.</p> YEAH !</p> <img alt="alternate text" src="/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/alexis-metaireau.rss.xml b/pelican/tests/output/basic/feeds/alexis-metaireau.rss.xml index 1af41d47..d4989286 100644 --- a/pelican/tests/output/basic/feeds/alexis-metaireau.rss.xml +++ b/pelican/tests/output/basic/feeds/alexis-metaireau.rss.xml @@ -7,4 +7,4 @@ as well as <strong>inline markup</strong>.</p> YEAH !</p> <img alt="alternate text" src="/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> -Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0000tag:None,2010-10-20:/oh-yeah.htmlbarohbaryeah \ No newline at end of file +Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0000tag:None,2010-10-20:/oh-yeah.htmlbarohbaryeah diff --git a/pelican/tests/output/basic/feeds/all-en.atom.xml b/pelican/tests/output/basic/feeds/all-en.atom.xml index 9c44c860..49c76c62 100644 --- a/pelican/tests/output/basic/feeds/all-en.atom.xml +++ b/pelican/tests/output/basic/feeds/all-en.atom.xml @@ -71,4 +71,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+00:002010-03-14T00:00:00+00:00tag:None,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/all-fr.atom.xml b/pelican/tests/output/basic/feeds/all-fr.atom.xml index 4ecf7534..bca3d2cb 100644 --- a/pelican/tests/output/basic/feeds/all-fr.atom.xml +++ b/pelican/tests/output/basic/feeds/all-fr.atom.xml @@ -1,4 +1,4 @@ A Pelican Blog/2012-02-29T00:00:00+00:00Deuxième article2012-02-29T00:00:00+00:002012-02-29T00:00:00+00:00tag:None,2012-02-29:/second-article-fr.html<p>Ceci est un article, en français.</p> Trop bien !2010-10-20T10:14:00+00:002010-10-20T10:14:00+00:00tag:None,2010-10-20:/oh-yeah-fr.html<p>Et voila du contenu en français</p> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/all.atom.xml b/pelican/tests/output/basic/feeds/all.atom.xml index e9dceb69..b2399afe 100644 --- a/pelican/tests/output/basic/feeds/all.atom.xml +++ b/pelican/tests/output/basic/feeds/all.atom.xml @@ -73,4 +73,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+00:002010-03-14T00:00:00+00:00tag:None,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/bar.atom.xml b/pelican/tests/output/basic/feeds/bar.atom.xml index edd1170a..93fff29c 100644 --- a/pelican/tests/output/basic/feeds/bar.atom.xml +++ b/pelican/tests/output/basic/feeds/bar.atom.xml @@ -5,4 +5,4 @@ YEAH !</p> <img alt="alternate text" src="/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/cat1.atom.xml b/pelican/tests/output/basic/feeds/cat1.atom.xml index 8516b95c..2f054a1c 100644 --- a/pelican/tests/output/basic/feeds/cat1.atom.xml +++ b/pelican/tests/output/basic/feeds/cat1.atom.xml @@ -4,4 +4,4 @@ <a href="/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00+00:002011-02-17T00:00:00+00:00tag:None,2011-02-17:/article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00+00:002011-02-17T00:00:00+00:00tag:None,2011-02-17:/article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00+00:002011-02-17T00:00:00+00:00tag:None,2011-02-17:/article-3.html<p>Article 3</p> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/misc.atom.xml b/pelican/tests/output/basic/feeds/misc.atom.xml index a307ac4e..9127b2a5 100644 --- a/pelican/tests/output/basic/feeds/misc.atom.xml +++ b/pelican/tests/output/basic/feeds/misc.atom.xml @@ -46,4 +46,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+00:002010-03-14T00:00:00+00:00tag:None,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/feeds/yeah.atom.xml b/pelican/tests/output/basic/feeds/yeah.atom.xml index 6f871915..6411bf6d 100644 --- a/pelican/tests/output/basic/feeds/yeah.atom.xml +++ b/pelican/tests/output/basic/feeds/yeah.atom.xml @@ -13,4 +13,4 @@ as well as <strong>inline markup</strong>.</p> </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> - \ No newline at end of file + diff --git a/pelican/tests/output/basic/filename_metadata-example.html b/pelican/tests/output/basic/filename_metadata-example.html index f3ae9cea..30da64fd 100644 --- a/pelican/tests/output/basic/filename_metadata-example.html +++ b/pelican/tests/output/basic/filename_metadata-example.html @@ -64,4 +64,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/index.html b/pelican/tests/output/basic/index.html index fd334d38..db95e29b 100644 --- a/pelican/tests/output/basic/index.html +++ b/pelican/tests/output/basic/index.html @@ -272,4 +272,4 @@ pelican.conf, it will …

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/oh-yeah-fr.html b/pelican/tests/output/basic/oh-yeah-fr.html index 3fdfeae9..388cc283 100644 --- a/pelican/tests/output/basic/oh-yeah-fr.html +++ b/pelican/tests/output/basic/oh-yeah-fr.html @@ -68,4 +68,4 @@ Translations: - \ No newline at end of file + diff --git a/pelican/tests/output/basic/oh-yeah.html b/pelican/tests/output/basic/oh-yeah.html index f8d3d227..186a3c84 100644 --- a/pelican/tests/output/basic/oh-yeah.html +++ b/pelican/tests/output/basic/oh-yeah.html @@ -76,4 +76,4 @@ YEAH !

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/override/index.html b/pelican/tests/output/basic/override/index.html index a74d802f..1b7c404b 100644 --- a/pelican/tests/output/basic/override/index.html +++ b/pelican/tests/output/basic/override/index.html @@ -24,7 +24,7 @@

Override url/save_as

- +

Test page which overrides save_as and url so that this page will be generated at a custom location.

@@ -48,4 +48,4 @@ at a custom location.

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/pages/this-is-a-test-hidden-page.html b/pelican/tests/output/basic/pages/this-is-a-test-hidden-page.html index 1c836201..fda32c01 100644 --- a/pelican/tests/output/basic/pages/this-is-a-test-hidden-page.html +++ b/pelican/tests/output/basic/pages/this-is-a-test-hidden-page.html @@ -24,7 +24,7 @@

This is a test hidden page

- +

This is great for things like error(404) pages Anyone can see this page but it's not linked to anywhere!

@@ -48,4 +48,4 @@ Anyone can see this page but it's not linked to anywhere!

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/pages/this-is-a-test-page.html b/pelican/tests/output/basic/pages/this-is-a-test-page.html index 372eff76..b79f424d 100644 --- a/pelican/tests/output/basic/pages/this-is-a-test-page.html +++ b/pelican/tests/output/basic/pages/this-is-a-test-page.html @@ -24,7 +24,7 @@

This is a test page

- +

Just an image.

alternate text wrong path since 'images' folder does not exist @@ -49,4 +49,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/second-article-fr.html b/pelican/tests/output/basic/second-article-fr.html index 514c5585..e70f16e5 100644 --- a/pelican/tests/output/basic/second-article-fr.html +++ b/pelican/tests/output/basic/second-article-fr.html @@ -68,4 +68,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/second-article.html b/pelican/tests/output/basic/second-article.html index 365f99cd..4c833a49 100644 --- a/pelican/tests/output/basic/second-article.html +++ b/pelican/tests/output/basic/second-article.html @@ -68,4 +68,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/tag/bar.html b/pelican/tests/output/basic/tag/bar.html index 047d772a..d2824c2e 100644 --- a/pelican/tests/output/basic/tag/bar.html +++ b/pelican/tests/output/basic/tag/bar.html @@ -121,4 +121,4 @@ YEAH !

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/tag/baz.html b/pelican/tests/output/basic/tag/baz.html index 51518620..01cb257e 100644 --- a/pelican/tests/output/basic/tag/baz.html +++ b/pelican/tests/output/basic/tag/baz.html @@ -64,4 +64,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/tag/foo.html b/pelican/tests/output/basic/tag/foo.html index 0214cf26..bdabf131 100644 --- a/pelican/tests/output/basic/tag/foo.html +++ b/pelican/tests/output/basic/tag/foo.html @@ -91,4 +91,4 @@ as well as inline markup.

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/tag/foobar.html b/pelican/tests/output/basic/tag/foobar.html index ab07e87f..00b72790 100644 --- a/pelican/tests/output/basic/tag/foobar.html +++ b/pelican/tests/output/basic/tag/foobar.html @@ -73,4 +73,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/tag/oh.html b/pelican/tests/output/basic/tag/oh.html index f3af2a2f..c675834b 100644 --- a/pelican/tests/output/basic/tag/oh.html +++ b/pelican/tests/output/basic/tag/oh.html @@ -24,7 +24,7 @@

Oh Oh Oh

- +

This page overrides the listening of the articles under the oh tag.

@@ -47,4 +47,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/tag/yeah.html b/pelican/tests/output/basic/tag/yeah.html index f04affa8..99806970 100644 --- a/pelican/tests/output/basic/tag/yeah.html +++ b/pelican/tests/output/basic/tag/yeah.html @@ -65,4 +65,4 @@ YEAH !

- \ No newline at end of file + diff --git a/pelican/tests/output/basic/tags.html b/pelican/tests/output/basic/tags.html index db5d6634..4d82ca7b 100644 --- a/pelican/tests/output/basic/tags.html +++ b/pelican/tests/output/basic/tags.html @@ -54,4 +54,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/theme/css/reset.css b/pelican/tests/output/basic/theme/css/reset.css index c88e6196..f5123cf6 100644 --- a/pelican/tests/output/basic/theme/css/reset.css +++ b/pelican/tests/output/basic/theme/css/reset.css @@ -49,4 +49,4 @@ del {text-decoration: line-through;} table { border-collapse: collapse; border-spacing: 0; -} \ No newline at end of file +} diff --git a/pelican/tests/output/basic/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt b/pelican/tests/output/basic/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt index 309fd710..c70bcad3 100644 --- a/pelican/tests/output/basic/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt +++ b/pelican/tests/output/basic/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt @@ -18,7 +18,7 @@ with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, +fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The diff --git a/pelican/tests/output/basic/this-is-a-super-article.html b/pelican/tests/output/basic/this-is-a-super-article.html index 6ac68664..52e0bf65 100644 --- a/pelican/tests/output/basic/this-is-a-super-article.html +++ b/pelican/tests/output/basic/this-is-a-super-article.html @@ -82,4 +82,4 @@ - \ No newline at end of file + diff --git a/pelican/tests/output/basic/unbelievable.html b/pelican/tests/output/basic/unbelievable.html index d87c31ea..710c8ff7 100644 --- a/pelican/tests/output/basic/unbelievable.html +++ b/pelican/tests/output/basic/unbelievable.html @@ -96,4 +96,4 @@ pelican.conf, it will have nothing in default.

- \ No newline at end of file + diff --git a/pelican/tests/output/custom/a-markdown-powered-article.html b/pelican/tests/output/custom/a-markdown-powered-article.html index 422421d8..3cf1deb7 100644 --- a/pelican/tests/output/custom/a-markdown-powered-article.html +++ b/pelican/tests/output/custom/a-markdown-powered-article.html @@ -111,4 +111,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/archives.html b/pelican/tests/output/custom/archives.html index 34c3f4cd..6cf7b82d 100644 --- a/pelican/tests/output/custom/archives.html +++ b/pelican/tests/output/custom/archives.html @@ -95,4 +95,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/article-1.html b/pelican/tests/output/custom/article-1.html index 226489ea..e28fb39b 100644 --- a/pelican/tests/output/custom/article-1.html +++ b/pelican/tests/output/custom/article-1.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/article-2.html b/pelican/tests/output/custom/article-2.html index 1a835849..8c33fe86 100644 --- a/pelican/tests/output/custom/article-2.html +++ b/pelican/tests/output/custom/article-2.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/article-3.html b/pelican/tests/output/custom/article-3.html index c3076e98..15862270 100644 --- a/pelican/tests/output/custom/article-3.html +++ b/pelican/tests/output/custom/article-3.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/author/alexis-metaireau.html b/pelican/tests/output/custom/author/alexis-metaireau.html index aef8c6e6..22a23340 100644 --- a/pelican/tests/output/custom/author/alexis-metaireau.html +++ b/pelican/tests/output/custom/author/alexis-metaireau.html @@ -171,4 +171,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/author/alexis-metaireau2.html b/pelican/tests/output/custom/author/alexis-metaireau2.html index 8d17eed5..e5f7e953 100644 --- a/pelican/tests/output/custom/author/alexis-metaireau2.html +++ b/pelican/tests/output/custom/author/alexis-metaireau2.html @@ -186,4 +186,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/author/alexis-metaireau3.html b/pelican/tests/output/custom/author/alexis-metaireau3.html index 48fe75ba..c5162737 100644 --- a/pelican/tests/output/custom/author/alexis-metaireau3.html +++ b/pelican/tests/output/custom/author/alexis-metaireau3.html @@ -136,4 +136,4 @@ pelican.conf, it will …

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/authors.html b/pelican/tests/output/custom/authors.html index de18662e..06919fb7 100644 --- a/pelican/tests/output/custom/authors.html +++ b/pelican/tests/output/custom/authors.html @@ -77,4 +77,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/categories.html b/pelican/tests/output/custom/categories.html index b558d389..34236cdb 100644 --- a/pelican/tests/output/custom/categories.html +++ b/pelican/tests/output/custom/categories.html @@ -80,4 +80,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/category/bar.html b/pelican/tests/output/custom/category/bar.html index 6f3e9f5b..ad1ef940 100644 --- a/pelican/tests/output/custom/category/bar.html +++ b/pelican/tests/output/custom/category/bar.html @@ -93,4 +93,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/category/cat1.html b/pelican/tests/output/custom/category/cat1.html index d9b1e41f..79428cd7 100644 --- a/pelican/tests/output/custom/category/cat1.html +++ b/pelican/tests/output/custom/category/cat1.html @@ -162,4 +162,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/category/misc.html b/pelican/tests/output/custom/category/misc.html index 7cc5bf9b..16c31252 100644 --- a/pelican/tests/output/custom/category/misc.html +++ b/pelican/tests/output/custom/category/misc.html @@ -173,4 +173,4 @@ pelican.conf, it will …

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/category/yeah.html b/pelican/tests/output/custom/category/yeah.html index 957c76ae..e919ddd5 100644 --- a/pelican/tests/output/custom/category/yeah.html +++ b/pelican/tests/output/custom/category/yeah.html @@ -101,4 +101,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/drafts/a-draft-article-without-date.html b/pelican/tests/output/custom/drafts/a-draft-article-without-date.html index 94d2c8e9..81137fc7 100644 --- a/pelican/tests/output/custom/drafts/a-draft-article-without-date.html +++ b/pelican/tests/output/custom/drafts/a-draft-article-without-date.html @@ -96,4 +96,4 @@ listed anywhere else.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/drafts/a-draft-article.html b/pelican/tests/output/custom/drafts/a-draft-article.html index c926c14f..260ccaf1 100644 --- a/pelican/tests/output/custom/drafts/a-draft-article.html +++ b/pelican/tests/output/custom/drafts/a-draft-article.html @@ -96,4 +96,4 @@ listed anywhere else.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/alexis-metaireau.atom.xml b/pelican/tests/output/custom/feeds/alexis-metaireau.atom.xml index f6cde37e..5bfb73d0 100644 --- a/pelican/tests/output/custom/feeds/alexis-metaireau.atom.xml +++ b/pelican/tests/output/custom/feeds/alexis-metaireau.atom.xml @@ -71,4 +71,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/alexis-metaireau.rss.xml b/pelican/tests/output/custom/feeds/alexis-metaireau.rss.xml index c13a742b..b5654682 100644 --- a/pelican/tests/output/custom/feeds/alexis-metaireau.rss.xml +++ b/pelican/tests/output/custom/feeds/alexis-metaireau.rss.xml @@ -26,4 +26,4 @@ YEAH !</p> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will …</p></div>Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:/unbelievable.htmlmiscThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> -Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc \ No newline at end of file +Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc diff --git a/pelican/tests/output/custom/feeds/all-en.atom.xml b/pelican/tests/output/custom/feeds/all-en.atom.xml index 703f56f0..1aac415a 100644 --- a/pelican/tests/output/custom/feeds/all-en.atom.xml +++ b/pelican/tests/output/custom/feeds/all-en.atom.xml @@ -71,4 +71,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/all-fr.atom.xml b/pelican/tests/output/custom/feeds/all-fr.atom.xml index 39565ca6..68ebd738 100644 --- a/pelican/tests/output/custom/feeds/all-fr.atom.xml +++ b/pelican/tests/output/custom/feeds/all-fr.atom.xml @@ -1,4 +1,4 @@ Alexis' loghttp://blog.notmyidea.org/2012-02-29T00:00:00+01:00A personal blog.Deuxième article2012-02-29T00:00:00+01:002012-02-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-02-29:/second-article-fr.html<p>Ceci est un article, en français.</p> Trop bien !2010-10-20T10:14:00+02:002010-10-20T10:14:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-20:/oh-yeah-fr.html<p>Et voila du contenu en français</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/all.atom.xml b/pelican/tests/output/custom/feeds/all.atom.xml index de5e733d..dbe37a32 100644 --- a/pelican/tests/output/custom/feeds/all.atom.xml +++ b/pelican/tests/output/custom/feeds/all.atom.xml @@ -73,4 +73,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/all.rss.xml b/pelican/tests/output/custom/feeds/all.rss.xml index a8d984fa..45a8dc58 100644 --- a/pelican/tests/output/custom/feeds/all.rss.xml +++ b/pelican/tests/output/custom/feeds/all.rss.xml @@ -28,4 +28,4 @@ YEAH !</p> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will …</p></div>Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:/unbelievable.htmlmiscThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> -Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc \ No newline at end of file +Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc diff --git a/pelican/tests/output/custom/feeds/bar.atom.xml b/pelican/tests/output/custom/feeds/bar.atom.xml index 002de037..d79aad2d 100644 --- a/pelican/tests/output/custom/feeds/bar.atom.xml +++ b/pelican/tests/output/custom/feeds/bar.atom.xml @@ -5,4 +5,4 @@ YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/bar.rss.xml b/pelican/tests/output/custom/feeds/bar.rss.xml index 53035e71..c993753a 100644 --- a/pelican/tests/output/custom/feeds/bar.rss.xml +++ b/pelican/tests/output/custom/feeds/bar.rss.xml @@ -5,4 +5,4 @@ YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> -Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0200tag:blog.notmyidea.org,2010-10-20:/oh-yeah.htmlbarohbaryeah \ No newline at end of file +Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0200tag:blog.notmyidea.org,2010-10-20:/oh-yeah.htmlbarohbaryeah diff --git a/pelican/tests/output/custom/feeds/cat1.atom.xml b/pelican/tests/output/custom/feeds/cat1.atom.xml index e8ed355b..c44ac595 100644 --- a/pelican/tests/output/custom/feeds/cat1.atom.xml +++ b/pelican/tests/output/custom/feeds/cat1.atom.xml @@ -4,4 +4,4 @@ <a href="http://blog.notmyidea.org/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00+01:002011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:/article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00+01:002011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:/article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00+01:002011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:/article-3.html<p>Article 3</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/cat1.rss.xml b/pelican/tests/output/custom/feeds/cat1.rss.xml index 9951b293..a6ca0b53 100644 --- a/pelican/tests/output/custom/feeds/cat1.rss.xml +++ b/pelican/tests/output/custom/feeds/cat1.rss.xml @@ -4,4 +4,4 @@ <a href="http://blog.notmyidea.org/unbelievable.html">a file-relative link to unbelievable</a></p>Alexis MétaireauWed, 20 Apr 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-04-20:/a-markdown-powered-article.htmlcat1Article 1http://blog.notmyidea.org/article-1.html<p>Article 1</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/article-1.htmlcat1Article 2http://blog.notmyidea.org/article-2.html<p>Article 2</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/article-2.htmlcat1Article 3http://blog.notmyidea.org/article-3.html<p>Article 3</p> -Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/article-3.htmlcat1 \ No newline at end of file +Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/article-3.htmlcat1 diff --git a/pelican/tests/output/custom/feeds/misc.atom.xml b/pelican/tests/output/custom/feeds/misc.atom.xml index a260f67d..117c2bc2 100644 --- a/pelican/tests/output/custom/feeds/misc.atom.xml +++ b/pelican/tests/output/custom/feeds/misc.atom.xml @@ -46,4 +46,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/misc.rss.xml b/pelican/tests/output/custom/feeds/misc.rss.xml index 828eae62..03b3b2fe 100644 --- a/pelican/tests/output/custom/feeds/misc.rss.xml +++ b/pelican/tests/output/custom/feeds/misc.rss.xml @@ -13,4 +13,4 @@ <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will …</p></div>Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:/unbelievable.htmlmiscThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> -Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc \ No newline at end of file +Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc diff --git a/pelican/tests/output/custom/feeds/yeah.atom.xml b/pelican/tests/output/custom/feeds/yeah.atom.xml index 127ab590..0e5e8858 100644 --- a/pelican/tests/output/custom/feeds/yeah.atom.xml +++ b/pelican/tests/output/custom/feeds/yeah.atom.xml @@ -13,4 +13,4 @@ as well as <strong>inline markup</strong>.</p> </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> - \ No newline at end of file + diff --git a/pelican/tests/output/custom/feeds/yeah.rss.xml b/pelican/tests/output/custom/feeds/yeah.rss.xml index 98b820ec..be592f11 100644 --- a/pelican/tests/output/custom/feeds/yeah.rss.xml +++ b/pelican/tests/output/custom/feeds/yeah.rss.xml @@ -1,4 +1,4 @@ Alexis' log - yeahhttp://blog.notmyidea.org/A personal blog.Sun, 17 Nov 2013 23:29:00 +0100This is a super article !http://blog.notmyidea.org/this-is-a-super-article.html<p class="first last">Multi-line metadata should be supported as well as <strong>inline markup</strong>.</p> -Alexis MétaireauThu, 02 Dec 2010 10:14:00 +0100tag:blog.notmyidea.org,2010-12-02:/this-is-a-super-article.htmlyeahfoobarfoobar \ No newline at end of file +Alexis MétaireauThu, 02 Dec 2010 10:14:00 +0100tag:blog.notmyidea.org,2010-12-02:/this-is-a-super-article.htmlyeahfoobarfoobar diff --git a/pelican/tests/output/custom/filename_metadata-example.html b/pelican/tests/output/custom/filename_metadata-example.html index 70d41179..8bc1babb 100644 --- a/pelican/tests/output/custom/filename_metadata-example.html +++ b/pelican/tests/output/custom/filename_metadata-example.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/index.html b/pelican/tests/output/custom/index.html index 6c4d7a94..d97eb4c4 100644 --- a/pelican/tests/output/custom/index.html +++ b/pelican/tests/output/custom/index.html @@ -171,4 +171,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/index2.html b/pelican/tests/output/custom/index2.html index 043f8c33..11943a88 100644 --- a/pelican/tests/output/custom/index2.html +++ b/pelican/tests/output/custom/index2.html @@ -186,4 +186,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/index3.html b/pelican/tests/output/custom/index3.html index f8ebaac0..72ac69c6 100644 --- a/pelican/tests/output/custom/index3.html +++ b/pelican/tests/output/custom/index3.html @@ -136,4 +136,4 @@ pelican.conf, it will …

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/jinja2_template.html b/pelican/tests/output/custom/jinja2_template.html index 27a6df8e..71a9e63a 100644 --- a/pelican/tests/output/custom/jinja2_template.html +++ b/pelican/tests/output/custom/jinja2_template.html @@ -72,4 +72,4 @@ Some text }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/oh-yeah-fr.html b/pelican/tests/output/custom/oh-yeah-fr.html index f30c9b63..555af6c0 100644 --- a/pelican/tests/output/custom/oh-yeah-fr.html +++ b/pelican/tests/output/custom/oh-yeah-fr.html @@ -114,4 +114,4 @@ Translations: }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/oh-yeah.html b/pelican/tests/output/custom/oh-yeah.html index 20b90351..661d0153 100644 --- a/pelican/tests/output/custom/oh-yeah.html +++ b/pelican/tests/output/custom/oh-yeah.html @@ -119,4 +119,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/override/index.html b/pelican/tests/output/custom/override/index.html index 9d1c4f46..09493938 100644 --- a/pelican/tests/output/custom/override/index.html +++ b/pelican/tests/output/custom/override/index.html @@ -28,7 +28,7 @@

Override url/save_as

- +

Test page which overrides save_as and url so that this page will be generated at a custom location.

@@ -76,4 +76,4 @@ at a custom location.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/pages/this-is-a-test-hidden-page.html b/pelican/tests/output/custom/pages/this-is-a-test-hidden-page.html index bd0d03ed..6eb578c9 100644 --- a/pelican/tests/output/custom/pages/this-is-a-test-hidden-page.html +++ b/pelican/tests/output/custom/pages/this-is-a-test-hidden-page.html @@ -28,7 +28,7 @@

This is a test hidden page

- +

This is great for things like error(404) pages Anyone can see this page but it's not linked to anywhere!

@@ -76,4 +76,4 @@ Anyone can see this page but it's not linked to anywhere!

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/pages/this-is-a-test-page.html b/pelican/tests/output/custom/pages/this-is-a-test-page.html index 16d17c3b..db977694 100644 --- a/pelican/tests/output/custom/pages/this-is-a-test-page.html +++ b/pelican/tests/output/custom/pages/this-is-a-test-page.html @@ -28,7 +28,7 @@

This is a test page

- +

Just an image.

alternate text wrong path since 'images' folder does not exist @@ -77,4 +77,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/second-article-fr.html b/pelican/tests/output/custom/second-article-fr.html index ff7af42d..27638737 100644 --- a/pelican/tests/output/custom/second-article-fr.html +++ b/pelican/tests/output/custom/second-article-fr.html @@ -114,4 +114,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/second-article.html b/pelican/tests/output/custom/second-article.html index a71df8cf..2ed7c822 100644 --- a/pelican/tests/output/custom/second-article.html +++ b/pelican/tests/output/custom/second-article.html @@ -114,4 +114,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/tag/bar.html b/pelican/tests/output/custom/tag/bar.html index 719ea12a..bc949e11 100644 --- a/pelican/tests/output/custom/tag/bar.html +++ b/pelican/tests/output/custom/tag/bar.html @@ -152,4 +152,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/tag/baz.html b/pelican/tests/output/custom/tag/baz.html index 048dc5ce..bb61b787 100644 --- a/pelican/tests/output/custom/tag/baz.html +++ b/pelican/tests/output/custom/tag/baz.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/tag/foo.html b/pelican/tests/output/custom/tag/foo.html index 637bce0b..4edfe432 100644 --- a/pelican/tests/output/custom/tag/foo.html +++ b/pelican/tests/output/custom/tag/foo.html @@ -122,4 +122,4 @@ as well as inline markup.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/tag/foobar.html b/pelican/tests/output/custom/tag/foobar.html index 296ee098..cebd52f4 100644 --- a/pelican/tests/output/custom/tag/foobar.html +++ b/pelican/tests/output/custom/tag/foobar.html @@ -101,4 +101,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/tag/oh.html b/pelican/tests/output/custom/tag/oh.html index 4a7ce439..4723075f 100644 --- a/pelican/tests/output/custom/tag/oh.html +++ b/pelican/tests/output/custom/tag/oh.html @@ -28,7 +28,7 @@

Oh Oh Oh

- +

This page overrides the listening of the articles under the oh tag.

@@ -75,4 +75,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/tag/yeah.html b/pelican/tests/output/custom/tag/yeah.html index 78618480..c3e3bb4a 100644 --- a/pelican/tests/output/custom/tag/yeah.html +++ b/pelican/tests/output/custom/tag/yeah.html @@ -93,4 +93,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/tags.html b/pelican/tests/output/custom/tags.html index 1a8ef572..17feabf9 100644 --- a/pelican/tests/output/custom/tags.html +++ b/pelican/tests/output/custom/tags.html @@ -82,4 +82,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/theme/css/reset.css b/pelican/tests/output/custom/theme/css/reset.css index c88e6196..f5123cf6 100644 --- a/pelican/tests/output/custom/theme/css/reset.css +++ b/pelican/tests/output/custom/theme/css/reset.css @@ -49,4 +49,4 @@ del {text-decoration: line-through;} table { border-collapse: collapse; border-spacing: 0; -} \ No newline at end of file +} diff --git a/pelican/tests/output/custom/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt b/pelican/tests/output/custom/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt index 309fd710..c70bcad3 100644 --- a/pelican/tests/output/custom/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt +++ b/pelican/tests/output/custom/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt @@ -18,7 +18,7 @@ with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, +fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The diff --git a/pelican/tests/output/custom/this-is-a-super-article.html b/pelican/tests/output/custom/this-is-a-super-article.html index ab9dc16f..565d9f3f 100644 --- a/pelican/tests/output/custom/this-is-a-super-article.html +++ b/pelican/tests/output/custom/this-is-a-super-article.html @@ -125,4 +125,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom/unbelievable.html b/pelican/tests/output/custom/unbelievable.html index a7ad0efa..6153392e 100644 --- a/pelican/tests/output/custom/unbelievable.html +++ b/pelican/tests/output/custom/unbelievable.html @@ -142,4 +142,4 @@ pelican.conf, it will have nothing in default.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/archives.html b/pelican/tests/output/custom_locale/archives.html index 25ef1c6c..8b07609d 100644 --- a/pelican/tests/output/custom_locale/archives.html +++ b/pelican/tests/output/custom_locale/archives.html @@ -95,4 +95,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/author/alexis-metaireau.html b/pelican/tests/output/custom_locale/author/alexis-metaireau.html index df76ccf6..86ee7416 100644 --- a/pelican/tests/output/custom_locale/author/alexis-metaireau.html +++ b/pelican/tests/output/custom_locale/author/alexis-metaireau.html @@ -171,4 +171,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/author/alexis-metaireau2.html b/pelican/tests/output/custom_locale/author/alexis-metaireau2.html index 42a929d0..cf332f97 100644 --- a/pelican/tests/output/custom_locale/author/alexis-metaireau2.html +++ b/pelican/tests/output/custom_locale/author/alexis-metaireau2.html @@ -186,4 +186,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/author/alexis-metaireau3.html b/pelican/tests/output/custom_locale/author/alexis-metaireau3.html index 941cdc46..dff225d2 100644 --- a/pelican/tests/output/custom_locale/author/alexis-metaireau3.html +++ b/pelican/tests/output/custom_locale/author/alexis-metaireau3.html @@ -136,4 +136,4 @@ pelican.conf, it will …

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/authors.html b/pelican/tests/output/custom_locale/authors.html index 0907ff7c..7cac21cc 100644 --- a/pelican/tests/output/custom_locale/authors.html +++ b/pelican/tests/output/custom_locale/authors.html @@ -77,4 +77,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/categories.html b/pelican/tests/output/custom_locale/categories.html index 01dc680a..3b102a03 100644 --- a/pelican/tests/output/custom_locale/categories.html +++ b/pelican/tests/output/custom_locale/categories.html @@ -80,4 +80,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/category/bar.html b/pelican/tests/output/custom_locale/category/bar.html index d3dc29de..644a611c 100644 --- a/pelican/tests/output/custom_locale/category/bar.html +++ b/pelican/tests/output/custom_locale/category/bar.html @@ -93,4 +93,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/category/cat1.html b/pelican/tests/output/custom_locale/category/cat1.html index 5278242c..0fe47339 100644 --- a/pelican/tests/output/custom_locale/category/cat1.html +++ b/pelican/tests/output/custom_locale/category/cat1.html @@ -162,4 +162,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/category/misc.html b/pelican/tests/output/custom_locale/category/misc.html index 82a77efb..b300e98f 100644 --- a/pelican/tests/output/custom_locale/category/misc.html +++ b/pelican/tests/output/custom_locale/category/misc.html @@ -173,4 +173,4 @@ pelican.conf, it will …

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/category/yeah.html b/pelican/tests/output/custom_locale/category/yeah.html index f0dff1b6..afa3c4dd 100644 --- a/pelican/tests/output/custom_locale/category/yeah.html +++ b/pelican/tests/output/custom_locale/category/yeah.html @@ -101,4 +101,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/drafts/a-draft-article-without-date.html b/pelican/tests/output/custom_locale/drafts/a-draft-article-without-date.html index 788f01a3..114aac6c 100644 --- a/pelican/tests/output/custom_locale/drafts/a-draft-article-without-date.html +++ b/pelican/tests/output/custom_locale/drafts/a-draft-article-without-date.html @@ -96,4 +96,4 @@ listed anywhere else.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/drafts/a-draft-article.html b/pelican/tests/output/custom_locale/drafts/a-draft-article.html index bd54bc56..406fbe36 100644 --- a/pelican/tests/output/custom_locale/drafts/a-draft-article.html +++ b/pelican/tests/output/custom_locale/drafts/a-draft-article.html @@ -96,4 +96,4 @@ listed anywhere else.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/alexis-metaireau.atom.xml b/pelican/tests/output/custom_locale/feeds/alexis-metaireau.atom.xml index d52de6f9..85b63173 100644 --- a/pelican/tests/output/custom_locale/feeds/alexis-metaireau.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/alexis-metaireau.atom.xml @@ -71,4 +71,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/alexis-metaireau.rss.xml b/pelican/tests/output/custom_locale/feeds/alexis-metaireau.rss.xml index 4d9f5165..f383a84d 100644 --- a/pelican/tests/output/custom_locale/feeds/alexis-metaireau.rss.xml +++ b/pelican/tests/output/custom_locale/feeds/alexis-metaireau.rss.xml @@ -26,4 +26,4 @@ YEAH !</p> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will …</p></div>Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:/posts/2010/octobre/15/unbelievable/miscThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> -Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc \ No newline at end of file +Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc diff --git a/pelican/tests/output/custom_locale/feeds/all-en.atom.xml b/pelican/tests/output/custom_locale/feeds/all-en.atom.xml index 974c63b3..974b4279 100644 --- a/pelican/tests/output/custom_locale/feeds/all-en.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/all-en.atom.xml @@ -71,4 +71,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/all-fr.atom.xml b/pelican/tests/output/custom_locale/feeds/all-fr.atom.xml index cfd6eeb2..f44b17f2 100644 --- a/pelican/tests/output/custom_locale/feeds/all-fr.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/all-fr.atom.xml @@ -1,4 +1,4 @@ Alexis' loghttp://blog.notmyidea.org/2012-02-29T00:00:00+01:00Deuxième article2012-02-29T00:00:00+01:002012-02-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-02-29:/second-article-fr.html<p>Ceci est un article, en français.</p> Trop bien !2010-10-20T10:14:00+02:002010-10-20T10:14:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-20:/oh-yeah-fr.html<p>Et voila du contenu en français</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/all.atom.xml b/pelican/tests/output/custom_locale/feeds/all.atom.xml index e1063591..c2a5ef38 100644 --- a/pelican/tests/output/custom_locale/feeds/all.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/all.atom.xml @@ -73,4 +73,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/all.rss.xml b/pelican/tests/output/custom_locale/feeds/all.rss.xml index 442fc1ab..9642bef9 100644 --- a/pelican/tests/output/custom_locale/feeds/all.rss.xml +++ b/pelican/tests/output/custom_locale/feeds/all.rss.xml @@ -28,4 +28,4 @@ YEAH !</p> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will …</p></div>Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:/posts/2010/octobre/15/unbelievable/miscThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> -Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc \ No newline at end of file +Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc diff --git a/pelican/tests/output/custom_locale/feeds/bar.atom.xml b/pelican/tests/output/custom_locale/feeds/bar.atom.xml index d4467ea7..f3d8cc1e 100644 --- a/pelican/tests/output/custom_locale/feeds/bar.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/bar.atom.xml @@ -5,4 +5,4 @@ YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/bar.rss.xml b/pelican/tests/output/custom_locale/feeds/bar.rss.xml index d17d7703..71130b31 100644 --- a/pelican/tests/output/custom_locale/feeds/bar.rss.xml +++ b/pelican/tests/output/custom_locale/feeds/bar.rss.xml @@ -5,4 +5,4 @@ YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> -Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0200tag:blog.notmyidea.org,2010-10-20:/posts/2010/octobre/20/oh-yeah/barohbaryeah \ No newline at end of file +Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0200tag:blog.notmyidea.org,2010-10-20:/posts/2010/octobre/20/oh-yeah/barohbaryeah diff --git a/pelican/tests/output/custom_locale/feeds/cat1.atom.xml b/pelican/tests/output/custom_locale/feeds/cat1.atom.xml index 87a822e5..9a72b398 100644 --- a/pelican/tests/output/custom_locale/feeds/cat1.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/cat1.atom.xml @@ -4,4 +4,4 @@ <a href="http://blog.notmyidea.org/posts/2010/octobre/15/unbelievable/">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00+01:002011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:/posts/2011/février/17/article-1/<p>Article 1</p> Article 22011-02-17T00:00:00+01:002011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:/posts/2011/février/17/article-2/<p>Article 2</p> Article 32011-02-17T00:00:00+01:002011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:/posts/2011/février/17/article-3/<p>Article 3</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/cat1.rss.xml b/pelican/tests/output/custom_locale/feeds/cat1.rss.xml index 6b328fda..c16b8092 100644 --- a/pelican/tests/output/custom_locale/feeds/cat1.rss.xml +++ b/pelican/tests/output/custom_locale/feeds/cat1.rss.xml @@ -4,4 +4,4 @@ <a href="http://blog.notmyidea.org/posts/2010/octobre/15/unbelievable/">a file-relative link to unbelievable</a></p>Alexis MétaireauWed, 20 Apr 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-04-20:/posts/2011/avril/20/a-markdown-powered-article/cat1Article 1http://blog.notmyidea.org/posts/2011/f%C3%A9vrier/17/article-1/<p>Article 1</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/posts/2011/février/17/article-1/cat1Article 2http://blog.notmyidea.org/posts/2011/f%C3%A9vrier/17/article-2/<p>Article 2</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/posts/2011/février/17/article-2/cat1Article 3http://blog.notmyidea.org/posts/2011/f%C3%A9vrier/17/article-3/<p>Article 3</p> -Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/posts/2011/février/17/article-3/cat1 \ No newline at end of file +Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:/posts/2011/février/17/article-3/cat1 diff --git a/pelican/tests/output/custom_locale/feeds/misc.atom.xml b/pelican/tests/output/custom_locale/feeds/misc.atom.xml index 2e46b473..4898ab84 100644 --- a/pelican/tests/output/custom_locale/feeds/misc.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/misc.atom.xml @@ -46,4 +46,4 @@ pelican.conf, it will have nothing in default.</p> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:002010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/misc.rss.xml b/pelican/tests/output/custom_locale/feeds/misc.rss.xml index 01c24157..d1493ae8 100644 --- a/pelican/tests/output/custom_locale/feeds/misc.rss.xml +++ b/pelican/tests/output/custom_locale/feeds/misc.rss.xml @@ -13,4 +13,4 @@ <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will …</p></div>Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:/posts/2010/octobre/15/unbelievable/miscThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> -Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc \ No newline at end of file +Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:/tag/baz.htmlmisc diff --git a/pelican/tests/output/custom_locale/feeds/yeah.atom.xml b/pelican/tests/output/custom_locale/feeds/yeah.atom.xml index 6f2e5f82..f316ada5 100644 --- a/pelican/tests/output/custom_locale/feeds/yeah.atom.xml +++ b/pelican/tests/output/custom_locale/feeds/yeah.atom.xml @@ -13,4 +13,4 @@ as well as <strong>inline markup</strong>.</p> </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/feeds/yeah.rss.xml b/pelican/tests/output/custom_locale/feeds/yeah.rss.xml index b7fb81f8..a0d0ba28 100644 --- a/pelican/tests/output/custom_locale/feeds/yeah.rss.xml +++ b/pelican/tests/output/custom_locale/feeds/yeah.rss.xml @@ -1,4 +1,4 @@ Alexis' log - yeahhttp://blog.notmyidea.org/Sun, 17 Nov 2013 23:29:00 +0100This is a super article !http://blog.notmyidea.org/posts/2010/d%C3%A9cembre/02/this-is-a-super-article/<p class="first last">Multi-line metadata should be supported as well as <strong>inline markup</strong>.</p> -Alexis MétaireauThu, 02 Dec 2010 10:14:00 +0100tag:blog.notmyidea.org,2010-12-02:/posts/2010/décembre/02/this-is-a-super-article/yeahfoobarfoobar \ No newline at end of file +Alexis MétaireauThu, 02 Dec 2010 10:14:00 +0100tag:blog.notmyidea.org,2010-12-02:/posts/2010/décembre/02/this-is-a-super-article/yeahfoobarfoobar diff --git a/pelican/tests/output/custom_locale/index.html b/pelican/tests/output/custom_locale/index.html index 054011cc..37bfa0ac 100644 --- a/pelican/tests/output/custom_locale/index.html +++ b/pelican/tests/output/custom_locale/index.html @@ -171,4 +171,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/index2.html b/pelican/tests/output/custom_locale/index2.html index fa2c4d2d..871fd594 100644 --- a/pelican/tests/output/custom_locale/index2.html +++ b/pelican/tests/output/custom_locale/index2.html @@ -186,4 +186,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/index3.html b/pelican/tests/output/custom_locale/index3.html index 71ccb4b1..e3bbdffd 100644 --- a/pelican/tests/output/custom_locale/index3.html +++ b/pelican/tests/output/custom_locale/index3.html @@ -136,4 +136,4 @@ pelican.conf, it will …

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/jinja2_template.html b/pelican/tests/output/custom_locale/jinja2_template.html index 01957524..c4bcf019 100644 --- a/pelican/tests/output/custom_locale/jinja2_template.html +++ b/pelican/tests/output/custom_locale/jinja2_template.html @@ -72,4 +72,4 @@ Some text }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/oh-yeah-fr.html b/pelican/tests/output/custom_locale/oh-yeah-fr.html index 01c7800f..02d30117 100644 --- a/pelican/tests/output/custom_locale/oh-yeah-fr.html +++ b/pelican/tests/output/custom_locale/oh-yeah-fr.html @@ -114,4 +114,4 @@ Translations: }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/override/index.html b/pelican/tests/output/custom_locale/override/index.html index a5fcbe04..e1212e43 100644 --- a/pelican/tests/output/custom_locale/override/index.html +++ b/pelican/tests/output/custom_locale/override/index.html @@ -28,7 +28,7 @@

Override url/save_as

- +

Test page which overrides save_as and url so that this page will be generated at a custom location.

@@ -76,4 +76,4 @@ at a custom location.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/pages/this-is-a-test-hidden-page.html b/pelican/tests/output/custom_locale/pages/this-is-a-test-hidden-page.html index 3e33e3fc..5ba42b3f 100644 --- a/pelican/tests/output/custom_locale/pages/this-is-a-test-hidden-page.html +++ b/pelican/tests/output/custom_locale/pages/this-is-a-test-hidden-page.html @@ -28,7 +28,7 @@

This is a test hidden page

- +

This is great for things like error(404) pages Anyone can see this page but it's not linked to anywhere!

@@ -76,4 +76,4 @@ Anyone can see this page but it's not linked to anywhere!

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/pages/this-is-a-test-page.html b/pelican/tests/output/custom_locale/pages/this-is-a-test-page.html index e4f1d60b..83aaddb0 100644 --- a/pelican/tests/output/custom_locale/pages/this-is-a-test-page.html +++ b/pelican/tests/output/custom_locale/pages/this-is-a-test-page.html @@ -28,7 +28,7 @@

This is a test page

- +

Just an image.

alternate text wrong path since 'images' folder does not exist @@ -77,4 +77,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2010/décembre/02/this-is-a-super-article/index.html b/pelican/tests/output/custom_locale/posts/2010/décembre/02/this-is-a-super-article/index.html index 4b522248..33866221 100644 --- a/pelican/tests/output/custom_locale/posts/2010/décembre/02/this-is-a-super-article/index.html +++ b/pelican/tests/output/custom_locale/posts/2010/décembre/02/this-is-a-super-article/index.html @@ -125,4 +125,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2010/octobre/15/unbelievable/index.html b/pelican/tests/output/custom_locale/posts/2010/octobre/15/unbelievable/index.html index f27464f8..ef9994c6 100644 --- a/pelican/tests/output/custom_locale/posts/2010/octobre/15/unbelievable/index.html +++ b/pelican/tests/output/custom_locale/posts/2010/octobre/15/unbelievable/index.html @@ -142,4 +142,4 @@ pelican.conf, it will have nothing in default.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2010/octobre/20/oh-yeah/index.html b/pelican/tests/output/custom_locale/posts/2010/octobre/20/oh-yeah/index.html index b47732b7..07332310 100644 --- a/pelican/tests/output/custom_locale/posts/2010/octobre/20/oh-yeah/index.html +++ b/pelican/tests/output/custom_locale/posts/2010/octobre/20/oh-yeah/index.html @@ -119,4 +119,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2011/avril/20/a-markdown-powered-article/index.html b/pelican/tests/output/custom_locale/posts/2011/avril/20/a-markdown-powered-article/index.html index 80e57bc3..5410e9d1 100644 --- a/pelican/tests/output/custom_locale/posts/2011/avril/20/a-markdown-powered-article/index.html +++ b/pelican/tests/output/custom_locale/posts/2011/avril/20/a-markdown-powered-article/index.html @@ -111,4 +111,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2011/février/17/article-1/index.html b/pelican/tests/output/custom_locale/posts/2011/février/17/article-1/index.html index c427e2c7..d4afa8b2 100644 --- a/pelican/tests/output/custom_locale/posts/2011/février/17/article-1/index.html +++ b/pelican/tests/output/custom_locale/posts/2011/février/17/article-1/index.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2011/février/17/article-2/index.html b/pelican/tests/output/custom_locale/posts/2011/février/17/article-2/index.html index 88c7adf2..2d849548 100644 --- a/pelican/tests/output/custom_locale/posts/2011/février/17/article-2/index.html +++ b/pelican/tests/output/custom_locale/posts/2011/février/17/article-2/index.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2011/février/17/article-3/index.html b/pelican/tests/output/custom_locale/posts/2011/février/17/article-3/index.html index 257fb6dd..c6b03cc2 100644 --- a/pelican/tests/output/custom_locale/posts/2011/février/17/article-3/index.html +++ b/pelican/tests/output/custom_locale/posts/2011/février/17/article-3/index.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2012/février/29/second-article/index.html b/pelican/tests/output/custom_locale/posts/2012/février/29/second-article/index.html index 3b3bd10a..a5a12bc9 100644 --- a/pelican/tests/output/custom_locale/posts/2012/février/29/second-article/index.html +++ b/pelican/tests/output/custom_locale/posts/2012/février/29/second-article/index.html @@ -114,4 +114,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/posts/2012/novembre/30/filename_metadata-example/index.html b/pelican/tests/output/custom_locale/posts/2012/novembre/30/filename_metadata-example/index.html index 2618f705..848a0431 100644 --- a/pelican/tests/output/custom_locale/posts/2012/novembre/30/filename_metadata-example/index.html +++ b/pelican/tests/output/custom_locale/posts/2012/novembre/30/filename_metadata-example/index.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/second-article-fr.html b/pelican/tests/output/custom_locale/second-article-fr.html index 7edf7710..51ee3977 100644 --- a/pelican/tests/output/custom_locale/second-article-fr.html +++ b/pelican/tests/output/custom_locale/second-article-fr.html @@ -114,4 +114,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/tag/bar.html b/pelican/tests/output/custom_locale/tag/bar.html index e0e0487f..a4bda96f 100644 --- a/pelican/tests/output/custom_locale/tag/bar.html +++ b/pelican/tests/output/custom_locale/tag/bar.html @@ -152,4 +152,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/tag/baz.html b/pelican/tests/output/custom_locale/tag/baz.html index 7fe3b54c..a27bc92e 100644 --- a/pelican/tests/output/custom_locale/tag/baz.html +++ b/pelican/tests/output/custom_locale/tag/baz.html @@ -110,4 +110,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/tag/foo.html b/pelican/tests/output/custom_locale/tag/foo.html index a31e348b..736fa5b8 100644 --- a/pelican/tests/output/custom_locale/tag/foo.html +++ b/pelican/tests/output/custom_locale/tag/foo.html @@ -122,4 +122,4 @@ as well as inline markup.

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/tag/foobar.html b/pelican/tests/output/custom_locale/tag/foobar.html index a33f3362..93757930 100644 --- a/pelican/tests/output/custom_locale/tag/foobar.html +++ b/pelican/tests/output/custom_locale/tag/foobar.html @@ -101,4 +101,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/tag/oh.html b/pelican/tests/output/custom_locale/tag/oh.html index 5d021c7c..1e583e7e 100644 --- a/pelican/tests/output/custom_locale/tag/oh.html +++ b/pelican/tests/output/custom_locale/tag/oh.html @@ -28,7 +28,7 @@

Oh Oh Oh

- +

This page overrides the listening of the articles under the oh tag.

@@ -75,4 +75,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/tag/yeah.html b/pelican/tests/output/custom_locale/tag/yeah.html index 72b905f5..219ab7e7 100644 --- a/pelican/tests/output/custom_locale/tag/yeah.html +++ b/pelican/tests/output/custom_locale/tag/yeah.html @@ -93,4 +93,4 @@ YEAH !

}()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/tags.html b/pelican/tests/output/custom_locale/tags.html index 88b02724..3e59c960 100644 --- a/pelican/tests/output/custom_locale/tags.html +++ b/pelican/tests/output/custom_locale/tags.html @@ -82,4 +82,4 @@ }()); - \ No newline at end of file + diff --git a/pelican/tests/output/custom_locale/theme/css/reset.css b/pelican/tests/output/custom_locale/theme/css/reset.css index c88e6196..f5123cf6 100644 --- a/pelican/tests/output/custom_locale/theme/css/reset.css +++ b/pelican/tests/output/custom_locale/theme/css/reset.css @@ -49,4 +49,4 @@ del {text-decoration: line-through;} table { border-collapse: collapse; border-spacing: 0; -} \ No newline at end of file +} diff --git a/pelican/tests/output/custom_locale/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt b/pelican/tests/output/custom_locale/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt index 309fd710..c70bcad3 100644 --- a/pelican/tests/output/custom_locale/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt +++ b/pelican/tests/output/custom_locale/theme/fonts/Yanone_Kaffeesatz_LICENSE.txt @@ -18,7 +18,7 @@ with others. The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, +fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The From 7f07c220deaa6a9e62aaab783651a3591330b524 Mon Sep 17 00:00:00 2001 From: boxydog Date: Thu, 30 May 2024 15:45:59 -0500 Subject: [PATCH 050/147] Add pre-commit djhtml, djcss, djjs to indent templates --- .pre-commit-config.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6179814..bfdd6149 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,6 +13,7 @@ repos: - id: end-of-file-fixer - id: forbid-new-submodules - id: trailing-whitespace + - repo: https://github.com/astral-sh/ruff-pre-commit # ruff version should match the one in pyproject.toml rev: v0.4.6 @@ -20,3 +21,10 @@ repos: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format + + - repo: https://github.com/rtts/djhtml + rev: '3.0.6' + hooks: + - id: djhtml + - id: djcss + - id: djjs From 4af40e80772a58eac8969360e5caeb99e3e26e78 Mon Sep 17 00:00:00 2001 From: boxydog Date: Fri, 31 May 2024 07:34:01 -0500 Subject: [PATCH 051/147] pre-commit filter auto-indents templates, css, js --- docs/_templates/page.html | 372 +++++++-------- .../content/article_with_inline_svg.html | 14 +- ...2017-04-21_-medium-post--d1bf01d62ba3.html | 140 +++--- .../basic/a-markdown-powered-article.html | 112 ++--- pelican/tests/output/basic/archives.html | 122 ++--- pelican/tests/output/basic/article-1.html | 108 ++--- pelican/tests/output/basic/article-2.html | 108 ++--- pelican/tests/output/basic/article-3.html | 108 ++--- .../output/basic/author/alexis-metaireau.html | 182 ++++---- pelican/tests/output/basic/authors.html | 84 ++-- pelican/tests/output/basic/categories.html | 90 ++-- pelican/tests/output/basic/category/bar.html | 114 ++--- pelican/tests/output/basic/category/cat1.html | 194 ++++---- pelican/tests/output/basic/category/misc.html | 216 ++++----- pelican/tests/output/basic/category/yeah.html | 124 ++--- .../drafts/a-draft-article-without-date.html | 110 ++--- .../output/basic/drafts/a-draft-article.html | 110 ++--- .../basic/filename_metadata-example.html | 108 ++--- pelican/tests/output/basic/index.html | 438 +++++++++--------- pelican/tests/output/basic/oh-yeah-fr.html | 114 ++--- pelican/tests/output/basic/oh-yeah.html | 130 +++--- .../tests/output/basic/override/index.html | 82 ++-- .../pages/this-is-a-test-hidden-page.html | 82 ++-- .../basic/pages/this-is-a-test-page.html | 84 ++-- .../tests/output/basic/second-article-fr.html | 114 ++--- .../tests/output/basic/second-article.html | 114 ++--- pelican/tests/output/basic/tag/bar.html | 204 ++++---- pelican/tests/output/basic/tag/baz.html | 108 ++--- pelican/tests/output/basic/tag/foo.html | 154 +++--- pelican/tests/output/basic/tag/foobar.html | 124 ++--- pelican/tests/output/basic/tag/oh.html | 80 ++-- pelican/tests/output/basic/tag/yeah.html | 114 ++--- pelican/tests/output/basic/tags.html | 94 ++-- .../tests/output/basic/theme/css/fonts.css | 16 +- pelican/tests/output/basic/theme/css/main.css | 372 +++++++-------- .../tests/output/basic/theme/css/pygment.css | 166 +++---- .../tests/output/basic/theme/css/reset.css | 24 +- .../tests/output/basic/theme/fonts/font.css | 16 +- .../output/basic/this-is-a-super-article.html | 138 +++--- pelican/tests/output/basic/unbelievable.html | 166 +++---- .../custom/a-markdown-powered-article.html | 204 ++++---- pelican/tests/output/custom/archives.html | 178 +++---- pelican/tests/output/custom/article-1.html | 200 ++++---- pelican/tests/output/custom/article-2.html | 200 ++++---- pelican/tests/output/custom/article-3.html | 200 ++++---- .../custom/author/alexis-metaireau.html | 294 ++++++------ .../custom/author/alexis-metaireau2.html | 320 ++++++------- .../custom/author/alexis-metaireau3.html | 238 +++++----- pelican/tests/output/custom/authors.html | 138 +++--- pelican/tests/output/custom/categories.html | 144 +++--- pelican/tests/output/custom/category/bar.html | 170 +++---- .../tests/output/custom/category/cat1.html | 274 +++++------ .../tests/output/custom/category/misc.html | 296 ++++++------ .../tests/output/custom/category/yeah.html | 180 +++---- .../drafts/a-draft-article-without-date.html | 172 +++---- .../output/custom/drafts/a-draft-article.html | 172 +++---- .../custom/filename_metadata-example.html | 200 ++++---- pelican/tests/output/custom/index.html | 294 ++++++------ pelican/tests/output/custom/index2.html | 320 ++++++------- pelican/tests/output/custom/index3.html | 238 +++++----- .../tests/output/custom/jinja2_template.html | 130 +++--- pelican/tests/output/custom/oh-yeah-fr.html | 206 ++++---- pelican/tests/output/custom/oh-yeah.html | 216 ++++----- .../tests/output/custom/override/index.html | 138 +++--- .../pages/this-is-a-test-hidden-page.html | 138 +++--- .../custom/pages/this-is-a-test-page.html | 140 +++--- .../output/custom/second-article-fr.html | 206 ++++---- .../tests/output/custom/second-article.html | 206 ++++---- pelican/tests/output/custom/tag/bar.html | 266 +++++------ pelican/tests/output/custom/tag/baz.html | 200 ++++---- pelican/tests/output/custom/tag/foo.html | 216 ++++----- pelican/tests/output/custom/tag/foobar.html | 180 +++---- pelican/tests/output/custom/tag/oh.html | 136 +++--- pelican/tests/output/custom/tag/yeah.html | 170 +++---- pelican/tests/output/custom/tags.html | 148 +++--- .../tests/output/custom/theme/css/fonts.css | 16 +- .../tests/output/custom/theme/css/main.css | 372 +++++++-------- .../tests/output/custom/theme/css/pygment.css | 166 +++---- .../tests/output/custom/theme/css/reset.css | 24 +- .../tests/output/custom/theme/fonts/font.css | 16 +- .../custom/this-is-a-super-article.html | 224 ++++----- pelican/tests/output/custom/unbelievable.html | 258 +++++------ .../tests/output/custom_locale/archives.html | 178 +++---- .../author/alexis-metaireau.html | 294 ++++++------ .../author/alexis-metaireau2.html | 320 ++++++------- .../author/alexis-metaireau3.html | 238 +++++----- .../tests/output/custom_locale/authors.html | 138 +++--- .../output/custom_locale/categories.html | 144 +++--- .../output/custom_locale/category/bar.html | 170 +++---- .../output/custom_locale/category/cat1.html | 274 +++++------ .../output/custom_locale/category/misc.html | 296 ++++++------ .../output/custom_locale/category/yeah.html | 180 +++---- .../drafts/a-draft-article-without-date.html | 172 +++---- .../custom_locale/drafts/a-draft-article.html | 172 +++---- pelican/tests/output/custom_locale/index.html | 294 ++++++------ .../tests/output/custom_locale/index2.html | 320 ++++++------- .../tests/output/custom_locale/index3.html | 238 +++++----- .../output/custom_locale/jinja2_template.html | 130 +++--- .../output/custom_locale/oh-yeah-fr.html | 206 ++++---- .../output/custom_locale/override/index.html | 138 +++--- .../pages/this-is-a-test-hidden-page.html | 138 +++--- .../pages/this-is-a-test-page.html | 140 +++--- .../02/this-is-a-super-article/index.html | 224 ++++----- .../2010/octobre/15/unbelievable/index.html | 258 +++++------ .../posts/2010/octobre/20/oh-yeah/index.html | 216 ++++----- .../20/a-markdown-powered-article/index.html | 204 ++++---- .../2011/février/17/article-1/index.html | 200 ++++---- .../2011/février/17/article-2/index.html | 200 ++++---- .../2011/février/17/article-3/index.html | 200 ++++---- .../2012/février/29/second-article/index.html | 206 ++++---- .../30/filename_metadata-example/index.html | 200 ++++---- .../custom_locale/second-article-fr.html | 206 ++++---- .../tests/output/custom_locale/tag/bar.html | 266 +++++------ .../tests/output/custom_locale/tag/baz.html | 200 ++++---- .../tests/output/custom_locale/tag/foo.html | 216 ++++----- .../output/custom_locale/tag/foobar.html | 180 +++---- .../tests/output/custom_locale/tag/oh.html | 136 +++--- .../tests/output/custom_locale/tag/yeah.html | 170 +++---- pelican/tests/output/custom_locale/tags.html | 148 +++--- .../output/custom_locale/theme/css/fonts.css | 16 +- .../output/custom_locale/theme/css/main.css | 372 +++++++-------- .../custom_locale/theme/css/pygment.css | 166 +++---- .../output/custom_locale/theme/css/reset.css | 24 +- .../output/custom_locale/theme/fonts/font.css | 16 +- pelican/themes/notmyidea/static/css/fonts.css | 16 +- pelican/themes/notmyidea/static/css/main.css | 372 +++++++-------- .../themes/notmyidea/static/css/pygment.css | 166 +++---- pelican/themes/notmyidea/static/css/reset.css | 24 +- .../themes/notmyidea/static/fonts/font.css | 16 +- .../themes/notmyidea/templates/analytics.html | 2 +- .../themes/notmyidea/templates/archives.html | 18 +- .../themes/notmyidea/templates/article.html | 72 +-- .../notmyidea/templates/article_infos.html | 26 +- .../themes/notmyidea/templates/authors.html | 16 +- pelican/themes/notmyidea/templates/base.html | 150 +++--- .../notmyidea/templates/categories.html | 16 +- .../notmyidea/templates/disqus_script.html | 18 +- .../themes/notmyidea/templates/github.html | 14 +- pelican/themes/notmyidea/templates/index.html | 110 ++--- pelican/themes/notmyidea/templates/page.html | 12 +- .../notmyidea/templates/period_archives.html | 18 +- pelican/themes/notmyidea/templates/tags.html | 16 +- .../notmyidea/templates/translations.html | 18 +- .../themes/notmyidea/templates/twitter.html | 2 +- pelican/themes/simple/templates/archives.html | 14 +- pelican/themes/simple/templates/article.html | 76 +-- pelican/themes/simple/templates/author.html | 2 +- pelican/themes/simple/templates/authors.html | 6 +- pelican/themes/simple/templates/base.html | 92 ++-- .../themes/simple/templates/categories.html | 6 +- pelican/themes/simple/templates/category.html | 2 +- pelican/themes/simple/templates/index.html | 30 +- pelican/themes/simple/templates/page.html | 12 +- .../themes/simple/templates/pagination.html | 22 +- .../simple/templates/period_archives.html | 14 +- pelican/themes/simple/templates/tag.html | 2 +- pelican/themes/simple/templates/tags.html | 6 +- .../themes/simple/templates/translations.html | 22 +- samples/content/pages/jinja2_template.html | 2 +- 159 files changed, 11584 insertions(+), 11584 deletions(-) diff --git a/docs/_templates/page.html b/docs/_templates/page.html index 233f43ad..0fbfdf7d 100644 --- a/docs/_templates/page.html +++ b/docs/_templates/page.html @@ -1,201 +1,201 @@ {% extends "base.html" %} {% block body -%} -{{ super() }} -{% include "partials/icons.html" %} + {{ super() }} + {% include "partials/icons.html" %} - - - - + + + + -{% if theme_announcement -%} -
- -
-{%- endif %} + {% if theme_announcement -%} +
+ +
+ {%- endif %} -
-
-
- -
- -
-
- +
+
+
+
- -
-
- -
-
-
- - - - - {% trans %}Back to top{% endtrans %} - -
- {% if theme_top_of_page_button == "edit" -%} - {%- include "components/edit-this-page.html" with context -%} - {%- elif theme_top_of_page_button != None -%} - {{ warning("Got an unsupported value for 'top_of_page_button'") }} - {%- endif -%} - {#- Theme toggle -#} -
- -
- +
+
+
-
- {% block content %}{{ body }}{% endblock %} -
+
-
- {% block footer %} - -
-
- {%- if show_copyright %} - - {%- endif %} - {%- if last_updated -%} -
- {% trans last_updated=last_updated|e -%} - Last updated on {{ last_updated }} - {%- endtrans -%} -
- {%- endif %} + +
-
- +
+
+
+ + + + + {% trans %}Back to top{% endtrans %} + +
+ {% if theme_top_of_page_button == "edit" -%} + {%- include "components/edit-this-page.html" with context -%} + {%- elif theme_top_of_page_button != None -%} + {{ warning("Got an unsupported value for 'top_of_page_button'") }} + {%- endif -%} + {#- Theme toggle -#} +
+ +
+ +
+
+ {% block content %}{{ body }}{% endblock %} +
+
+ +
+ +
-
{%- endblock %} diff --git a/pelican/tests/content/article_with_inline_svg.html b/pelican/tests/content/article_with_inline_svg.html index 07f97a8a..06725704 100644 --- a/pelican/tests/content/article_with_inline_svg.html +++ b/pelican/tests/content/article_with_inline_svg.html @@ -5,13 +5,13 @@ Ensure that the title attribute in an inline svg is not handled as an HTML title. - - A different title inside the inline SVG - - - - - + + A different title inside the inline SVG + + + + + diff --git a/pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html b/pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html index 02d272dc..6d28f1a2 100644 --- a/pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html +++ b/pelican/tests/content/medium_posts/2017-04-21_-medium-post--d1bf01d62ba3.html @@ -1,72 +1,72 @@ A title
-
-

A name (like title)

-
-
+ * { + font-family: Georgia, Cambria, "Times New Roman", Times, serif; + } + html, body { + margin: 0; + padding: 0; + } + h1 { + font-size: 50px; + margin-bottom: 17px; + color: #333; + } + h2 { + font-size: 24px; + line-height: 1.6; + margin: 30px 0 0 0; + margin-bottom: 18px; + margin-top: 33px; + color: #333; + } + h3 { + font-size: 30px; + margin: 10px 0 20px 0; + color: #333; + } + header { + width: 640px; + margin: auto; + } + section { + width: 640px; + margin: auto; + } + section p { + margin-bottom: 27px; + font-size: 20px; + line-height: 1.6; + color: #333; + } + section img { + max-width: 640px; + } + footer { + padding: 0 20px; + margin: 50px 0; + text-align: center; + font-size: 12px; + } + .aspectRatioPlaceholder { + max-width: auto !important; + max-height: auto !important; + } + .aspectRatioPlaceholder-fill { + padding-bottom: 0 !important; + } + header, + section[data-field=subtitle], + section[data-field=description] { + display: none; + } + +
+
+

Title header

A paragraph of content.

Paragraph number two.

A list:

  1. One.
  2. Two.
  3. Three.

A link: link text.

Header 2

A block quote:

quote words strong words

after blockquote

A figure caption.

A final note: Cross-Validated has sometimes been helpful.


+
diff --git a/pelican/tests/output/basic/a-markdown-powered-article.html b/pelican/tests/output/basic/a-markdown-powered-article.html index 3c2821f1..66136d87 100644 --- a/pelican/tests/output/basic/a-markdown-powered-article.html +++ b/pelican/tests/output/basic/a-markdown-powered-article.html @@ -1,68 +1,68 @@ - - - - - A markdown powered article - - - - + + + + + A markdown powered article + + + + - - -
-
-
-

- A markdown powered article

-
+ + +
+ -
-
-
+
+
+ -
+ +
+
- - + diff --git a/pelican/tests/output/basic/archives.html b/pelican/tests/output/basic/archives.html index 3218fe1d..7aa6b263 100644 --- a/pelican/tests/output/basic/archives.html +++ b/pelican/tests/output/basic/archives.html @@ -1,70 +1,70 @@ - - - - - A Pelican Blog - - - + + + + + A Pelican Blog + + + - - -
-

Archives for A Pelican Blog

+ + +
+

Archives for A Pelican Blog

-
-
Fri 30 November 2012
-
FILENAME_METADATA example
-
Wed 29 February 2012
-
Second article
-
Wed 20 April 2011
-
A markdown powered article
-
Thu 17 February 2011
-
Article 1
-
Thu 17 February 2011
-
Article 2
-
Thu 17 February 2011
-
Article 3
-
Thu 02 December 2010
-
This is a super article !
-
Wed 20 October 2010
-
Oh yeah !
-
Fri 15 October 2010
-
Unbelievable !
-
Sun 14 March 2010
-
The baz tag
-
-
-
-
+
+ -
+ + +
- - + diff --git a/pelican/tests/output/basic/article-1.html b/pelican/tests/output/basic/article-1.html index 91dcff19..4ec2a0e1 100644 --- a/pelican/tests/output/basic/article-1.html +++ b/pelican/tests/output/basic/article-1.html @@ -1,67 +1,67 @@ - - - - - Article 1 - - - - + + + + + Article 1 + + + + - - -
- +
+
+ -
+ + +
- - + diff --git a/pelican/tests/output/basic/article-2.html b/pelican/tests/output/basic/article-2.html index e3ad5724..99819902 100644 --- a/pelican/tests/output/basic/article-2.html +++ b/pelican/tests/output/basic/article-2.html @@ -1,67 +1,67 @@ - - - - - Article 2 - - - - + + + + + Article 2 + + + + - - -
- +
+
+ -
+ + +
- - + diff --git a/pelican/tests/output/basic/article-3.html b/pelican/tests/output/basic/article-3.html index 2ec3f1e7..596db91f 100644 --- a/pelican/tests/output/basic/article-3.html +++ b/pelican/tests/output/basic/article-3.html @@ -1,67 +1,67 @@ - - - - - Article 3 - - - - + + + + + Article 3 + + + + - - -
- +
+
+ -
+ + +
- - + diff --git a/pelican/tests/output/basic/author/alexis-metaireau.html b/pelican/tests/output/basic/author/alexis-metaireau.html index d682ab29..e4bde41d 100644 --- a/pelican/tests/output/basic/author/alexis-metaireau.html +++ b/pelican/tests/output/basic/author/alexis-metaireau.html @@ -1,112 +1,112 @@ - - - - - A Pelican Blog - Alexis Métaireau - - - + + + + + A Pelican Blog - Alexis Métaireau + + + - - + + - +

→ And now try with some utf8 hell: ééé

+ + +
-

Other articles

-
-
    +

    Other articles

    +
    +
      -
    1. -
      -

      Oh yeah !

      -
      +
    2. +
      +

      Oh yeah !

      +
      -
      -
      - - Published: Wed 20 October 2010 - +
      +
      -

      Why not ?

      -

      After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! -YEAH !

      -alternate text -
      +
      +

      Why not ?

      +

      After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! + YEAH !

      + alternate text +
      - read more -
      -
    3. -
    + read more + + +
-
- +
- - + diff --git a/pelican/tests/output/basic/authors.html b/pelican/tests/output/basic/authors.html index 86d2249a..27d10c2f 100644 --- a/pelican/tests/output/basic/authors.html +++ b/pelican/tests/output/basic/authors.html @@ -1,52 +1,52 @@ - - - - - A Pelican Blog - Authors - - - + + + + + A Pelican Blog - Authors + + + - - + + -
-

Authors on A Pelican Blog

- -
- -
- -
+
- + + +
- + + + diff --git a/pelican/tests/output/basic/categories.html b/pelican/tests/output/basic/categories.html index 86606fbe..5c85b20e 100644 --- a/pelican/tests/output/basic/categories.html +++ b/pelican/tests/output/basic/categories.html @@ -1,55 +1,55 @@ - - - - - A Pelican Blog - Categories - - - + + + + + A Pelican Blog - Categories + + + - - + + -
-

Categories for A Pelican Blog

- -
- -
- -
+
- + + +
- + + + diff --git a/pelican/tests/output/basic/category/bar.html b/pelican/tests/output/basic/category/bar.html index c4f57bdd..e89375bf 100644 --- a/pelican/tests/output/basic/category/bar.html +++ b/pelican/tests/output/basic/category/bar.html @@ -1,68 +1,68 @@ - - - - - A Pelican Blog - bar - - - + + + + + A Pelican Blog - bar + + + - - + + - +
+ -
+ + +
- - + diff --git a/pelican/tests/output/basic/category/cat1.html b/pelican/tests/output/basic/category/cat1.html index a291aae4..6c0cd64c 100644 --- a/pelican/tests/output/basic/category/cat1.html +++ b/pelican/tests/output/basic/category/cat1.html @@ -1,125 +1,125 @@ - - - - - A Pelican Blog - cat1 - - - + + + + + A Pelican Blog - cat1 + + + - - + + -
-

Other articles

-
-
    +

    Other articles

    +
    +
      -
    1. -
    2. -
    3. -
      -

      Article 3

      -
      +
    4. +
      +

      Article 3

      +
      -
      -
      - - Published: Thu 17 February 2011 - +
      +
      + + Published: Thu 17 February 2011 + -

      In cat1.

      +

      In cat1.

      -

      Article 3

      +

      Article 3

      - read more -
      -
    5. -
    + read more + + +
-
- +
- - + diff --git a/pelican/tests/output/basic/category/misc.html b/pelican/tests/output/basic/category/misc.html index fa786910..fa9eb563 100644 --- a/pelican/tests/output/basic/category/misc.html +++ b/pelican/tests/output/basic/category/misc.html @@ -1,136 +1,136 @@ - - - - - A Pelican Blog - misc - - - + + + + + A Pelican Blog - misc + + + - - + + -
-

Other articles

-
-
    +

    Other articles

    +
    +
      -
    1. -
    2. -
      -

      Unbelievable !

      -
      +
    3. +
      +

      Unbelievable !

      +
      -
      -