diff --git a/.editorconfig b/.editorconfig
index b42ca8c2..edb13c8a 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -11,5 +11,5 @@ trim_trailing_whitespace = true
[*.py]
max_line_length = 79
-[*.yml]
+[*.{yml,yaml}]
indent_size = 2
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index bcbd94d4..7e178b57 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -15,14 +15,14 @@ jobs:
strategy:
matrix:
config:
- - os: ubuntu
- python: 3.5
- os: ubuntu
python: 3.6
- os: ubuntu
python: 3.7
- os: ubuntu
python: 3.8
+ - os: ubuntu
+ python: 3.9
- os: macos
python: 3.7
- os: windows
@@ -31,7 +31,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup Python ${{ matrix.config.python }}
- uses: actions/setup-python@v1.1.1
+ uses: actions/setup-python@v2
with:
python-version: ${{ matrix.config.python }}
- name: Set pip cache (Linux)
@@ -84,9 +84,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup Python
- uses: actions/setup-python@v1.1.1
+ uses: actions/setup-python@v2
with:
- python-version: 3.6
+ python-version: 3.7
- name: Set pip cache (Linux)
uses: actions/cache@v1
if: startsWith(runner.os, 'Linux')
@@ -108,9 +108,9 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup Python
- uses: actions/setup-python@v1.1.1
+ uses: actions/setup-python@v2
with:
- python-version: 3.6
+ python-version: 3.7
- name: Set pip cache (Linux)
uses: actions/cache@v1
if: startsWith(runner.os, 'Linux')
@@ -134,7 +134,7 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup Python
- uses: actions/setup-python@v1.1.1
+ uses: actions/setup-python@v2
with:
python-version: 3.7
- name: Check release
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c0637a7f..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-language: python
-python:
- - "3.6"
-env:
- global:
- - PYPI_USERNAME=autopub
- - secure: "h5V/+YL+CrqvfAesNkSb824Ngk5x+f0eFzj/LBbmnzjvArKAmc6R6WGyx8SDD7WF/PlaTf0M1fH3a7pjIS8Ee+TS1Rb0Lt1HPqUs1yntg1+Js2ZQp3p20wfsDc+bZ4/2g8xLsSMv1EJ4np7/GJ5fXqpSxjr/Xs5LYA7ZLwNNwDw="
- - secure: "GiDFfmjH7uzYNnkjQMV/mIkbRdmgkGmtbFPeaj9taBNA5tPp3IBt3GOOS6UL/zm9xiwu9Xo6sxZWkGzY19Hsdv28YPH34N3abo0QSnz4IGiHs152Hi7Qi6Tb0QkT5D3OxuSIm8LmFL7+su89Q7vBFowrT6HL1Mn8CDDWSj3eqbo="
- - TWINE_USERNAME=$PYPI_USERNAME
- - TWINE_PASSWORD=$PYPI_PASSWORD
- matrix:
- - TOX_ENV=docs
- - TOX_ENV=flake8
- - TOX_ENV=py3.5
- - TOX_ENV=py3.6
-matrix:
- include:
- - python: 3.7
- sudo: true
- dist: xenial
- env:
- - TOX_ENV=py3.7
-addons:
- apt_packages:
- - pandoc
-before_install:
- - sudo apt-get update -qq
- - sudo locale-gen fr_FR.UTF-8 tr_TR.UTF-8
-install:
- - pip install tox==2.5.0
-script: tox -e $TOX_ENV
-before_deploy:
- - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then travis_terminate 0; fi'
- - pip install githubrelease
- - pip install --pre autopub
- - autopub check || travis_terminate 0
- - pip install poetry
- - pip install twine
- - git checkout ${TRAVIS_BRANCH}
- - git remote set-url origin https://$GITHUB_TOKEN@github.com/$TRAVIS_REPO_SLUG
-deploy:
- provider: script
- script: autopub deploy
- skip_cleanup: true
- on:
- branch: master
- python: "3.7"
-# The channel name "irc.freenode.org#pelican" is encrypted against getpelican/pelican to prevent IRC spam of forks
-notifications:
- irc:
- channels:
- - secure: "JP57f61QovrhmLoAF6oPOzIK2aXGfSO06FHg7yiuKBOWMiaxQejZUGJX919muCLhWJXDugsviIqCMoAWwNV3o1WQbqIr+G5TR+N9MrtCs4Zi6vpGj09bR8giKUKx+PPKEoe1Ew56E4y2LxzGO4Lj9hZx8M2YVdwPNWrWZgp6WXE="
- on_success: change
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index 9561b04f..61935f62 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -43,7 +43,7 @@ publicly-accessible location:
* Describe what version of Pelican you are running (output of ``pelican --version``
or the HEAD commit hash if you cloned the repo) and how exactly you installed
- it (the full command you used, e.g. ``pip install pelican``).
+ it (the full command you used, e.g. ``python -m pip install pelican``).
* If you are looking for a way to get some end result, prepare a detailed
description of what the end result should look like (preferably in the form of
an image or a mock-up page) and explain in detail what you have done so far to
diff --git a/MANIFEST.in b/MANIFEST.in
index 138c8f00..469f6fff 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,3 @@
include *.rst
-recursive-include pelican *.html *.css *png *.rst *.markdown *.md *.mkd *.xml *.py
+recursive-include pelican *.html *.css *png *.rst *.markdown *.md *.mkd *.xml *.py *.jinja2
include LICENSE THANKS docs/changelog.rst pyproject.toml
diff --git a/README.rst b/README.rst
index dee92234..995d23b0 100644
--- a/README.rst
+++ b/README.rst
@@ -1,5 +1,5 @@
Pelican |build-status| |pypi-version| |repology|
-=====================================
+================================================
Pelican is a static site generator, written in Python_.
@@ -60,7 +60,7 @@ Why the name "Pelican"?
:target: https://github.com/getpelican/pelican/actions
:alt: GitHub Actions CI: continuous integration status
.. |pypi-version| image:: https://img.shields.io/pypi/v/pelican.svg
- :target: https://pypi.python.org/pypi/pelican
+ :target: https://pypi.org/project/pelican/
:alt: PyPI: the Python Package Index
.. |repology| image:: https://repology.org/badge/tiny-repos/pelican.svg
:target: https://repology.org/project/pelican/versions
diff --git a/THANKS b/THANKS
index 08ac7bb2..fd9f030e 100644
--- a/THANKS
+++ b/THANKS
@@ -97,6 +97,7 @@ Kyle Fuller
Laureline Guerin
Leonard Huang
Leroy Jiang
+Lucas Cimon
Marcel Hellkamp
Marco Milanesi
Marcus Fredriksson
diff --git a/docs/changelog.rst b/docs/changelog.rst
index febc5322..fc673d90 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -1,6 +1,52 @@
Release history
###############
+4.6.0 - 2021-03-23
+==================
+
+* Add new URL pattern to ``PAGINATION_PATTERNS`` for the last page in the list `(#1401) `_
+* Speed up ``livereload`` Invoke task via caching `(#2847) `_
+* Ignore ``None`` return value from ``get_generators`` signal `(#2850) `_
+* Relax dependency minimum versions and remove upper bounds
+
+4.5.4 - 2021-01-04
+==================
+
+Replace plugin definitions in settings with string representations after registering, so they can be cached correctly `(#2828) `_.
+
+4.5.3 - 2020-12-01
+==================
+
+Fix a mistake made in PR #2821
+
+4.5.2 - 2020-11-22
+==================
+
+Improve logging of generators and writer loaders
+
+4.5.1 - 2020-11-02
+==================
+
+* Refactor intra-site link discovery in order to match more permissively `(#2646) `_
+* Fix plugins running twice in auto-reload mode `(#2817) `_
+* Add notice to use ``from pelican import signals`` instead of ``import pelican.signals`` `(#2805) `_
+
+4.5.0 - 2020-08-20
+==================
+
+* Add namespace plugin support; list plugins via ``pelican-plugins`` command
+* Override settings via ``-e`` / ``--extra-settings`` CLI option flags
+* Add settings for custom Jinja globals and tests
+* Customize article summary ellipsis via ``SUMMARY_END_SUFFIX`` setting
+* Customize Typogrify dash handling via new ``TYPOGRIFY_DASHES`` setting
+* Support Unicode when generating slugs
+* Support Asciidoc ``.adoc`` file generation in Pelican importer
+* Improve user experience when ``pelican --listen`` web server is quit
+* Improve Invoke tasks template
+* Include tests in source distributions
+* Switch CI from Travis to GitHub Actions
+* Remove support for Python 2.7
+
4.2.0 - 2019-10-17
==================
@@ -12,7 +58,7 @@ Release history
4.1.3 - 2019-10-09
==================
-* Fix quick-start docs regarding `pelican --listen`
+* Fix quick-start docs regarding ``pelican --listen``
* Set default listen address to 127.0.0.1
* Add extra/optional Markdown dependency to setup.py
* Use correct SSH port syntax for rsync in tasks.py
@@ -30,8 +76,8 @@ Fix pelican.settings.load_source to avoid caching issues - PR #2621
* Add AutoPub to auto-publish releases on PR merge
* Add CSS classes for reStructuredText figures
-* Pass `argv` to Pelican `main` entrypoint
-* Set default content status to a blank string rather than `None`
+* Pass ``argv`` to Pelican ``main`` entrypoint
+* Set default content status to a blank string rather than ``None``
4.1.0 - 2019-07-14
==================
diff --git a/docs/contribute.rst b/docs/contribute.rst
index 66890ae7..a86a5031 100644
--- a/docs/contribute.rst
+++ b/docs/contribute.rst
@@ -44,9 +44,9 @@ to manually create and activate a virtual environment::
Install the needed dependencies and set up the project::
- pip install invoke
+ python -m pip install invoke
invoke setup
- pip install -e ~/projects/pelican
+ python -m pip install -e ~/projects/pelican
Your local environment should now be ready to go!
@@ -75,11 +75,14 @@ via::
invoke tests
-In addition to running the test suite, the above invocation will also check code
-style and let you know whether non-conforming patterns were found. In some cases
-these linters will make the needed changes directly, while in other cases you
-may need to make additional changes until ``invoke tests`` no longer reports any
-code style violations.
+In addition to running the test suite, it is important to also ensure that any
+lines you changed conform to code style guidelines. You can check that via::
+
+ invoke lint
+
+If code style violations are found in lines you changed, correct those lines
+and re-run the above lint command until they have all been fixed. You do not
+need to address style violations, if any, for code lines you did not touch.
After making your changes and running the tests, you may see a test failure
mentioning that "some generated files differ from the expected functional tests
@@ -145,9 +148,20 @@ Create a topic branch for your plugin bug fix or feature::
git checkout -b name-of-your-bugfix-or-feature
-After writing new tests for your plugin changes, run the plugin test suite::
+After writing new tests for your plugin changes, run the plugin test suite and
+check for code style compliance via::
invoke tests
+ invoke lint
+
+If style violations are found, many of them can be addressed automatically via::
+
+ invoke black
+ invoke isort
+
+If style violations are found even after running the above auto-formatters,
+you will need to make additional manual changes until ``invoke lint`` no longer
+reports any code style violations.
.. _plugin template: https://github.com/getpelican/cookiecutter-pelican-plugin
.. _Simple Footnotes: https://github.com/pelican-plugins/simple-footnotes
diff --git a/docs/faq.rst b/docs/faq.rst
index c35cd6c6..5ad372c5 100644
--- a/docs/faq.rst
+++ b/docs/faq.rst
@@ -74,7 +74,7 @@ Markdown format, you will need to explicitly install the Markdown library. You
can do so by typing the following command, prepending ``sudo`` if permissions
require it::
- pip install markdown
+ python -m pip install markdown
Can I use arbitrary metadata in my templates?
=============================================
@@ -174,28 +174,18 @@ your site.
Feeds are still generated when this warning is displayed, but links within may
be malformed and thus the feed may not validate.
-My feeds are broken since I upgraded to Pelican 3.x
-===================================================
+Can I force Atom feeds to show only summaries instead of article content?
+=========================================================================
-Starting in 3.0, some of the FEED setting names were changed to more explicitly
-refer to the Atom feeds they inherently represent (much like the FEED_RSS
-setting names). Here is an exact list of the renamed settings::
-
- FEED -> FEED_ATOM
- TAG_FEED -> TAG_FEED_ATOM
- CATEGORY_FEED -> CATEGORY_FEED_ATOM
-
-Starting in 3.1, the new feed ``FEED_ALL_ATOM`` has been introduced: this feed
-will aggregate all posts regardless of their language. This setting generates
-``'feeds/all.atom.xml'`` by default and ``FEED_ATOM`` now defaults to ``None``.
-The following feed setting has also been renamed::
-
- TRANSLATION_FEED -> TRANSLATION_FEED_ATOM
-
-Older themes that referenced the old setting names may not link properly. In
-order to rectify this, please update your theme for compatibility by changing
-the relevant values in your template files. For an example of complete feed
-headers and usage please check out the ``simple`` theme.
+Instead of having to open a separate browser window to read articles, the
+overwhelming majority of folks who use feed readers prefer to read content
+within the feed reader itself. Mainly for that reason, Pelican does not support
+restricting Atom feeds to only contain summaries. Unlike Atom feeds, the RSS
+feed specification does not include a separate ``content`` field, so by default
+Pelican publishes RSS feeds that only contain summaries (but can optionally be
+set to instead publish full content RSS feeds). So the default feed generation
+behavior provides users with a choice: subscribe to Atom feeds for full content
+or to RSS feeds for just the summaries.
Is Pelican only suitable for blogs?
===================================
@@ -228,7 +218,7 @@ which will make it compare the file checksums in a much faster way than Pelican
would.
When only several specific output files are of interest (e.g. when working on
-some specific page or the theme templates), the `WRITE_SELECTED` option may
+some specific page or the theme templates), the ``WRITE_SELECTED`` option may
help, see :ref:`writing_only_selected_content`.
How to process only a subset of all articles?
@@ -242,11 +232,10 @@ command similar to ``cd content; find -name '*.md' | head -n 10``.
My tag-cloud is missing/broken since I upgraded Pelican
=======================================================
-In an ongoing effort to steamline Pelican, `tag_cloud` generation has been
-moved out of the pelican core and into a separate `plugin
-`_. See
-the :ref:`plugins` documentation further information about the Pelican plugin
-system.
+In an ongoing effort to streamline Pelican, tag cloud generation has been
+moved out of Pelican core and into a separate `plugin
+`_. See the :ref:`plugins`
+documentation for further information about the Pelican plugin system.
Since I upgraded Pelican my pages are no longer rendered
========================================================
diff --git a/docs/importer.rst b/docs/importer.rst
index b8313f49..7b839d30 100644
--- a/docs/importer.rst
+++ b/docs/importer.rst
@@ -24,8 +24,8 @@ not be converted (as Pelican also supports Markdown).
Unlike Pelican, Wordpress supports multiple categories per article. These
are imported as a comma-separated string. You have to resolve these
- manually, or use a plugin that enables multiple categories per article
- (like `more_categories`_).
+ manually, or use a plugin such as `More Categories`_ that enables multiple
+ categories per article.
Dependencies
============
@@ -140,4 +140,4 @@ To test the module, one can use sample files:
- for WordPress: https://www.wpbeginner.com/wp-themes/how-to-add-dummy-content-for-theme-development-in-wordpress/
- for Dotclear: http://media.dotaddict.org/tda/downloads/lorem-backup.txt
-.. _more_categories: https://github.com/getpelican/pelican-plugins/tree/master/more_categories
+.. _More Categories: https://github.com/pelican-plugins/more-categories
diff --git a/docs/install.rst b/docs/install.rst
index 03480e79..eb618035 100644
--- a/docs/install.rst
+++ b/docs/install.rst
@@ -1,19 +1,17 @@
Installing Pelican
##################
-Pelican currently runs best on Python 2.7.x and 3.5+; earlier versions of
-Python are not supported.
+Pelican currently runs best on 3.6+; earlier versions of Python are not supported.
-You can install Pelican via several different methods. The simplest is via
-`pip `_::
+You can install Pelican via several different methods. The simplest is via Pip_::
- pip install pelican
+ python -m pip install pelican
Or, if you plan on using Markdown::
- pip install pelican[Markdown]
+ python -m pip install "pelican[markdown]"
-(Keep in mind that operating systems will often require you to prefix the above
+(Keep in mind that some operating systems will require you to prefix the above
command with ``sudo`` in order to install Pelican system-wide.)
While the above is the simplest method, the recommended approach is to create a
@@ -26,7 +24,7 @@ session and create a new virtual environment for Pelican::
source bin/activate
Once the virtual environment has been created and activated, Pelican can be
-installed via ``pip install pelican`` as noted above. Alternatively, if you
+installed via ``python -m pip install pelican`` as noted above. Alternatively, if you
have the project source, you can install Pelican using the distutils method::
cd path-to-Pelican-source
@@ -35,7 +33,7 @@ have the project source, you can install Pelican using the distutils method::
If you have Git installed and prefer to install the latest bleeding-edge
version of Pelican rather than a stable release, use the following command::
- pip install -e "git+https://github.com/getpelican/pelican.git#egg=pelican"
+ python -m pip install -e "git+https://github.com/getpelican/pelican.git#egg=pelican"
Once Pelican is installed, you can run ``pelican --help`` to see basic usage
options. For more detail, refer to the :doc:`Publish` section.
@@ -46,17 +44,13 @@ Optional packages
If you plan on using `Markdown `_ as a
markup format, you can install Pelican with Markdown support::
- pip install pelican[Markdown]
-
-Or you might need to install it a posteriori::
-
- pip install Markdown
+ python -m pip install "pelican[markdown]"
Typographical enhancements can be enabled in your settings file, but first the
requisite `Typogrify `_ library must be
installed::
- pip install typogrify
+ python -m pip install typogrify
Dependencies
------------
@@ -75,9 +69,8 @@ automatically installed without any action on your part:
broadcast signaling system
* `unidecode `_, for ASCII
transliterations of Unicode text
-* `six `_, for Python 2 and 3 compatibility
utilities
-* `MarkupSafe `_, for a markup safe
+* `MarkupSafe `_, for a markup-safe
string implementation
* `python-dateutil `_, to read
the date metadata
@@ -85,10 +78,10 @@ automatically installed without any action on your part:
Upgrading
---------
-If you installed a stable Pelican release via ``pip`` and wish to upgrade to
+If you installed a stable Pelican release via Pip_ and wish to upgrade to
the latest stable release, you can do so by adding ``--upgrade``::
- pip install --upgrade pelican
+ python -m pip install --upgrade pelican
If you installed Pelican via distutils or the bleeding-edge method, simply
perform the same step to install the most recent version.
@@ -126,4 +119,5 @@ content)::
The next step is to begin to adding content to the *content* folder that has
been created for you.
+.. _Pip: https://pip.pypa.io/
.. _virtualenv: https://virtualenv.pypa.io/en/latest/
diff --git a/docs/internals.rst b/docs/internals.rst
index 5b41070e..01d60c39 100644
--- a/docs/internals.rst
+++ b/docs/internals.rst
@@ -44,17 +44,22 @@ HTML content and some metadata.
Take a look at the Markdown reader::
+ from pelican.readers import BaseReader
+ from pelican.utils import pelican_open
+ from markdown import Markdown
+
class MarkdownReader(BaseReader):
- enabled = bool(Markdown)
+ enabled = True
def read(self, source_path):
"""Parse content and metadata of markdown files"""
- text = pelican_open(source_path)
- md_extensions = {'markdown.extensions.meta': {},
- 'markdown.extensions.codehilite': {}}
- md = Markdown(extensions=md_extensions.keys(),
- extension_configs=md_extensions)
- content = md.convert(text)
+
+ with pelican_open(source_path) as text:
+ md_extensions = {'markdown.extensions.meta': {},
+ 'markdown.extensions.codehilite': {}}
+ md = Markdown(extensions=md_extensions.keys(),
+ extension_configs=md_extensions)
+ content = md.convert(text)
metadata = {}
for name, value in md.Meta.items():
diff --git a/docs/plugins.rst b/docs/plugins.rst
index a4ef91d6..f661afb8 100644
--- a/docs/plugins.rst
+++ b/docs/plugins.rst
@@ -12,8 +12,8 @@ How to use plugins
Starting with version 4.5, Pelican moved to a new plugin structure utilizing
namespace packages that can be easily installed via Pip_. Plugins supporting
this structure will install under the namespace package ``pelican.plugins`` and
-can be automatically discovered by Pelican. To see a list of plugins that are
-active in your environment, run::
+can be automatically discovered by Pelican. To see a list of Pip-installed
+namespace plugins that are active in your environment, run::
pelican-plugins
@@ -70,8 +70,8 @@ How to create plugins
=====================
Plugins are based on the concept of signals. Pelican sends signals, and plugins
-subscribe to those signals. The list of signals are defined in a subsequent
-section.
+subscribe to those signals. The list of available signals is documented in a
+subsequent section.
The only rule to follow for plugins is to define a ``register`` callable, in
which you map the signals to your plugin logic. Let's take a simple example::
@@ -94,6 +94,10 @@ which you map the signals to your plugin logic. Let's take a simple example::
your ``register`` callable or they will be garbage-collected before the
signal is emitted.
+If multiple plugins connect to the same signal, there is no way to guarantee or
+control in which order the plugins will be executed. This is a limitation
+inherited from Blinker_, the dependency Pelican uses to implement signals.
+
Namespace plugin structure
--------------------------
@@ -272,3 +276,4 @@ Adding a new generator is also really easy. You might want to have a look at
.. _Pip: https://pip.pypa.io/
.. _pelican-plugins bug #314: https://github.com/getpelican/pelican-plugins/issues/314
+.. _Blinker: https://pythonhosted.org/blinker/
diff --git a/docs/publish.rst b/docs/publish.rst
index 9bea8938..ae1428f5 100644
--- a/docs/publish.rst
+++ b/docs/publish.rst
@@ -118,7 +118,7 @@ in a wide range of environments. The downside is that it must be installed
separately. Use the following command to install Invoke, prefixing with
``sudo`` if your environment requires it::
- pip install invoke
+ python -m pip install invoke
Take a moment to open the ``tasks.py`` file that was generated in your project
root. You will see a number of commands, any one of which can be renamed,
@@ -139,7 +139,7 @@ http://localhost:8000/::
invoke serve
To serve the generated site with automatic browser reloading every time a
-change is detected, first ``pip install livereload``, then use the
+change is detected, first ``python -m pip install livereload``, then use the
following command::
invoke livereload
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index 1f6358a7..ddc42651 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -8,10 +8,10 @@ Installation
------------
Install Pelican (and optionally Markdown if you intend to use it) on Python
-2.7.x or Python 3.5+ by running the following command in your preferred
-terminal, prefixing with ``sudo`` if permissions warrant::
+3.6+ by running the following command in your preferred terminal, prefixing
+with ``sudo`` if permissions warrant::
- pip install pelican[Markdown]
+ python -m pip install "pelican[markdown]"
Create a project
----------------
diff --git a/docs/settings.rst b/docs/settings.rst
index 2b99072f..c66c42a3 100644
--- a/docs/settings.rst
+++ b/docs/settings.rst
@@ -9,6 +9,12 @@ line::
If you used the ``pelican-quickstart`` command, your primary settings file will
be named ``pelicanconf.py`` by default.
+You can also specify extra settings via ``-e`` / ``--extra-settings`` option
+flags, which will override default settings as well as any defined within
+settings files::
+
+ pelican content -e DELETE_OUTPUT_DIRECTORY=true
+
.. note::
When experimenting with different settings (especially the metadata ones)
@@ -270,8 +276,8 @@ Basic settings
If set to True, several typographical improvements will be incorporated into
the generated HTML via the `Typogrify
- `_ library, which can be installed
- via: ``pip install typogrify``
+ `_ library, which can be installed
+ via: ``python -m pip install typogrify``
.. data:: TYPOGRIFY_IGNORE_TAGS = []
@@ -297,10 +303,10 @@ Basic settings
does not otherwise specify a summary. Setting to ``None`` will cause the
summary to be a copy of the original content.
-.. data:: SUMMARY_END_MARKER = '…'
+.. data:: SUMMARY_END_SUFFIX = '…'
When creating a short summary of an article and the result was truncated to
- match the required word length, this will be used as the truncation marker.
+ match the required word length, this will be used as the truncation suffix.
.. data:: WITH_FUTURE_DATES = True
@@ -770,7 +776,7 @@ Template pages
.. data:: TEMPLATE_PAGES = None
A mapping containing template pages that will be rendered with the blog
- entries. See :ref:`template_pages`.
+ entries.
If you want to generate custom pages besides your blog entries, you can
point any Jinja2 template file with a path pointing to the file and the
@@ -1061,6 +1067,11 @@ as follows::
)
+If you want a pattern to apply to the last page in the list, use ``-1``
+as the ``minimum_page`` value::
+
+ (-1, '{base_name}/last/', '{base_name}/last/index.html'),
+
Translations
============
@@ -1123,10 +1134,11 @@ Ordering content
Defines how the articles (``articles_page.object_list`` in the template) are
sorted. Valid options are: metadata as a string (use ``reversed-`` prefix
- the reverse the sort order), special option ``'basename'`` which will use
- the basename of the file (without path) or a custom function to extract the
- sorting key from articles. The default value, ``'reversed-date'``, will sort
- articles by date in reverse order (i.e. newest article comes first).
+ to reverse the sort order), special option ``'basename'`` which will use
+ the basename of the file (without path), or a custom function to extract the
+ sorting key from articles. Using a value of ``'date'`` will sort articles in
+ chronological order, while the default value, ``'reversed-date'``, will sort
+ articles by date in reverse order (i.e., newest article comes first).
.. data:: PAGE_ORDER_BY = 'basename'
diff --git a/pelican/__init__.py b/pelican/__init__.py
index 3339f0b6..acaec61f 100644
--- a/pelican/__init__.py
+++ b/pelican/__init__.py
@@ -20,10 +20,10 @@ from pelican.generators import (ArticlesGenerator, # noqa: I100
PagesGenerator, SourceFileGenerator,
StaticGenerator, TemplatePagesGenerator)
from pelican.plugins import signals
-from pelican.plugins._utils import load_plugins
+from pelican.plugins._utils import get_plugin_name, load_plugins
from pelican.readers import Readers
from pelican.server import ComplexHTTPRequestHandler, RootedHTTPServer
-from pelican.settings import read_settings
+from pelican.settings import coerce_overrides, read_settings
from pelican.utils import (FileSystemWatcher, clean_output_dir, maybe_pluralize)
from pelican.writers import Writer
@@ -65,14 +65,18 @@ class Pelican:
sys.path.insert(0, '')
def init_plugins(self):
- self.plugins = load_plugins(self.settings)
- for plugin in self.plugins:
- logger.debug('Registering plugin `%s`', plugin.__name__)
+ self.plugins = []
+ for plugin in load_plugins(self.settings):
+ name = get_plugin_name(plugin)
+ logger.debug('Registering plugin `%s`', name)
try:
plugin.register()
+ self.plugins.append(plugin)
except Exception as e:
logger.error('Cannot register plugin `%s`\n%s',
- plugin.__name__, e)
+ name, e)
+
+ self.settings['PLUGINS'] = [get_plugin_name(p) for p in self.plugins]
def run(self):
"""Run the generators and return"""
@@ -93,7 +97,7 @@ class Pelican:
path=self.path,
theme=self.theme,
output_path=self.output_path,
- ) for cls in self.get_generator_classes()
+ ) for cls in self._get_generator_classes()
]
# Delete the output directory if (1) the appropriate setting is True
@@ -114,7 +118,7 @@ class Pelican:
signals.all_generators_finalized.send(generators)
- writer = self.get_writer()
+ writer = self._get_writer()
for p in generators:
if hasattr(p, 'generate_output'):
@@ -168,46 +172,57 @@ class Pelican:
pluralized_draft_pages,
time.time() - start_time))
- def get_generator_classes(self):
- generators = [ArticlesGenerator, PagesGenerator]
+ def _get_generator_classes(self):
+ discovered_generators = [
+ (ArticlesGenerator, "internal"),
+ (PagesGenerator, "internal")
+ ]
- if self.settings['TEMPLATE_PAGES']:
- generators.append(TemplatePagesGenerator)
- if self.settings['OUTPUT_SOURCES']:
- generators.append(SourceFileGenerator)
+ if self.settings["TEMPLATE_PAGES"]:
+ discovered_generators.append((TemplatePagesGenerator, "internal"))
- for pair in signals.get_generators.send(self):
- (funct, value) = pair
+ if self.settings["OUTPUT_SOURCES"]:
+ discovered_generators.append((SourceFileGenerator, "internal"))
- if not isinstance(value, Iterable):
- value = (value, )
-
- for v in value:
- if isinstance(v, type):
- logger.debug('Found generator: %s', v)
- generators.append(v)
+ for receiver, values in signals.get_generators.send(self):
+ if not isinstance(values, Iterable):
+ values = (values,)
+ for generator in values:
+ if generator is None:
+ continue # plugin did not return a generator
+ discovered_generators.append((generator, receiver.__module__))
# StaticGenerator must run last, so it can identify files that
# were skipped by the other generators, and so static files can
# have their output paths overridden by the {attach} link syntax.
- generators.append(StaticGenerator)
+ discovered_generators.append((StaticGenerator, "internal"))
+
+ generators = []
+
+ for generator, origin in discovered_generators:
+ if not isinstance(generator, type):
+ logger.error("Generator %s (%s) cannot be loaded", generator, origin)
+ continue
+
+ logger.debug("Found generator: %s (%s)", generator.__name__, origin)
+ generators.append(generator)
+
return generators
- def get_writer(self):
- writers = [w for (_, w) in signals.get_writer.send(self)
- if isinstance(w, type)]
- writers_found = len(writers)
- if writers_found == 0:
+ def _get_writer(self):
+ writers = [w for _, w in signals.get_writer.send(self) if isinstance(w, type)]
+ num_writers = len(writers)
+
+ if num_writers == 0:
return Writer(self.output_path, settings=self.settings)
- else:
- writer = writers[0]
- if writers_found == 1:
- logger.debug('Found writer: %s', writer)
- else:
- logger.warning(
- '%s writers found, using only first one: %s',
- writers_found, writer)
- return writer(self.output_path, settings=self.settings)
+
+ if num_writers > 1:
+ logger.warning("%s writers found, using only first one", num_writers)
+
+ writer = writers[0]
+
+ logger.debug("Found writer: %s", writer)
+ return writer(self.output_path, settings=self.settings)
class PrintSettings(argparse.Action):
@@ -236,6 +251,18 @@ class PrintSettings(argparse.Action):
parser.exit()
+class ParseDict(argparse.Action):
+ def __call__(self, parser, namespace, values, option_string=None):
+ d = {}
+ if values:
+ for item in values:
+ split_items = item.split("=", 1)
+ key = split_items[0].strip()
+ value = split_items[1].strip()
+ d[key] = value
+ setattr(namespace, self.dest, d)
+
+
def parse_arguments(argv=None):
parser = argparse.ArgumentParser(
description='A tool to generate a static blog, '
@@ -329,6 +356,16 @@ def parse_arguments(argv=None):
help='IP to bind to when serving files via HTTP '
'(default: 127.0.0.1)')
+ parser.add_argument('-e', '--extra-settings', dest='overrides',
+ help='Specify one or more SETTING=VALUE pairs to '
+ 'override settings. If VALUE contains spaces, '
+ 'add quotes: SETTING="VALUE". Values other than '
+ 'integers and strings can be specified via JSON '
+ 'notation. (e.g., SETTING=none)',
+ nargs='*',
+ action=ParseDict
+ )
+
args = parser.parse_args(argv)
if args.port is not None and not args.listen:
@@ -364,6 +401,7 @@ def get_config(args):
if args.bind is not None:
config['BIND'] = args.bind
config['DEBUG'] = args.verbosity == logging.DEBUG
+ config.update(coerce_overrides(args.overrides))
return config
@@ -441,7 +479,7 @@ def listen(server, port, output, excqueue=None):
return
try:
- print("\nServing site at: {}:{} - Tap CTRL-C to stop".format(
+ print("\nServing site at: http://{}:{} - Tap CTRL-C to stop".format(
server, port))
httpd.serve_forever()
except Exception as e:
diff --git a/pelican/contents.py b/pelican/contents.py
index aa22311d..1740df88 100644
--- a/pelican/contents.py
+++ b/pelican/contents.py
@@ -4,7 +4,8 @@ import locale
import logging
import os
import re
-from urllib.parse import urljoin, urlparse, urlunparse
+from html import unescape
+from urllib.parse import unquote, urljoin, urlparse, urlunparse
import pytz
@@ -250,38 +251,55 @@ class Content:
# XXX Put this in a different location.
if what in {'filename', 'static', 'attach'}:
- if path.startswith('/'):
- path = path[1:]
+ def _get_linked_content(key, url):
+ nonlocal value
+
+ def _find_path(path):
+ if path.startswith('/'):
+ path = path[1:]
+ else:
+ # relative to the source path of this content
+ path = self.get_relative_source_path(
+ os.path.join(self.relative_dir, path)
+ )
+ return self._context[key].get(path, None)
+
+ # try path
+ result = _find_path(url.path)
+ if result is not None:
+ return result
+
+ # try unquoted path
+ result = _find_path(unquote(url.path))
+ if result is not None:
+ return result
+
+ # try html unescaped url
+ unescaped_url = urlparse(unescape(url.geturl()))
+ result = _find_path(unescaped_url.path)
+ if result is not None:
+ value = unescaped_url
+ return result
+
+ # check if a static file is linked with {filename}
+ if what == 'filename' and key == 'generated_content':
+ linked_content = _get_linked_content('static_content', value)
+ if linked_content:
+ logger.warning(
+ '{filename} used for linking to static'
+ ' content %s in %s. Use {static} instead',
+ value.path,
+ self.get_relative_source_path())
+ return linked_content
+
+ return None
+
+ if what == 'filename':
+ key = 'generated_content'
else:
- # relative to the source path of this content
- path = self.get_relative_source_path(
- os.path.join(self.relative_dir, path)
- )
+ key = 'static_content'
- key = 'static_content' if what in ('static', 'attach')\
- else 'generated_content'
-
- def _get_linked_content(key, path):
- try:
- return self._context[key][path]
- except KeyError:
- try:
- # Markdown escapes spaces, try unescaping
- return self._context[key][path.replace('%20', ' ')]
- except KeyError:
- if what == 'filename' and key == 'generated_content':
- key = 'static_content'
- linked_content = _get_linked_content(key, path)
- if linked_content:
- logger.warning(
- '{filename} used for linking to static'
- ' content %s in %s. Use {static} instead',
- path,
- self.get_relative_source_path())
- return linked_content
- return None
-
- linked_content = _get_linked_content(key, path)
+ linked_content = _get_linked_content(key, value)
if linked_content:
if what == 'attach':
linked_content.attach_to(self)
@@ -392,7 +410,7 @@ class Content:
return truncate_html_words(self.content,
self.settings['SUMMARY_MAX_LENGTH'],
- self.settings['SUMMARY_END_MARKER'])
+ self.settings['SUMMARY_END_SUFFIX'])
@property
def summary(self):
diff --git a/pelican/paginator.py b/pelican/paginator.py
index 9d169045..7e738fe3 100644
--- a/pelican/paginator.py
+++ b/pelican/paginator.py
@@ -118,8 +118,13 @@ class Page:
# find the last matching pagination rule
for p in self.settings['PAGINATION_PATTERNS']:
- if p.min_page <= self.number:
- rule = p
+ if p.min_page == -1:
+ if not self.has_next():
+ rule = p
+ break
+ else:
+ if p.min_page <= self.number:
+ rule = p
if not rule:
return ''
diff --git a/pelican/plugins/_utils.py b/pelican/plugins/_utils.py
index 78c19e54..87877b08 100644
--- a/pelican/plugins/_utils.py
+++ b/pelican/plugins/_utils.py
@@ -1,6 +1,7 @@
import importlib
import importlib.machinery
import importlib.util
+import inspect
import logging
import pkgutil
import sys
@@ -40,6 +41,11 @@ def list_plugins(ns_pkg=None):
def load_legacy_plugin(plugin, plugin_paths):
+ if '.' in plugin:
+ # it is in a package, try to resolve package first
+ package, _, _ = plugin.rpartition('.')
+ load_legacy_plugin(package, plugin_paths)
+
# Try to find plugin in PLUGIN_PATHS
spec = importlib.machinery.PathFinder.find_spec(plugin, plugin_paths)
if spec is None:
@@ -48,6 +54,9 @@ def load_legacy_plugin(plugin, plugin_paths):
if spec is None:
raise ImportError('Cannot import plugin `{}`'.format(plugin))
else:
+ # Avoid loading the same plugin twice
+ if spec.name in sys.modules:
+ return sys.modules[spec.name]
# create module object from spec
mod = importlib.util.module_from_spec(spec)
# place it into sys.modules cache
@@ -99,3 +108,18 @@ def load_plugins(settings):
plugins = list(namespace_plugins.values())
return plugins
+
+
+def get_plugin_name(plugin):
+ """
+ Plugins can be passed as module objects, however this breaks caching as
+ module objects cannot be pickled. To work around this, all plugins are
+ stringified post-initialization.
+ """
+ if inspect.isclass(plugin):
+ return plugin.__qualname__
+
+ if inspect.ismodule(plugin):
+ return plugin.__name__
+
+ return type(plugin).__qualname__
diff --git a/pelican/readers.py b/pelican/readers.py
index 8c108510..15d09908 100644
--- a/pelican/readers.py
+++ b/pelican/readers.py
@@ -227,7 +227,7 @@ class RstReader(BaseReader):
if element.tagname == 'field': # custom fields (e.g. summary)
name_elem, body_elem = element.children
name = name_elem.astext()
- if name in formatted_fields:
+ if name.lower() in formatted_fields:
value = render_node_to_html(
document, body_elem,
self.field_body_translator_class)
diff --git a/pelican/settings.py b/pelican/settings.py
index 7b333de8..ea3ee8eb 100644
--- a/pelican/settings.py
+++ b/pelican/settings.py
@@ -1,6 +1,7 @@
import copy
import importlib.util
import inspect
+import json
import locale
import logging
import os
@@ -135,7 +136,7 @@ DEFAULT_CONFIG = {
'TYPOGRIFY': False,
'TYPOGRIFY_IGNORE_TAGS': [],
'TYPOGRIFY_DASHES': 'default',
- 'SUMMARY_END_MARKER': '…',
+ 'SUMMARY_END_SUFFIX': '…',
'SUMMARY_MAX_LENGTH': 50,
'PLUGIN_PATHS': [],
'PLUGINS': None,
@@ -658,3 +659,25 @@ def configure_settings(settings):
continue # setting not specified, nothing to do
return settings
+
+
+def coerce_overrides(overrides):
+ if overrides is None:
+ return {}
+ coerced = {}
+ types_to_cast = {int, str, bool}
+ for k, v in overrides.items():
+ if k not in DEFAULT_CONFIG:
+ logger.warning('Override for unknown setting %s, ignoring', k)
+ continue
+ setting_type = type(DEFAULT_CONFIG[k])
+ if setting_type not in types_to_cast:
+ coerced[k] = json.loads(v)
+ else:
+ try:
+ coerced[k] = setting_type(v)
+ except ValueError:
+ logger.debug('ValueError for %s override with %s, try to '
+ 'load as json', k, v)
+ coerced[k] = json.loads(v)
+ return coerced
diff --git a/pelican/signals.py b/pelican/signals.py
new file mode 100644
index 00000000..9b84a92a
--- /dev/null
+++ b/pelican/signals.py
@@ -0,0 +1,4 @@
+raise ImportError(
+ 'Importing from `pelican.signals` is deprecated. '
+ 'Use `from pelican import signals` or `import pelican.plugins.signals` instead.'
+)
diff --git a/pelican/tests/content/article_with_capitalized_metadata.rst b/pelican/tests/content/article_with_capitalized_metadata.rst
new file mode 100644
index 00000000..93ed5b15
--- /dev/null
+++ b/pelican/tests/content/article_with_capitalized_metadata.rst
@@ -0,0 +1,16 @@
+
+This is a super article !
+#########################
+
+:TAGS: foo, bar, foobar
+:DATE: 2010-12-02 10:14
+:MODIFIED: 2010-12-02 10:20
+:CATEGORY: yeah
+:AUTHOR: Alexis Métaireau
+:SUMMARY:
+ Multi-line metadata should be supported
+ as well as **inline markup** and stuff to "typogrify"...
+:CUSTOM_FIELD: http://notmyidea.org
+:CUSTOM_FORMATTED_FIELD:
+ Multi-line metadata should also be supported
+ as well as *inline markup* and stuff to "typogrify"...
diff --git a/pelican/tests/dummy_plugins/normal_plugin/normal_plugin/__init__.py b/pelican/tests/dummy_plugins/normal_plugin/normal_plugin/__init__.py
index 5838a835..e714c7a6 100644
--- a/pelican/tests/dummy_plugins/normal_plugin/normal_plugin/__init__.py
+++ b/pelican/tests/dummy_plugins/normal_plugin/normal_plugin/__init__.py
@@ -1,7 +1,5 @@
from .submodule import noop # noqa: F401
-NAME = 'normal plugin'
-
def register():
pass
diff --git a/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/__init__.py b/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subpackage/__init__.py b/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subpackage/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subpackage/subpackage.py b/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subpackage/subpackage.py
new file mode 100644
index 00000000..9e12b19f
--- /dev/null
+++ b/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subpackage/subpackage.py
@@ -0,0 +1,2 @@
+def register():
+ pass
diff --git a/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subplugin.py b/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subplugin.py
new file mode 100644
index 00000000..9e12b19f
--- /dev/null
+++ b/pelican/tests/dummy_plugins/normal_plugin/normal_submodule_plugin/subplugin.py
@@ -0,0 +1,2 @@
+def register():
+ pass
diff --git a/pelican/tests/output/basic/category/misc.html b/pelican/tests/output/basic/category/misc.html
index 4f597888..119f5931 100644
--- a/pelican/tests/output/basic/category/misc.html
+++ b/pelican/tests/output/basic/category/misc.html
@@ -81,7 +81,7 @@
a file-relative link to markdown-article
Testing sourcecode directive
-
| formatter = self.options and VARIANTS[self.options.keys()[0]]
+ | formatter = self.options and VARIANTS[self.options.keys()[0]]
|
diff --git a/pelican/tests/output/basic/feeds/all-en.atom.xml b/pelican/tests/output/basic/feeds/all-en.atom.xml
index f59ea651..250d75db 100644
--- a/pelican/tests/output/basic/feeds/all-en.atom.xml
+++ b/pelican/tests/output/basic/feeds/all-en.atom.xml
@@ -31,7 +31,7 @@ YEAH !</p>
<a class="reference external" href="/a-markdown-powered-article.html">a file-relative link to markdown-article</a></p>
<div class="section" id="testing-sourcecode-directive">
<h2>Testing sourcecode directive</h2>
-<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
+<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
</pre></div>
</td></tr></table></div>
<div class="section" id="testing-another-case">
@@ -42,7 +42,7 @@ pelican.conf, it will …</p></div> &l
<a class="reference external" href="/a-markdown-powered-article.html">a file-relative link to markdown-article</a></p>
<div class="section" id="testing-sourcecode-directive">
<h2>Testing sourcecode directive</h2>
-<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
+<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
</pre></div>
</td></tr></table></div>
<div class="section" id="testing-another-case">
@@ -55,7 +55,7 @@ pelican.conf, it will have nothing in default.</p>
</div>
<div class="section" id="testing-more-sourcecode-directives">
<h2>Testing more sourcecode directives</h2>
-<div class="highlight"><pre><span></span><span id="foo-8"><a name="foo-8"></a><span class="lineno special"> 8 </span><span class="testingk">def</span> <span class="testingnf">run</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingp">):</span><br></span><span id="foo-9"><a name="foo-9"></a><span class="lineno"> </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">assert_has_content</span><span class="testingp">()</span><br></span><span id="foo-10"><a name="foo-10"></a><span class="lineno special">10 </span> <span class="testingk">try</span><span class="testingp">:</span><br></span><span id="foo-11"><a name="foo-11"></a><span class="lineno"> </span> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">get_lexer_by_name</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">arguments</span><span class="testingp">[</span><span class="testingmi">0</span><span class="testingp">])</span><br></span><span id="foo-12"><a name="foo-12"></a><span class="lineno special">12 </span> <span class="testingk">except</span> <span class="testingne">ValueError</span><span class="testingp">:</span><br></span><span id="foo-13"><a name="foo-13"></a><span class="lineno"> </span> <span class="testingc1"># no lexer found - use the text one instead of an exception</span><br></span><span id="foo-14"><a name="foo-14"></a><span class="lineno special">14 </span> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">TextLexer</span><span class="testingp">()</span><br></span><span id="foo-15"><a name="foo-15"></a><span class="lineno"> </span><br></span><span id="foo-16"><a name="foo-16"></a><span class="lineno special">16 </span> <span class="testingk">if</span> <span class="testingp">(</span><span class="testings1">'linenos'</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span> <span class="testingow">and</span><br></span><span id="foo-17"><a name="foo-17"></a><span class="lineno"> </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'table'</span><span class="testingp">,</span> <span class="testings1">'inline'</span><span class="testingp">)):</span><br></span><span id="foo-18"><a name="foo-18"></a><span class="lineno special">18 </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings1">'table'</span><br></span><span id="foo-19"><a name="foo-19"></a><span class="lineno"> </span><br></span><span id="foo-20"><a name="foo-20"></a><span class="lineno special">20 </span> <span class="testingk">for</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'nowrap'</span><span class="testingp">,</span> <span class="testings1">'nobackground'</span><span class="testingp">,</span> <span class="testings1">'anchorlinenos'</span><span class="testingp">):</span><br></span><span id="foo-21"><a name="foo-21"></a><span class="lineno"> </span> <span class="testingk">if</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">:</span><br></span><span id="foo-22"><a name="foo-22"></a><span class="lineno special">22 </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testingn">flag</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testingkc">True</span><br></span><span id="foo-23"><a name="foo-23"></a><span class="lineno"> </span><br></span><span id="foo-24"><a name="foo-24"></a><span class="lineno special">24 </span> <span class="testingc1"># noclasses should already default to False, but just in case...</span><br></span><span id="foo-25"><a name="foo-25"></a><span class="lineno"> </span> <span class="testingn">formatter</span> <span class="testingo">=</span> <span class="testingn">HtmlFormatter</span><span class="testingp">(</span><span class="testingn">noclasses</span><span class="testingo">=</span><span class="testingkc">False</span><span class="testingp">,</span> <span class="testingo">**</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">)</span><br></span><span id="foo-26"><a name="foo-26"></a><span class="lineno special">26 </span> <span class="testingn">parsed</span> <span class="testingo">=</span> <span class="testingn">highlight</span><span class="testingp">(</span><span class="testings1">'</span><span class="testingse">\n</span><span class="testings1">'</span><span class="testingo">.</span><span class="testingn">join</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">content</span><span class="testingp">),</span> <span class="testingn">lexer</span><span class="testingp">,</span> <span class="testingn">formatter</span><span class="testingp">)</span><br></span><span id="foo-27"><a name="foo-27"></a><span class="lineno"> </span> <span class="testingk">return</span> <span class="testingp">[</span><span class="testingn">nodes</span><span class="testingo">.</span><span class="testingn">raw</span><span class="testingp">(</span><span class="testings1">''</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingnb">format</span><span class="testingo">=</span><span class="testings1">'html'</span><span class="testingp">)]</span><br></span></pre></div>
+<div class="highlight"><pre><span></span><span id="foo-8"><a name="foo-8"></a><a href="#foo-8"><span class="linenos special"> 8</span></a><span class="testingk">def</span> <span class="testingnf">run</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingp">):</span><br></span><span id="foo-9"><a name="foo-9"></a><a href="#foo-9"><span class="linenos"> </span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">assert_has_content</span><span class="testingp">()</span><br></span><span id="foo-10"><a name="foo-10"></a><a href="#foo-10"><span class="linenos special">10</span></a> <span class="testingk">try</span><span class="testingp">:</span><br></span><span id="foo-11"><a name="foo-11"></a><a href="#foo-11"><span class="linenos"> </span></a> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">get_lexer_by_name</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">arguments</span><span class="testingp">[</span><span class="testingmi">0</span><span class="testingp">])</span><br></span><span id="foo-12"><a name="foo-12"></a><a href="#foo-12"><span class="linenos special">12</span></a> <span class="testingk">except</span> <span class="testingne">ValueError</span><span class="testingp">:</span><br></span><span id="foo-13"><a name="foo-13"></a><a href="#foo-13"><span class="linenos"> </span></a> <span class="testingc1"># no lexer found - use the text one instead of an exception</span><br></span><span id="foo-14"><a name="foo-14"></a><a href="#foo-14"><span class="linenos special">14</span></a> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">TextLexer</span><span class="testingp">()</span><br></span><span id="foo-15"><a name="foo-15"></a><a href="#foo-15"><span class="linenos"> </span></a><br></span><span id="foo-16"><a name="foo-16"></a><a href="#foo-16"><span class="linenos special">16</span></a> <span class="testingk">if</span> <span class="testingp">(</span><span class="testings1">'linenos'</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span> <span class="testingow">and</span><br></span><span id="foo-17"><a name="foo-17"></a><a href="#foo-17"><span class="linenos"> </span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'table'</span><span class="testingp">,</span> <span class="testings1">'inline'</span><span class="testingp">)):</span><br></span><span id="foo-18"><a name="foo-18"></a><a href="#foo-18"><span class="linenos special">18</span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings1">'table'</span><br></span><span id="foo-19"><a name="foo-19"></a><a href="#foo-19"><span class="linenos"> </span></a><br></span><span id="foo-20"><a name="foo-20"></a><a href="#foo-20"><span class="linenos special">20</span></a> <span class="testingk">for</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'nowrap'</span><span class="testingp">,</span> <span class="testings1">'nobackground'</span><span class="testingp">,</span> <span class="testings1">'anchorlinenos'</span><span class="testingp">):</span><br></span><span id="foo-21"><a name="foo-21"></a><a href="#foo-21"><span class="linenos"> </span></a> <span class="testingk">if</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">:</span><br></span><span id="foo-22"><a name="foo-22"></a><a href="#foo-22"><span class="linenos special">22</span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testingn">flag</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testingkc">True</span><br></span><span id="foo-23"><a name="foo-23"></a><a href="#foo-23"><span class="linenos"> </span></a><br></span><span id="foo-24"><a name="foo-24"></a><a href="#foo-24"><span class="linenos special">24</span></a> <span class="testingc1"># noclasses should already default to False, but just in case...</span><br></span><span id="foo-25"><a name="foo-25"></a><a href="#foo-25"><span class="linenos"> </span></a> <span class="testingn">formatter</span> <span class="testingo">=</span> <span class="testingn">HtmlFormatter</span><span class="testingp">(</span><span class="testingn">noclasses</span><span class="testingo">=</span><span class="testingkc">False</span><span class="testingp">,</span> <span class="testingo">**</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">)</span><br></span><span id="foo-26"><a name="foo-26"></a><a href="#foo-26"><span class="linenos special">26</span></a> <span class="testingn">parsed</span> <span class="testingo">=</span> <span class="testingn">highlight</span><span class="testingp">(</span><span class="testings1">'</span><span class="testingse">\n</span><span class="testings1">'</span><span class="testingo">.</span><span class="testingn">join</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">content</span><span class="testingp">),</span> <span class="testingn">lexer</span><span class="testingp">,</span> <span class="testingn">formatter</span><span class="testingp">)</span><br></span><span id="foo-27"><a name="foo-27"></a><a href="#foo-27"><span class="linenos"> </span></a> <span class="testingk">return</span> <span class="testingp">[</span><span class="testingn">nodes</span><span class="testingo">.</span><span class="testingn">raw</span><span class="testingp">(</span><span class="testings1">''</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingnb">format</span><span class="testingo">=</span><span class="testings1">'html'</span><span class="testingp">)]</span><br></span></pre></div>
<p>Lovely.</p>
</div>
<div class="section" id="testing-even-more-sourcecode-directives">
diff --git a/pelican/tests/output/basic/feeds/all.atom.xml b/pelican/tests/output/basic/feeds/all.atom.xml
index 7407d2ff..1abfef18 100644
--- a/pelican/tests/output/basic/feeds/all.atom.xml
+++ b/pelican/tests/output/basic/feeds/all.atom.xml
@@ -33,7 +33,7 @@ YEAH !</p>
<a class="reference external" href="/a-markdown-powered-article.html">a file-relative link to markdown-article</a></p>
<div class="section" id="testing-sourcecode-directive">
<h2>Testing sourcecode directive</h2>
-<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
+<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
</pre></div>
</td></tr></table></div>
<div class="section" id="testing-another-case">
@@ -44,7 +44,7 @@ pelican.conf, it will …</p></div>&l
<a class="reference external" href="/a-markdown-powered-article.html">a file-relative link to markdown-article</a></p>
<div class="section" id="testing-sourcecode-directive">
<h2>Testing sourcecode directive</h2>
-<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
+<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
</pre></div>
</td></tr></table></div>
<div class="section" id="testing-another-case">
@@ -57,7 +57,7 @@ pelican.conf, it will have nothing in default.</p>
</div>
<div class="section" id="testing-more-sourcecode-directives">
<h2>Testing more sourcecode directives</h2>
-<div class="highlight"><pre><span></span><span id="foo-8"><a name="foo-8"></a><span class="lineno special"> 8 </span><span class="testingk">def</span> <span class="testingnf">run</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingp">):</span><br></span><span id="foo-9"><a name="foo-9"></a><span class="lineno"> </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">assert_has_content</span><span class="testingp">()</span><br></span><span id="foo-10"><a name="foo-10"></a><span class="lineno special">10 </span> <span class="testingk">try</span><span class="testingp">:</span><br></span><span id="foo-11"><a name="foo-11"></a><span class="lineno"> </span> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">get_lexer_by_name</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">arguments</span><span class="testingp">[</span><span class="testingmi">0</span><span class="testingp">])</span><br></span><span id="foo-12"><a name="foo-12"></a><span class="lineno special">12 </span> <span class="testingk">except</span> <span class="testingne">ValueError</span><span class="testingp">:</span><br></span><span id="foo-13"><a name="foo-13"></a><span class="lineno"> </span> <span class="testingc1"># no lexer found - use the text one instead of an exception</span><br></span><span id="foo-14"><a name="foo-14"></a><span class="lineno special">14 </span> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">TextLexer</span><span class="testingp">()</span><br></span><span id="foo-15"><a name="foo-15"></a><span class="lineno"> </span><br></span><span id="foo-16"><a name="foo-16"></a><span class="lineno special">16 </span> <span class="testingk">if</span> <span class="testingp">(</span><span class="testings1">'linenos'</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span> <span class="testingow">and</span><br></span><span id="foo-17"><a name="foo-17"></a><span class="lineno"> </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'table'</span><span class="testingp">,</span> <span class="testings1">'inline'</span><span class="testingp">)):</span><br></span><span id="foo-18"><a name="foo-18"></a><span class="lineno special">18 </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings1">'table'</span><br></span><span id="foo-19"><a name="foo-19"></a><span class="lineno"> </span><br></span><span id="foo-20"><a name="foo-20"></a><span class="lineno special">20 </span> <span class="testingk">for</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'nowrap'</span><span class="testingp">,</span> <span class="testings1">'nobackground'</span><span class="testingp">,</span> <span class="testings1">'anchorlinenos'</span><span class="testingp">):</span><br></span><span id="foo-21"><a name="foo-21"></a><span class="lineno"> </span> <span class="testingk">if</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">:</span><br></span><span id="foo-22"><a name="foo-22"></a><span class="lineno special">22 </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testingn">flag</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testingkc">True</span><br></span><span id="foo-23"><a name="foo-23"></a><span class="lineno"> </span><br></span><span id="foo-24"><a name="foo-24"></a><span class="lineno special">24 </span> <span class="testingc1"># noclasses should already default to False, but just in case...</span><br></span><span id="foo-25"><a name="foo-25"></a><span class="lineno"> </span> <span class="testingn">formatter</span> <span class="testingo">=</span> <span class="testingn">HtmlFormatter</span><span class="testingp">(</span><span class="testingn">noclasses</span><span class="testingo">=</span><span class="testingkc">False</span><span class="testingp">,</span> <span class="testingo">**</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">)</span><br></span><span id="foo-26"><a name="foo-26"></a><span class="lineno special">26 </span> <span class="testingn">parsed</span> <span class="testingo">=</span> <span class="testingn">highlight</span><span class="testingp">(</span><span class="testings1">'</span><span class="testingse">\n</span><span class="testings1">'</span><span class="testingo">.</span><span class="testingn">join</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">content</span><span class="testingp">),</span> <span class="testingn">lexer</span><span class="testingp">,</span> <span class="testingn">formatter</span><span class="testingp">)</span><br></span><span id="foo-27"><a name="foo-27"></a><span class="lineno"> </span> <span class="testingk">return</span> <span class="testingp">[</span><span class="testingn">nodes</span><span class="testingo">.</span><span class="testingn">raw</span><span class="testingp">(</span><span class="testings1">''</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingnb">format</span><span class="testingo">=</span><span class="testings1">'html'</span><span class="testingp">)]</span><br></span></pre></div>
+<div class="highlight"><pre><span></span><span id="foo-8"><a name="foo-8"></a><a href="#foo-8"><span class="linenos special"> 8</span></a><span class="testingk">def</span> <span class="testingnf">run</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingp">):</span><br></span><span id="foo-9"><a name="foo-9"></a><a href="#foo-9"><span class="linenos"> </span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">assert_has_content</span><span class="testingp">()</span><br></span><span id="foo-10"><a name="foo-10"></a><a href="#foo-10"><span class="linenos special">10</span></a> <span class="testingk">try</span><span class="testingp">:</span><br></span><span id="foo-11"><a name="foo-11"></a><a href="#foo-11"><span class="linenos"> </span></a> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">get_lexer_by_name</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">arguments</span><span class="testingp">[</span><span class="testingmi">0</span><span class="testingp">])</span><br></span><span id="foo-12"><a name="foo-12"></a><a href="#foo-12"><span class="linenos special">12</span></a> <span class="testingk">except</span> <span class="testingne">ValueError</span><span class="testingp">:</span><br></span><span id="foo-13"><a name="foo-13"></a><a href="#foo-13"><span class="linenos"> </span></a> <span class="testingc1"># no lexer found - use the text one instead of an exception</span><br></span><span id="foo-14"><a name="foo-14"></a><a href="#foo-14"><span class="linenos special">14</span></a> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">TextLexer</span><span class="testingp">()</span><br></span><span id="foo-15"><a name="foo-15"></a><a href="#foo-15"><span class="linenos"> </span></a><br></span><span id="foo-16"><a name="foo-16"></a><a href="#foo-16"><span class="linenos special">16</span></a> <span class="testingk">if</span> <span class="testingp">(</span><span class="testings1">'linenos'</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span> <span class="testingow">and</span><br></span><span id="foo-17"><a name="foo-17"></a><a href="#foo-17"><span class="linenos"> </span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'table'</span><span class="testingp">,</span> <span class="testings1">'inline'</span><span class="testingp">)):</span><br></span><span id="foo-18"><a name="foo-18"></a><a href="#foo-18"><span class="linenos special">18</span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings1">'table'</span><br></span><span id="foo-19"><a name="foo-19"></a><a href="#foo-19"><span class="linenos"> </span></a><br></span><span id="foo-20"><a name="foo-20"></a><a href="#foo-20"><span class="linenos special">20</span></a> <span class="testingk">for</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'nowrap'</span><span class="testingp">,</span> <span class="testings1">'nobackground'</span><span class="testingp">,</span> <span class="testings1">'anchorlinenos'</span><span class="testingp">):</span><br></span><span id="foo-21"><a name="foo-21"></a><a href="#foo-21"><span class="linenos"> </span></a> <span class="testingk">if</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">:</span><br></span><span id="foo-22"><a name="foo-22"></a><a href="#foo-22"><span class="linenos special">22</span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testingn">flag</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testingkc">True</span><br></span><span id="foo-23"><a name="foo-23"></a><a href="#foo-23"><span class="linenos"> </span></a><br></span><span id="foo-24"><a name="foo-24"></a><a href="#foo-24"><span class="linenos special">24</span></a> <span class="testingc1"># noclasses should already default to False, but just in case...</span><br></span><span id="foo-25"><a name="foo-25"></a><a href="#foo-25"><span class="linenos"> </span></a> <span class="testingn">formatter</span> <span class="testingo">=</span> <span class="testingn">HtmlFormatter</span><span class="testingp">(</span><span class="testingn">noclasses</span><span class="testingo">=</span><span class="testingkc">False</span><span class="testingp">,</span> <span class="testingo">**</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">)</span><br></span><span id="foo-26"><a name="foo-26"></a><a href="#foo-26"><span class="linenos special">26</span></a> <span class="testingn">parsed</span> <span class="testingo">=</span> <span class="testingn">highlight</span><span class="testingp">(</span><span class="testings1">'</span><span class="testingse">\n</span><span class="testings1">'</span><span class="testingo">.</span><span class="testingn">join</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">content</span><span class="testingp">),</span> <span class="testingn">lexer</span><span class="testingp">,</span> <span class="testingn">formatter</span><span class="testingp">)</span><br></span><span id="foo-27"><a name="foo-27"></a><a href="#foo-27"><span class="linenos"> </span></a> <span class="testingk">return</span> <span class="testingp">[</span><span class="testingn">nodes</span><span class="testingo">.</span><span class="testingn">raw</span><span class="testingp">(</span><span class="testings1">''</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingnb">format</span><span class="testingo">=</span><span class="testings1">'html'</span><span class="testingp">)]</span><br></span></pre></div>
<p>Lovely.</p>
</div>
<div class="section" id="testing-even-more-sourcecode-directives">
diff --git a/pelican/tests/output/basic/feeds/misc.atom.xml b/pelican/tests/output/basic/feeds/misc.atom.xml
index a8243b48..2b09bda3 100644
--- a/pelican/tests/output/basic/feeds/misc.atom.xml
+++ b/pelican/tests/output/basic/feeds/misc.atom.xml
@@ -6,7 +6,7 @@
<a class="reference external" href="/a-markdown-powered-article.html">a file-relative link to markdown-article</a></p>
<div class="section" id="testing-sourcecode-directive">
<h2>Testing sourcecode directive</h2>
-<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
+<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
</pre></div>
</td></tr></table></div>
<div class="section" id="testing-another-case">
@@ -17,7 +17,7 @@ pelican.conf, it will …</p></div>&l
<a class="reference external" href="/a-markdown-powered-article.html">a file-relative link to markdown-article</a></p>
<div class="section" id="testing-sourcecode-directive">
<h2>Testing sourcecode directive</h2>
-<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
+<table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span><span class="n">formatter</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="ow">and</span> <span class="n">VARIANTS</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">keys</span><span class="p">()[</span><span class="mi">0</span><span class="p">]]</span>
</pre></div>
</td></tr></table></div>
<div class="section" id="testing-another-case">
@@ -30,7 +30,7 @@ pelican.conf, it will have nothing in default.</p>
</div>
<div class="section" id="testing-more-sourcecode-directives">
<h2>Testing more sourcecode directives</h2>
-<div class="highlight"><pre><span></span><span id="foo-8"><a name="foo-8"></a><span class="lineno special"> 8 </span><span class="testingk">def</span> <span class="testingnf">run</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingp">):</span><br></span><span id="foo-9"><a name="foo-9"></a><span class="lineno"> </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">assert_has_content</span><span class="testingp">()</span><br></span><span id="foo-10"><a name="foo-10"></a><span class="lineno special">10 </span> <span class="testingk">try</span><span class="testingp">:</span><br></span><span id="foo-11"><a name="foo-11"></a><span class="lineno"> </span> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">get_lexer_by_name</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">arguments</span><span class="testingp">[</span><span class="testingmi">0</span><span class="testingp">])</span><br></span><span id="foo-12"><a name="foo-12"></a><span class="lineno special">12 </span> <span class="testingk">except</span> <span class="testingne">ValueError</span><span class="testingp">:</span><br></span><span id="foo-13"><a name="foo-13"></a><span class="lineno"> </span> <span class="testingc1"># no lexer found - use the text one instead of an exception</span><br></span><span id="foo-14"><a name="foo-14"></a><span class="lineno special">14 </span> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">TextLexer</span><span class="testingp">()</span><br></span><span id="foo-15"><a name="foo-15"></a><span class="lineno"> </span><br></span><span id="foo-16"><a name="foo-16"></a><span class="lineno special">16 </span> <span class="testingk">if</span> <span class="testingp">(</span><span class="testings1">'linenos'</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span> <span class="testingow">and</span><br></span><span id="foo-17"><a name="foo-17"></a><span class="lineno"> </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'table'</span><span class="testingp">,</span> <span class="testings1">'inline'</span><span class="testingp">)):</span><br></span><span id="foo-18"><a name="foo-18"></a><span class="lineno special">18 </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings1">'table'</span><br></span><span id="foo-19"><a name="foo-19"></a><span class="lineno"> </span><br></span><span id="foo-20"><a name="foo-20"></a><span class="lineno special">20 </span> <span class="testingk">for</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'nowrap'</span><span class="testingp">,</span> <span class="testings1">'nobackground'</span><span class="testingp">,</span> <span class="testings1">'anchorlinenos'</span><span class="testingp">):</span><br></span><span id="foo-21"><a name="foo-21"></a><span class="lineno"> </span> <span class="testingk">if</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">:</span><br></span><span id="foo-22"><a name="foo-22"></a><span class="lineno special">22 </span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testingn">flag</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testingkc">True</span><br></span><span id="foo-23"><a name="foo-23"></a><span class="lineno"> </span><br></span><span id="foo-24"><a name="foo-24"></a><span class="lineno special">24 </span> <span class="testingc1"># noclasses should already default to False, but just in case...</span><br></span><span id="foo-25"><a name="foo-25"></a><span class="lineno"> </span> <span class="testingn">formatter</span> <span class="testingo">=</span> <span class="testingn">HtmlFormatter</span><span class="testingp">(</span><span class="testingn">noclasses</span><span class="testingo">=</span><span class="testingkc">False</span><span class="testingp">,</span> <span class="testingo">**</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">)</span><br></span><span id="foo-26"><a name="foo-26"></a><span class="lineno special">26 </span> <span class="testingn">parsed</span> <span class="testingo">=</span> <span class="testingn">highlight</span><span class="testingp">(</span><span class="testings1">'</span><span class="testingse">\n</span><span class="testings1">'</span><span class="testingo">.</span><span class="testingn">join</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">content</span><span class="testingp">),</span> <span class="testingn">lexer</span><span class="testingp">,</span> <span class="testingn">formatter</span><span class="testingp">)</span><br></span><span id="foo-27"><a name="foo-27"></a><span class="lineno"> </span> <span class="testingk">return</span> <span class="testingp">[</span><span class="testingn">nodes</span><span class="testingo">.</span><span class="testingn">raw</span><span class="testingp">(</span><span class="testings1">''</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingnb">format</span><span class="testingo">=</span><span class="testings1">'html'</span><span class="testingp">)]</span><br></span></pre></div>
+<div class="highlight"><pre><span></span><span id="foo-8"><a name="foo-8"></a><a href="#foo-8"><span class="linenos special"> 8</span></a><span class="testingk">def</span> <span class="testingnf">run</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingp">):</span><br></span><span id="foo-9"><a name="foo-9"></a><a href="#foo-9"><span class="linenos"> </span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">assert_has_content</span><span class="testingp">()</span><br></span><span id="foo-10"><a name="foo-10"></a><a href="#foo-10"><span class="linenos special">10</span></a> <span class="testingk">try</span><span class="testingp">:</span><br></span><span id="foo-11"><a name="foo-11"></a><a href="#foo-11"><span class="linenos"> </span></a> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">get_lexer_by_name</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">arguments</span><span class="testingp">[</span><span class="testingmi">0</span><span class="testingp">])</span><br></span><span id="foo-12"><a name="foo-12"></a><a href="#foo-12"><span class="linenos special">12</span></a> <span class="testingk">except</span> <span class="testingne">ValueError</span><span class="testingp">:</span><br></span><span id="foo-13"><a name="foo-13"></a><a href="#foo-13"><span class="linenos"> </span></a> <span class="testingc1"># no lexer found - use the text one instead of an exception</span><br></span><span id="foo-14"><a name="foo-14"></a><a href="#foo-14"><span class="linenos special">14</span></a> <span class="testingn">lexer</span> <span class="testingo">=</span> <span class="testingn">TextLexer</span><span class="testingp">()</span><br></span><span id="foo-15"><a name="foo-15"></a><a href="#foo-15"><span class="linenos"> </span></a><br></span><span id="foo-16"><a name="foo-16"></a><a href="#foo-16"><span class="linenos special">16</span></a> <span class="testingk">if</span> <span class="testingp">(</span><span class="testings1">'linenos'</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span> <span class="testingow">and</span><br></span><span id="foo-17"><a name="foo-17"></a><a href="#foo-17"><span class="linenos"> </span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'table'</span><span class="testingp">,</span> <span class="testings1">'inline'</span><span class="testingp">)):</span><br></span><span id="foo-18"><a name="foo-18"></a><a href="#foo-18"><span class="linenos special">18</span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testings1">'linenos'</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings1">'table'</span><br></span><span id="foo-19"><a name="foo-19"></a><a href="#foo-19"><span class="linenos"> </span></a><br></span><span id="foo-20"><a name="foo-20"></a><a href="#foo-20"><span class="linenos special">20</span></a> <span class="testingk">for</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings1">'nowrap'</span><span class="testingp">,</span> <span class="testings1">'nobackground'</span><span class="testingp">,</span> <span class="testings1">'anchorlinenos'</span><span class="testingp">):</span><br></span><span id="foo-21"><a name="foo-21"></a><a href="#foo-21"><span class="linenos"> </span></a> <span class="testingk">if</span> <span class="testingn">flag</span> <span class="testingow">in</span> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">:</span><br></span><span id="foo-22"><a name="foo-22"></a><a href="#foo-22"><span class="linenos special">22</span></a> <span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">[</span><span class="testingn">flag</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testingkc">True</span><br></span><span id="foo-23"><a name="foo-23"></a><a href="#foo-23"><span class="linenos"> </span></a><br></span><span id="foo-24"><a name="foo-24"></a><a href="#foo-24"><span class="linenos special">24</span></a> <span class="testingc1"># noclasses should already default to False, but just in case...</span><br></span><span id="foo-25"><a name="foo-25"></a><a href="#foo-25"><span class="linenos"> </span></a> <span class="testingn">formatter</span> <span class="testingo">=</span> <span class="testingn">HtmlFormatter</span><span class="testingp">(</span><span class="testingn">noclasses</span><span class="testingo">=</span><span class="testingkc">False</span><span class="testingp">,</span> <span class="testingo">**</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">options</span><span class="testingp">)</span><br></span><span id="foo-26"><a name="foo-26"></a><a href="#foo-26"><span class="linenos special">26</span></a> <span class="testingn">parsed</span> <span class="testingo">=</span> <span class="testingn">highlight</span><span class="testingp">(</span><span class="testings1">'</span><span class="testingse">\n</span><span class="testings1">'</span><span class="testingo">.</span><span class="testingn">join</span><span class="testingp">(</span><span class="testingbp">self</span><span class="testingo">.</span><span class="testingn">content</span><span class="testingp">),</span> <span class="testingn">lexer</span><span class="testingp">,</span> <span class="testingn">formatter</span><span class="testingp">)</span><br></span><span id="foo-27"><a name="foo-27"></a><a href="#foo-27"><span class="linenos"> </span></a> <span class="testingk">return</span> <span class="testingp">[</span><span class="testingn">nodes</span><span class="testingo">.</span><span class="testingn">raw</span><span class="testingp">(</span><span class="testings1">''</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingnb">format</span><span class="testingo">=</span><span class="testings1">'html'</span><span class="testingp">)]</span><br></span></pre></div>
<p>Lovely.</p>
</div>
<div class="section" id="testing-even-more-sourcecode-directives">
diff --git a/pelican/tests/output/basic/index.html b/pelican/tests/output/basic/index.html
index f215dc44..e10477db 100644
--- a/pelican/tests/output/basic/index.html
+++ b/pelican/tests/output/basic/index.html
@@ -220,7 +220,7 @@ YEAH !
a file-relative link to markdown-article
Testing sourcecode directive
- | formatter = self.options and VARIANTS[self.options.keys()[0]]
+ | formatter = self.options and VARIANTS[self.options.keys()[0]]
|
diff --git a/pelican/tests/output/basic/unbelievable.html b/pelican/tests/output/basic/unbelievable.html
index e0836d70..33e0ad53 100644
--- a/pelican/tests/output/basic/unbelievable.html
+++ b/pelican/tests/output/basic/unbelievable.html
@@ -43,7 +43,7 @@
a file-relative link to markdown-article
Testing sourcecode directive
- | formatter = self.options and VARIANTS[self.options.keys()[0]]
+ | formatter = self.options and VARIANTS[self.options.keys()[0]]
|
@@ -56,7 +56,7 @@ pelican.conf, it will have nothing in default.
Testing more sourcecode directives
- 8 def run(self): self.assert_has_content() 10 try: lexer = get_lexer_by_name(self.arguments[0]) 12 except ValueError: # no lexer found - use the text one instead of an exception 14 lexer = TextLexer() 16 if ('linenos' in self.options and self.options['linenos'] not in ('table', 'inline')): 18 self.options['linenos'] = 'table' 20 for flag in ('nowrap', 'nobackground', 'anchorlinenos'): if flag in self.options: 22 self.options[flag] = True 24 # noclasses should already default to False, but just in case... formatter = HtmlFormatter(noclasses=False, **self.options) 26 parsed = highlight('\n'.join(self.content), lexer, formatter) return [nodes.raw('', parsed, format='html')]
+ 8def run(self): self.assert_has_content() 10 try: lexer = get_lexer_by_name(self.arguments[0]) 12 except ValueError: # no lexer found - use the text one instead of an exception 14 lexer = TextLexer() 16 if ('linenos' in self.options and self.options['linenos'] not in ('table', 'inline')): 18 self.options['linenos'] = 'table' 20 for flag in ('nowrap', 'nobackground', 'anchorlinenos'): if flag in self.options: 22 self.options[flag] = True 24 # noclasses should already default to False, but just in case... formatter = HtmlFormatter(noclasses=False, **self.options) 26 parsed = highlight('\n'.join(self.content), lexer, formatter) return [nodes.raw('', parsed, format='html')]
Lovely.
diff --git a/pelican/tests/output/custom/author/alexis-metaireau.html b/pelican/tests/output/custom/author/alexis-metaireau.html
index 7a277e2c..f768b15e 100644
--- a/pelican/tests/output/custom/author/alexis-metaireau.html
+++ b/pelican/tests/output/custom/author/alexis-metaireau.html
@@ -168,4 +168,4 @@
}());
|
|
|