pelican-3.3/0000755000076500000240000000000012220367225012524 5ustar jmstaff00000000000000pelican-3.3/CONTRIBUTING.rst0000666000076500000240000000466312153236656015212 0ustar jmstaff00000000000000Contribution submission guidelines ================================== * Consider whether your new feature might be better suited as a plugin_. Folks are usually available in the `#pelican IRC channel`_ if help is needed to make that determination. * `Create a new git branch`_ specific to your change (as opposed to making your commits in the master branch). * **Don't put multiple fixes/features in the same branch / pull request.** For example, if you're hacking on a new feature and find a bugfix that doesn't *require* your new feature, **make a new distinct branch and pull request** for the bugfix. * Adhere to PEP8 coding standards whenever possible. * Check for unnecessary whitespace via ``git diff --check`` before committing. * **Add docs and tests for your changes**. * `Run all the tests`_ **on both Python 2.7 and 3.3** to ensure nothing was accidentally broken. * First line of your commit message should start with present-tense verb, be 50 characters or less, and include the relevant issue number(s) if applicable. *Example:* ``Ensure proper PLUGIN_PATH behavior. Refs #428.`` If the commit *completely fixes* an existing bug report, please use ``Fixes #585`` or ``Fix #585`` syntax (so the relevant issue is automatically closed upon PR merge). * After the first line of the commit message, add a blank line and then a more detailed explanation (when relevant). * If you have previously filed a GitHub issue and want to contribute code that addresses that issue, **please use** ``hub pull-request`` instead of using GitHub's web UI to submit the pull request. This isn't an absolute requirement, but makes the maintainers' lives much easier! Specifically: `install hub `_ and then run `hub pull-request `_ to turn your GitHub issue into a pull request containing your code. Check out our `Git Tips`_ page or ask on the `#pelican IRC channel`_ if you need assistance or have any questions about these guidelines. .. _`plugin`: http://docs.getpelican.com/en/latest/plugins.html .. _`#pelican IRC channel`: http://webchat.freenode.net/?channels=pelican&uio=d4 .. _`Create a new git branch`: https://github.com/getpelican/pelican/wiki/Git-Tips#making-your-changes .. _`Run all the tests`: http://docs.getpelican.com/en/latest/contribute.html#running-the-test-suite .. _`Git Tips`: https://github.com/getpelican/pelican/wiki/Git-Tips pelican-3.3/docs/0000755000076500000240000000000012220367225013454 5ustar jmstaff00000000000000pelican-3.3/docs/changelog.rst0000644000076500000240000001543112220367223016137 0ustar jmstaff00000000000000Release history ############### 3.3.0 (2013-09-24) ================== * Drop Python 3.2 support in favor of Python 3.3 * Add ``Fabfile`` so Fabric can be used for workflow automation instead of Make * ``OUTPUT_RETENTION`` setting can be used to preserve metadata (e.g., VCS data such as ``.hg`` and ``.git``) from being removed from output directory * Tumblr import * Improve logic and consistency when cleaning output folder * Improve documentation versioning and release automation * Improve pagination flexibility * Rename signals for better consistency (some plugins may need to be updated) * Move metadata extraction from generators to readers; metadata extraction no longer article-specific * Deprecate ``FILES_TO_COPY`` in favor of ``STATIC_PATHS`` and ``EXTRA_PATH_METADATA`` * Summaries in Markdown posts no longer include footnotes * Remove unnecessary whitespace in output via ``lstrip_blocks`` Jinja parameter * Move PDF generation from core to plugin * Replace ``MARKUP`` setting with ``READERS`` * Add warning if img tag is missing ``alt`` attribute * Add support for ``{}`` in relative links syntax, besides ``||`` * Add support for ``{tag}`` and ``{category}`` relative links * Add a ``content_written`` signal 3.2.1 and 3.2.2 =============== * Facilitate inclusion in FreeBSD Ports Collection 3.2 (2013-04-24) ================ * Support for Python 3! * Override page save-to location from meta-data (enables using a static page as the site's home page, for example) * Time period archives (per-year, per-month, and per-day archives of posts) * Posterous blog import * Improve WordPress blog import * Migrate plugins to separate repository * Improve HTML parser * Provide ability to show or hide categories from menu using ``DISPLAY_CATEGORIES_ON_MENU`` option * Auto-regeneration can be told to ignore files via ``IGNORE_FILES`` setting * Improve post-generation feedback to user * For multilingual posts, use meta-data to designate which is the original and which is the translation * Add ``.mdown`` to list of supported Markdown file extensions * Document-relative URL generation (``RELATIVE_URLS``) is now off by default 3.1 (2012-12-04) ================ * Importer now stores slugs within files by default. This can be disabled with the ``--disable-slugs`` option. * Improve handling of links to intra-site resources * Ensure WordPress import adds paragraphs for all types of line endings in post content * Decode HTML entities within WordPress post titles on import * Improve appearance of LinkedIn icon in default theme * Add GitHub and Google+ social icons support in default theme * Optimize social icons * Add ``FEED_ALL_ATOM`` and ``FEED_ALL_RSS`` to generate feeds containing all posts regardless of their language * Split ``TRANSLATION_FEED`` into ``TRANSLATION_FEED_ATOM`` and ``TRANSLATION_FEED_RSS`` * Different feeds can now be enabled/disabled individually * Allow for blank author: if ``AUTHOR`` setting is not set, author won't default to ``${USER}`` anymore, and a post won't contain any author information if the post author is empty * Move LESS and Webassets support from Pelican core to plugin * The ``DEFAULT_DATE`` setting now defaults to ``None``, which means that articles won't be generated unless date metadata is specified * Add ``FILENAME_METADATA`` setting to support metadata extraction from filename * Add ``gzip_cache`` plugin to compress common text files into a ``.gz`` file within the same directory as the original file, preventing the server (e.g. Nginx) from having to compress files during an HTTP call * Add support for AsciiDoc-formatted content * Add ``USE_FOLDER_AS_CATEGORY`` setting so that feature can be toggled on/off * Support arbitrary Jinja template files * Restore basic functional tests * New signals: ``generator_init``, ``get_generators``, and ``article_generate_preread`` 3.0 (2012-08-08) ================ * Refactored the way URLs are handled * Improved the English documentation * Fixed packaging using ``setuptools`` entrypoints * Added ``typogrify`` support * Added a way to disable feed generation * Added support for ``DIRECT_TEMPLATES`` * Allow multiple extensions for content files * Added LESS support * Improved the import script * Added functional tests * Rsync support in the generated Makefile * Improved feed support (easily pluggable with Feedburner for instance) * Added support for ``abbr`` in reST * Fixed a bunch of bugs :-) 2.8 (2012-02-28) ================== * Dotclear importer * Allow the usage of Markdown extensions * Themes are now easily extensible * Don't output pagination information if there is only one page * Add a page per author, with all their articles * Improved the test suite * Made the themes easier to extend * Removed Skribit support * Added a ``pelican-quickstart`` script * Fixed timezone-related issues * Added some scripts for Windows support * Date can be specified in seconds * Never fail when generating posts (skip and continue) * Allow the use of future dates * Support having different timezones per language * Enhanced the documentation 2.7 (2011-06-11) ================== * Use ``logging`` rather than echoing to stdout * Support custom Jinja filters * Compatibility with Python 2.5 * Added a theme manager * Packaged for Debian * Added draft support 2.6 (2011-03-08) ================== * Changes in the output directory structure * Makes templates easier to work with / create * Added RSS support (was Atom-only) * Added tag support for the feeds * Enhance the documentation * Added another theme (brownstone) * Added translations * Added a way to use cleaner URLs with a rewrite url module (or equivalent) * Added a tag cloud * Added an autoreloading feature: the blog is automatically regenerated each time a modification is detected * Translate the documentation into French * Import a blog from an RSS feed * Pagination support * Added Skribit support 2.5 (2010-11-20) ================== * Import from Wordpress * Added some new themes (martyalchin / wide-notmyidea) * First bug report! * Linkedin support * Added a FAQ * Google Analytics support * Twitter support * Use relative URLs, not static ones 2.4 (2010-11-06) ================ * Minor themes changes * Add Disqus support (so we have comments) * Another code refactoring * Added config settings about pages * Blog entries can also be generated in PDF 2.3 (2010-10-31) ================ * Markdown support 2.2 (2010-10-30) ================ * Prettify output * Manages static pages as well 2.1 (2010-10-30) ================ * Make notmyidea the default theme 2.0 (2010-10-30) ================ * Refactoring to be more extensible * Change into the setting variables 1.2 (2010-09-28) ================ * Added a debug option * Added per-category feeds * Use filesystem to get dates if no metadata is provided * Add Pygments support 1.1 (2010-08-19) ================ * First working version pelican-3.3/docs/conf.py0000644000076500000240000000325012220367223014751 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import sys, os sys.path.append(os.path.abspath(os.pardir)) from pelican import __version__ # -- General configuration ----------------------------------------------------- templates_path = ['_templates'] extensions = ['sphinx.ext.autodoc', 'sphinx.ext.ifconfig', 'sphinx.ext.extlinks'] source_suffix = '.rst' master_doc = 'index' project = 'Pelican' copyright = '2010, Alexis Metaireau and contributors' exclude_patterns = ['_build'] release = __version__ version = '.'.join(release.split('.')[:1]) last_stable = '3.2.2' rst_prolog = ''' .. |last_stable| replace:: :pelican-doc:`{0}` '''.format(last_stable) extlinks = { 'pelican-doc': ('http://docs.getpelican.com/%s/', '') } # -- Options for HTML output --------------------------------------------------- html_theme_path = ['_themes'] html_theme = 'pelican' html_theme_options = { 'nosidebar': True, 'index_logo': 'pelican.png', 'github_fork': 'getpelican/pelican', } html_static_path = ['_static'] # Output file base name for HTML help builder. htmlhelp_basename = 'Pelicandoc' # -- Options for LaTeX output -------------------------------------------------- latex_documents = [ ('index', 'Pelican.tex', 'Pelican Documentation', 'Alexis Métaireau', 'manual'), ] # -- Options for manual page output -------------------------------------------- man_pages = [ ('index', 'pelican', 'pelican documentation', ['Alexis Métaireau'], 1), ('pelican-themes', 'pelican-themes', 'A theme manager for Pelican', ['Mickaël Raybaud'], 1), ('themes', 'pelican-theming', 'How to create themes for Pelican', ['The Pelican contributors'], 1) ] pelican-3.3/LICENSE0000644000076500000240000010333012036016606013530 0ustar jmstaff00000000000000 GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU Affero General Public License is a free, copyleft license for software and other kinds of works, specifically designed to ensure cooperation with the community in the case of network server software. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, our General Public Licenses are intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. Developers that use our General Public Licenses protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License which gives you legal permission to copy, distribute and/or modify the software. A secondary benefit of defending all users' freedom is that improvements made in alternate versions of the program, if they receive widespread use, become available for other developers to incorporate. Many developers of free software are heartened and encouraged by the resulting cooperation. However, in the case of software used on network servers, this result may fail to come about. The GNU General Public License permits making a modified version and letting the public access it on a server without ever releasing its source code to the public. The GNU Affero General Public License is designed specifically to ensure that, in such cases, the modified source code becomes available to the community. It requires the operator of a network server to provide the source code of the modified version running there to the users of that server. Therefore, public use of a modified version, on a publicly accessible server, gives the public access to the source code of the modified version. An older license, called the Affero General Public License and published by Affero, was designed to accomplish similar goals. This is a different license, not a version of the Affero GPL, but Affero has released a new version of the Affero GPL which permits relicensing under this license. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU Affero General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Remote Network Interaction; Use with the GNU General Public License. Notwithstanding any other provision of this License, if you modify the Program, your modified version must prominently offer all users interacting with it remotely through a computer network (if your version supports such interaction) an opportunity to receive the Corresponding Source of your version by providing access to the Corresponding Source from a network server at no charge, through some standard or customary means of facilitating copying of software. This Corresponding Source shall include the Corresponding Source for any work covered by version 3 of the GNU General Public License that is incorporated pursuant to the following paragraph. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the work with which it is combined will remain governed by version 3 of the GNU General Public License. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU Affero General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU Affero General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU Affero General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU Affero General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If your software can interact with users remotely through a computer network, you should also make sure that it provides a way for users to get its source. For example, if your program is a web application, its interface could display a "Source" link that leads users to an archive of the code. There are many ways you could offer source, and different solutions will be better for different programs; see section 13 for the specific requirements. You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU AGPL, see . pelican-3.3/MANIFEST.in0000666000076500000240000000020512155506417014270 0ustar jmstaff00000000000000include *.rst recursive-include pelican *.html *.css *png *.in *.rst *.md *.mkd *.xml *.py include LICENSE THANKS docs/changelog.rst pelican-3.3/pelican/0000755000076500000240000000000012220367225014137 5ustar jmstaff00000000000000pelican-3.3/pelican/__init__.py0000644000076500000240000003517512220367223016261 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six import os import re import sys import time import logging import argparse import locale import collections from pelican import signals from pelican.generators import (ArticlesGenerator, PagesGenerator, StaticGenerator, SourceFileGenerator, TemplatePagesGenerator) from pelican.log import init from pelican.readers import Readers from pelican.settings import read_settings from pelican.utils import clean_output_dir, folder_watcher, file_watcher from pelican.writers import Writer __version__ = "3.3.0" DEFAULT_CONFIG_NAME = 'pelicanconf.py' logger = logging.getLogger(__name__) class Pelican(object): def __init__(self, settings): """ Pelican initialisation, performs some checks on the environment before doing anything else. """ # define the default settings self.settings = settings self._handle_deprecation() self.path = settings['PATH'] self.theme = settings['THEME'] self.output_path = settings['OUTPUT_PATH'] self.ignore_files = settings['IGNORE_FILES'] self.delete_outputdir = settings['DELETE_OUTPUT_DIRECTORY'] self.output_retention = settings['OUTPUT_RETENTION'] self.init_path() self.init_plugins() signals.initialized.send(self) def init_path(self): if not any(p in sys.path for p in ['', os.curdir]): logger.debug("Adding current directory to system path") sys.path.insert(0, '') def init_plugins(self): self.plugins = [] logger.debug('Temporarily adding PLUGIN_PATH to system path') _sys_path = sys.path[:] sys.path.insert(0, self.settings['PLUGIN_PATH']) for plugin in self.settings['PLUGINS']: # if it's a string, then import it if isinstance(plugin, six.string_types): logger.debug("Loading plugin `{0}`".format(plugin)) try: plugin = __import__(plugin, globals(), locals(), str('module')) except ImportError as e: logger.error("Can't find plugin `{0}`: {1}".format(plugin, e)) continue logger.debug("Registering plugin `{0}`".format(plugin.__name__)) plugin.register() self.plugins.append(plugin) logger.debug('Restoring system path') sys.path = _sys_path def _handle_deprecation(self): if self.settings.get('CLEAN_URLS', False): logger.warning('Found deprecated `CLEAN_URLS` in settings.' ' Modifying the following settings for the' ' same behaviour.') self.settings['ARTICLE_URL'] = '{slug}/' self.settings['ARTICLE_LANG_URL'] = '{slug}-{lang}/' self.settings['PAGE_URL'] = 'pages/{slug}/' self.settings['PAGE_LANG_URL'] = 'pages/{slug}-{lang}/' for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL', 'PAGE_LANG_URL'): logger.warning("%s = '%s'" % (setting, self.settings[setting])) if self.settings.get('ARTICLE_PERMALINK_STRUCTURE', False): logger.warning('Found deprecated `ARTICLE_PERMALINK_STRUCTURE` in' ' settings. Modifying the following settings for' ' the same behaviour.') structure = self.settings['ARTICLE_PERMALINK_STRUCTURE'] # Convert %(variable) into {variable}. structure = re.sub('%\((\w+)\)s', '{\g<1>}', structure) # Convert %x into {date:%x} for strftime structure = re.sub('(%[A-z])', '{date:\g<1>}', structure) # Strip a / prefix structure = re.sub('^/', '', structure) for setting in ('ARTICLE_URL', 'ARTICLE_LANG_URL', 'PAGE_URL', 'PAGE_LANG_URL', 'ARTICLE_SAVE_AS', 'ARTICLE_LANG_SAVE_AS', 'PAGE_SAVE_AS', 'PAGE_LANG_SAVE_AS'): self.settings[setting] = os.path.join(structure, self.settings[setting]) logger.warning("%s = '%s'" % (setting, self.settings[setting])) if self.settings.get('FEED', False): logger.warning('Found deprecated `FEED` in settings. Modify FEED' ' to FEED_ATOM in your settings and theme for the same behavior.' ' Temporarily setting FEED_ATOM for backwards compatibility.') self.settings['FEED_ATOM'] = self.settings['FEED'] if self.settings.get('TAG_FEED', False): logger.warning('Found deprecated `TAG_FEED` in settings. Modify ' ' TAG_FEED to TAG_FEED_ATOM in your settings and theme for the ' 'same behavior. Temporarily setting TAG_FEED_ATOM for backwards ' 'compatibility.') self.settings['TAG_FEED_ATOM'] = self.settings['TAG_FEED'] if self.settings.get('CATEGORY_FEED', False): logger.warning('Found deprecated `CATEGORY_FEED` in settings. ' 'Modify CATEGORY_FEED to CATEGORY_FEED_ATOM in your settings and ' 'theme for the same behavior. Temporarily setting ' 'CATEGORY_FEED_ATOM for backwards compatibility.') self.settings['CATEGORY_FEED_ATOM'] =\ self.settings['CATEGORY_FEED'] if self.settings.get('TRANSLATION_FEED', False): logger.warning('Found deprecated `TRANSLATION_FEED` in settings. ' 'Modify TRANSLATION_FEED to TRANSLATION_FEED_ATOM in your ' 'settings and theme for the same behavior. Temporarily setting ' 'TRANSLATION_FEED_ATOM for backwards compatibility.') self.settings['TRANSLATION_FEED_ATOM'] =\ self.settings['TRANSLATION_FEED'] def run(self): """Run the generators and return""" start_time = time.time() context = self.settings.copy() context['filenames'] = {} # share the dict between all the generators context['localsiteurl'] = self.settings['SITEURL'] # share generators = [ cls( context=context, settings=self.settings, path=self.path, theme=self.theme, output_path=self.output_path, ) for cls in self.get_generator_classes() ] # erase the directory if it is not the source and if that's # explicitely asked if (self.delete_outputdir and not os.path.realpath(self.path).startswith(self.output_path)): clean_output_dir(self.output_path, self.output_retention) for p in generators: if hasattr(p, 'generate_context'): p.generate_context() writer = self.get_writer() for p in generators: if hasattr(p, 'generate_output'): p.generate_output(writer) signals.finalized.send(self) articles_generator = next(g for g in generators if isinstance(g, ArticlesGenerator)) pages_generator = next(g for g in generators if isinstance(g, PagesGenerator)) print('Done: Processed {} articles and {} pages in {:.2f} seconds.'.format( len(articles_generator.articles) + len(articles_generator.translations), len(pages_generator.pages) + len(pages_generator.translations), time.time() - start_time)) def get_generator_classes(self): generators = [StaticGenerator, ArticlesGenerator, PagesGenerator] if self.settings['TEMPLATE_PAGES']: generators.append(TemplatePagesGenerator) if self.settings['OUTPUT_SOURCES']: generators.append(SourceFileGenerator) for pair in signals.get_generators.send(self): (funct, value) = pair if not isinstance(value, collections.Iterable): value = (value, ) for v in value: if isinstance(v, type): logger.debug('Found generator: {0}'.format(v)) generators.append(v) return generators def get_writer(self): return Writer(self.output_path, settings=self.settings) def parse_arguments(): parser = argparse.ArgumentParser(description="""A tool to generate a static blog, with restructured text input files.""", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument(dest='path', nargs='?', help='Path where to find the content files.', default=None) parser.add_argument('-t', '--theme-path', dest='theme', help='Path where to find the theme templates. If not specified, it' 'will use the default one included with pelican.') parser.add_argument('-o', '--output', dest='output', help='Where to output the generated files. If not specified, a ' 'directory will be created, named "output" in the current path.') parser.add_argument('-s', '--settings', dest='settings', help='The settings of the application, this is automatically set to ' '{0} if a file exists with this name.'.format(DEFAULT_CONFIG_NAME)) parser.add_argument('-d', '--delete-output-directory', dest='delete_outputdir', action='store_true', default=None, help='Delete the output directory.') parser.add_argument('-v', '--verbose', action='store_const', const=logging.INFO, dest='verbosity', help='Show all messages.') parser.add_argument('-q', '--quiet', action='store_const', const=logging.CRITICAL, dest='verbosity', help='Show only critical errors.') parser.add_argument('-D', '--debug', action='store_const', const=logging.DEBUG, dest='verbosity', help='Show all message, including debug messages.') parser.add_argument('--version', action='version', version=__version__, help='Print the pelican version and exit.') parser.add_argument('-r', '--autoreload', dest='autoreload', action='store_true', help="Relaunch pelican each time a modification occurs" " on the content files.") return parser.parse_args() def get_config(args): config = {} if args.path: config['PATH'] = os.path.abspath(os.path.expanduser(args.path)) if args.output: config['OUTPUT_PATH'] = \ os.path.abspath(os.path.expanduser(args.output)) if args.theme: abstheme = os.path.abspath(os.path.expanduser(args.theme)) config['THEME'] = abstheme if os.path.exists(abstheme) else args.theme if args.delete_outputdir is not None: config['DELETE_OUTPUT_DIRECTORY'] = args.delete_outputdir # argparse returns bytes in Py2. There is no definite answer as to which # encoding argparse (or sys.argv) uses. # "Best" option seems to be locale.getpreferredencoding() # ref: http://mail.python.org/pipermail/python-list/2006-October/405766.html if not six.PY3: enc = locale.getpreferredencoding() for key in config: if key in ('PATH', 'OUTPUT_PATH', 'THEME'): config[key] = config[key].decode(enc) return config def get_instance(args): config_file = args.settings if config_file is None and os.path.isfile(DEFAULT_CONFIG_NAME): config_file = DEFAULT_CONFIG_NAME settings = read_settings(config_file, override=get_config(args)) cls = settings['PELICAN_CLASS'] if isinstance(cls, six.string_types): module, cls_name = cls.rsplit('.', 1) module = __import__(module) cls = getattr(module, cls_name) return cls(settings), settings def main(): args = parse_arguments() init(args.verbosity) pelican, settings = get_instance(args) readers = Readers(settings) watchers = {'content': folder_watcher(pelican.path, readers.extensions, pelican.ignore_files), 'theme': folder_watcher(pelican.theme, [''], pelican.ignore_files), 'settings': file_watcher(args.settings)} try: if args.autoreload: print(' --- AutoReload Mode: Monitoring `content`, `theme` and' ' `settings` for changes. ---') while True: try: # Check source dir for changed files ending with the given # extension in the settings. In the theme dir is no such # restriction; all files are recursively checked if they # have changed, no matter what extension the filenames # have. modified = {k: next(v) for k, v in watchers.items()} if modified['settings']: pelican, settings = get_instance(args) if any(modified.values()): print('\n-> Modified: {}. re-generating...'.format( ', '.join(k for k, v in modified.items() if v))) if modified['content'] is None: logger.warning('No valid files found in content.') if modified['theme'] is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except KeyboardInterrupt: logger.warning("Keyboard interrupt, quitting.") break except Exception as e: if (args.verbosity == logging.DEBUG): logger.critical(e.args) raise logger.warning( 'Caught exception "{0}". Reloading.'.format(e)) finally: time.sleep(.5) # sleep to avoid cpu load else: if next(watchers['content']) is None: logger.warning('No valid files found in content.') if next(watchers['theme']) is None: logger.warning('Empty theme folder. Using `basic` theme.') pelican.run() except Exception as e: # localized systems have errors in native language if locale is set # so convert the message to unicode with the correct encoding msg = str(e) if not six.PY3: msg = msg.decode(locale.getpreferredencoding()) logger.critical(msg) if (args.verbosity == logging.DEBUG): raise else: sys.exit(getattr(e, 'exitcode', 1)) pelican-3.3/pelican/contents.py0000644000076500000240000002624412215535610016355 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six import copy import locale import logging import functools import os import re import sys from datetime import datetime from pelican import signals from pelican.settings import DEFAULT_CONFIG from pelican.utils import (slugify, truncate_html_words, memoized, strftime, python_2_unicode_compatible, deprecated_attribute, path_to_url) # Import these so that they're avalaible when you import from pelican.contents. from pelican.urlwrappers import (URLWrapper, Author, Category, Tag) # NOQA logger = logging.getLogger(__name__) class Content(object): """Represents a content. :param content: the string to parse, containing the original content. :param metadata: the metadata associated to this page (optional). :param settings: the settings dictionary (optional). :param source_path: The location of the source of this content (if any). :param context: The shared context between generators. """ @deprecated_attribute(old='filename', new='source_path', since=(3, 2, 0)) def filename(): return None def __init__(self, content, metadata=None, settings=None, source_path=None, context=None): if metadata is None: metadata = {} if settings is None: settings = copy.deepcopy(DEFAULT_CONFIG) self.settings = settings self._content = content if context is None: context = {} self._context = context self.translations = [] local_metadata = dict(settings['DEFAULT_METADATA']) local_metadata.update(metadata) # set metadata as attributes for key, value in local_metadata.items(): if key in ('save_as', 'url'): key = 'override_' + key setattr(self, key.lower(), value) # also keep track of the metadata attributes available self.metadata = local_metadata #default template if it's not defined in page self.template = self._get_template() # default author to the one in settings if not defined if not hasattr(self, 'author'): if 'AUTHOR' in settings: self.author = Author(settings['AUTHOR'], settings) # XXX Split all the following code into pieces, there is too much here. # manage languages self.in_default_lang = True if 'DEFAULT_LANG' in settings: default_lang = settings['DEFAULT_LANG'].lower() if not hasattr(self, 'lang'): self.lang = default_lang self.in_default_lang = (self.lang == default_lang) # create the slug if not existing, from the title if not hasattr(self, 'slug') and hasattr(self, 'title'): self.slug = slugify(self.title, settings.get('SLUG_SUBSTITUTIONS', ())) self.source_path = source_path # manage the date format if not hasattr(self, 'date_format'): if hasattr(self, 'lang') and self.lang in settings['DATE_FORMATS']: self.date_format = settings['DATE_FORMATS'][self.lang] else: self.date_format = settings['DEFAULT_DATE_FORMAT'] if isinstance(self.date_format, tuple): locale_string = self.date_format[0] if sys.version_info < (3, ) and isinstance(locale_string, six.text_type): locale_string = locale_string.encode('ascii') locale.setlocale(locale.LC_ALL, locale_string) self.date_format = self.date_format[1] if hasattr(self, 'date'): self.locale_date = strftime(self.date, self.date_format) # manage status if not hasattr(self, 'status'): self.status = settings['DEFAULT_STATUS'] if not settings['WITH_FUTURE_DATES']: if hasattr(self, 'date') and self.date > datetime.now(): self.status = 'draft' # store the summary metadata if it is set if 'summary' in metadata: self._summary = metadata['summary'] signals.content_object_init.send(self) def __str__(self): if self.source_path is None: return repr(self) elif six.PY3: return self.source_path or repr(self) else: return str(self.source_path.encode('utf-8', 'replace')) def check_properties(self): """Test mandatory properties are set.""" for prop in self.mandatory_properties: if not hasattr(self, prop): raise NameError(prop) @property def url_format(self): """Returns the URL, formatted with the proper values""" metadata = copy.copy(self.metadata) path = self.metadata.get('path', self.get_relative_source_path()) default_category = self.settings['DEFAULT_CATEGORY'] slug_substitutions = self.settings.get('SLUG_SUBSTITUTIONS', ()) metadata.update({ 'path': path_to_url(path), 'slug': getattr(self, 'slug', ''), 'lang': getattr(self, 'lang', 'en'), 'date': getattr(self, 'date', datetime.now()), 'author': slugify( getattr(self, 'author', ''), slug_substitutions ), 'category': slugify( getattr(self, 'category', default_category), slug_substitutions ) }) return metadata def _expand_settings(self, key): fq_key = ('%s_%s' % (self.__class__.__name__, key)).upper() return self.settings[fq_key].format(**self.url_format) def get_url_setting(self, key): if hasattr(self, 'override_' + key): return getattr(self, 'override_' + key) key = key if self.in_default_lang else 'lang_%s' % key return self._expand_settings(key) def _update_content(self, content, siteurl): """Update the content attribute. Change all the relative paths of the content to relative paths suitable for the ouput content. :param content: content resource that will be passed to the templates. :param siteurl: siteurl which is locally generated by the writer in case of RELATIVE_URLS. """ if not content: return content instrasite_link_regex = self.settings['INTRASITE_LINK_REGEX'] regex = r""" (?P<\s*[^\>]* # match tag with src and href attr (?:href|src)\s*=) (?P["\']) # require value to be quoted (?P{0}(?P.*?)) # the url value \2""".format(instrasite_link_regex) hrefs = re.compile(regex, re.X) def replacer(m): what = m.group('what') value = m.group('value') origin = m.group('path') # we support only filename for now. the plan is to support # categories, tags, etc. in the future, but let's keep things # simple for now. # XXX Put this in a different location. if what == 'filename': if value.startswith('/'): value = value[1:] else: # relative to the source path of this content value = self.get_relative_source_path( os.path.join(self.relative_dir, value) ) if value in self._context['filenames']: origin = '/'.join((siteurl, self._context['filenames'][value].url)) origin = origin.replace('\\', '/') # Fow windows paths. else: logger.warning("Unable to find {fn}, skipping url" " replacement".format(fn=value)) elif what == 'category': origin = Category(value, self.settings).url elif what == 'tag': origin = Tag(value, self.settings).url return ''.join((m.group('markup'), m.group('quote'), origin, m.group('quote'))) return hrefs.sub(replacer, content) @memoized def get_content(self, siteurl): if hasattr(self, '_get_content'): content = self._get_content() else: content = self._content return self._update_content(content, siteurl) @property def content(self): return self.get_content(self._context.get('localsiteurl', '')) def _get_summary(self): """Returns the summary of an article. This is based on the summary metadata if set, otherwise truncate the content. """ if hasattr(self, '_summary'): return self._summary if self.settings['SUMMARY_MAX_LENGTH'] is None: return self.content return truncate_html_words(self.content, self.settings['SUMMARY_MAX_LENGTH']) def _set_summary(self, summary): """Dummy function""" pass summary = property(_get_summary, _set_summary, "Summary of the article." "Based on the content. Can't be set") url = property(functools.partial(get_url_setting, key='url')) save_as = property(functools.partial(get_url_setting, key='save_as')) def _get_template(self): if hasattr(self, 'template') and self.template is not None: return self.template else: return self.default_template def get_relative_source_path(self, source_path=None): """Return the relative path (from the content path) to the given source_path. If no source path is specified, use the source path of this content object. """ if not source_path: source_path = self.source_path if source_path is None: return None return os.path.relpath( os.path.abspath(os.path.join(self.settings['PATH'], source_path)), os.path.abspath(self.settings['PATH']) ) @property def relative_dir(self): return os.path.dirname(os.path.relpath( os.path.abspath(self.source_path), os.path.abspath(self.settings['PATH'])) ) class Page(Content): mandatory_properties = ('title',) default_template = 'page' class Article(Page): mandatory_properties = ('title', 'date', 'category') default_template = 'article' class Quote(Page): base_properties = ('author', 'date') @python_2_unicode_compatible class Static(Page): @deprecated_attribute(old='filepath', new='source_path', since=(3, 2, 0)) def filepath(): return None @deprecated_attribute(old='src', new='source_path', since=(3, 2, 0)) def src(): return None @deprecated_attribute(old='dst', new='save_as', since=(3, 2, 0)) def dst(): return None def is_valid_content(content, f): try: content.check_properties() return True except NameError as e: logger.error("Skipping %s: could not find information about " "'%s'" % (f, e)) return False pelican-3.3/pelican/generators.py0000644000076500000240000005646612215535610016702 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import os import math import random import logging import shutil from codecs import open from collections import defaultdict from functools import partial from itertools import chain, groupby from operator import attrgetter, itemgetter from jinja2 import (Environment, FileSystemLoader, PrefixLoader, ChoiceLoader, BaseLoader, TemplateNotFound) from pelican.contents import Article, Page, Static, is_valid_content from pelican.readers import Readers from pelican.utils import copy, process_translations, mkdir_p, DateFormatter from pelican import signals logger = logging.getLogger(__name__) class Generator(object): """Baseclass generator""" def __init__(self, context, settings, path, theme, output_path, **kwargs): self.context = context self.settings = settings self.path = path self.theme = theme self.output_path = output_path for arg, value in kwargs.items(): setattr(self, arg, value) self.readers = Readers(self.settings) # templates cache self._templates = {} self._templates_path = [] self._templates_path.append(os.path.expanduser( os.path.join(self.theme, 'templates'))) self._templates_path += self.settings['EXTRA_TEMPLATES_PATHS'] theme_path = os.path.dirname(os.path.abspath(__file__)) simple_loader = FileSystemLoader(os.path.join(theme_path, "themes", "simple", "templates")) self.env = Environment( trim_blocks=True, lstrip_blocks=True, loader=ChoiceLoader([ FileSystemLoader(self._templates_path), simple_loader, # implicit inheritance PrefixLoader({'!simple': simple_loader}) # explicit one ]), extensions=self.settings['JINJA_EXTENSIONS'], ) logger.debug('template list: {0}'.format(self.env.list_templates())) # provide utils.strftime as a jinja filter self.env.filters.update({'strftime': DateFormatter()}) # get custom Jinja filters from user settings custom_filters = self.settings['JINJA_FILTERS'] self.env.filters.update(custom_filters) signals.generator_init.send(self) def get_template(self, name): """Return the template by name. Use self.theme to get the templates to use, and return a list of templates ready to use with Jinja2. """ if name not in self._templates: try: self._templates[name] = self.env.get_template(name + '.html') except TemplateNotFound: raise Exception('[templates] unable to load %s.html from %s' % (name, self._templates_path)) return self._templates[name] def _include_path(self, path, extensions=None): """Inclusion logic for .get_files(), returns True/False :param path: the path which might be including :param extensions: the list of allowed extensions (if False, all extensions are allowed) """ if extensions is None: extensions = tuple(self.readers.extensions) basename = os.path.basename(path) if extensions is False or basename.endswith(extensions): return True return False def get_files(self, path, exclude=[], extensions=None): """Return a list of files to use, based on rules :param path: the path to search (relative to self.path) :param exclude: the list of path to exclude :param extensions: the list of allowed extensions (if False, all extensions are allowed) """ files = [] root = os.path.join(self.path, path) if os.path.isdir(root): for dirpath, dirs, temp_files in os.walk(root, followlinks=True): for e in exclude: if e in dirs: dirs.remove(e) reldir = os.path.relpath(dirpath, self.path) for f in temp_files: fp = os.path.join(reldir, f) if self._include_path(fp, extensions): files.append(fp) elif os.path.exists(root) and self._include_path(path, extensions): files.append(path) # can't walk non-directories return files def add_source_path(self, content): location = content.get_relative_source_path() self.context['filenames'][location] = content def _update_context(self, items): """Update the context with the given items from the currrent processor. """ for item in items: value = getattr(self, item) if hasattr(value, 'items'): value = list(value.items()) # py3k safeguard for iterators self.context[item] = value class _FileLoader(BaseLoader): def __init__(self, path, basedir): self.path = path self.fullpath = os.path.join(basedir, path) def get_source(self, environment, template): if template != self.path or not os.path.exists(self.fullpath): raise TemplateNotFound(template) mtime = os.path.getmtime(self.fullpath) with open(self.fullpath, 'r', encoding='utf-8') as f: source = f.read() return (source, self.fullpath, lambda: mtime == os.path.getmtime(self.fullpath)) class TemplatePagesGenerator(Generator): def generate_output(self, writer): for source, dest in self.settings['TEMPLATE_PAGES'].items(): self.env.loader.loaders.insert(0, _FileLoader(source, self.path)) try: template = self.env.get_template(source) rurls = self.settings['RELATIVE_URLS'] writer.write_file(dest, template, self.context, rurls, override_output=True) finally: del self.env.loader.loaders[0] class ArticlesGenerator(Generator): """Generate blog articles""" def __init__(self, *args, **kwargs): """initialize properties""" self.articles = [] # only articles in default language self.translations = [] self.dates = {} self.tags = defaultdict(list) self.categories = defaultdict(list) self.related_posts = [] self.authors = defaultdict(list) self.drafts = [] super(ArticlesGenerator, self).__init__(*args, **kwargs) signals.article_generator_init.send(self) def generate_feeds(self, writer): """Generate the feeds from the current context, and output files.""" if self.settings.get('FEED_ATOM'): writer.write_feed(self.articles, self.context, self.settings['FEED_ATOM']) if self.settings.get('FEED_RSS'): writer.write_feed(self.articles, self.context, self.settings['FEED_RSS'], feed_type='rss') if (self.settings.get('FEED_ALL_ATOM') or self.settings.get('FEED_ALL_RSS')): all_articles = list(self.articles) for article in self.articles: all_articles.extend(article.translations) all_articles.sort(key=attrgetter('date'), reverse=True) if self.settings.get('FEED_ALL_ATOM'): writer.write_feed(all_articles, self.context, self.settings['FEED_ALL_ATOM']) if self.settings.get('FEED_ALL_RSS'): writer.write_feed(all_articles, self.context, self.settings['FEED_ALL_RSS'], feed_type='rss') for cat, arts in self.categories: arts.sort(key=attrgetter('date'), reverse=True) if self.settings.get('CATEGORY_FEED_ATOM'): writer.write_feed(arts, self.context, self.settings['CATEGORY_FEED_ATOM'] % cat.slug) if self.settings.get('CATEGORY_FEED_RSS'): writer.write_feed(arts, self.context, self.settings['CATEGORY_FEED_RSS'] % cat.slug, feed_type='rss') if (self.settings.get('TAG_FEED_ATOM') or self.settings.get('TAG_FEED_RSS')): for tag, arts in self.tags.items(): arts.sort(key=attrgetter('date'), reverse=True) if self.settings.get('TAG_FEED_ATOM'): writer.write_feed(arts, self.context, self.settings['TAG_FEED_ATOM'] % tag.slug) if self.settings.get('TAG_FEED_RSS'): writer.write_feed(arts, self.context, self.settings['TAG_FEED_RSS'] % tag.slug, feed_type='rss') if (self.settings.get('TRANSLATION_FEED_ATOM') or self.settings.get('TRANSLATION_FEED_RSS')): translations_feeds = defaultdict(list) for article in chain(self.articles, self.translations): translations_feeds[article.lang].append(article) for lang, items in translations_feeds.items(): items.sort(key=attrgetter('date'), reverse=True) if self.settings.get('TRANSLATION_FEED_ATOM'): writer.write_feed(items, self.context, self.settings['TRANSLATION_FEED_ATOM'] % lang) if self.settings.get('TRANSLATION_FEED_RSS'): writer.write_feed(items, self.context, self.settings['TRANSLATION_FEED_RSS'] % lang, feed_type='rss') def generate_articles(self, write): """Generate the articles.""" for article in chain(self.translations, self.articles): write(article.save_as, self.get_template(article.template), self.context, article=article, category=article.category, override_output=hasattr(article, 'override_save_as')) def generate_period_archives(self, write): """Generate per-year, per-month, and per-day archives.""" try: template = self.get_template('period_archives') except Exception: template = self.get_template('archives') def _generate_period_archives(dates, key, save_as_fmt): """Generate period archives from `dates`, grouped by `key` and written to `save_as`. """ # `dates` is already sorted by date for _period, group in groupby(dates, key=key): archive = list(group) # arbitrarily grab the first date so that the usual # format string syntax can be used for specifying the # period archive dates date = archive[0].date save_as = save_as_fmt.format(date=date) write(save_as, template, self.context, dates=archive, blog=True) period_save_as = { 'year' : self.settings['YEAR_ARCHIVE_SAVE_AS'], 'month': self.settings['MONTH_ARCHIVE_SAVE_AS'], 'day' : self.settings['DAY_ARCHIVE_SAVE_AS'], } period_date_key = { 'year' : attrgetter('date.year'), 'month': attrgetter('date.year', 'date.month'), 'day' : attrgetter('date.year', 'date.month', 'date.day') } for period in 'year', 'month', 'day': save_as = period_save_as[period] if save_as: key = period_date_key[period] _generate_period_archives(self.dates, key, save_as) def generate_direct_templates(self, write): """Generate direct templates pages""" PAGINATED_TEMPLATES = self.settings['PAGINATED_DIRECT_TEMPLATES'] for template in self.settings['DIRECT_TEMPLATES']: paginated = {} if template in PAGINATED_TEMPLATES: paginated = {'articles': self.articles, 'dates': self.dates} save_as = self.settings.get("%s_SAVE_AS" % template.upper(), '%s.html' % template) if not save_as: continue write(save_as, self.get_template(template), self.context, blog=True, paginated=paginated, page_name=os.path.splitext(save_as)[0]) def generate_tags(self, write): """Generate Tags pages.""" tag_template = self.get_template('tag') for tag, articles in self.tags.items(): articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(tag.save_as, tag_template, self.context, tag=tag, articles=articles, dates=dates, paginated={'articles': articles, 'dates': dates}, page_name=tag.page_name, all_articles=self.articles) def generate_categories(self, write): """Generate category pages.""" category_template = self.get_template('category') for cat, articles in self.categories: articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(cat.save_as, category_template, self.context, category=cat, articles=articles, dates=dates, paginated={'articles': articles, 'dates': dates}, page_name=cat.page_name, all_articles=self.articles) def generate_authors(self, write): """Generate Author pages.""" author_template = self.get_template('author') for aut, articles in self.authors: articles.sort(key=attrgetter('date'), reverse=True) dates = [article for article in self.dates if article in articles] write(aut.save_as, author_template, self.context, author=aut, articles=articles, dates=dates, paginated={'articles': articles, 'dates': dates}, page_name=aut.page_name, all_articles=self.articles) def generate_drafts(self, write): """Generate drafts pages.""" for article in self.drafts: write(os.path.join('drafts', '%s.html' % article.slug), self.get_template(article.template), self.context, article=article, category=article.category, all_articles=self.articles) def generate_pages(self, writer): """Generate the pages on the disk""" write = partial(writer.write_file, relative_urls=self.settings['RELATIVE_URLS']) # to minimize the number of relative path stuff modification # in writer, articles pass first self.generate_articles(write) self.generate_period_archives(write) self.generate_direct_templates(write) # and subfolders after that self.generate_tags(write) self.generate_categories(write) self.generate_authors(write) self.generate_drafts(write) def generate_context(self): """Add the articles into the shared context""" all_articles = [] for f in self.get_files( self.settings['ARTICLE_DIR'], exclude=self.settings['ARTICLE_EXCLUDES']): try: article = self.readers.read_file( base_path=self.path, path=f, content_class=Article, context=self.context, preread_signal=signals.article_generator_preread, preread_sender=self, context_signal=signals.article_generator_context, context_sender=self) except Exception as e: logger.warning('Could not process {}\n{}'.format(f, e)) continue if not is_valid_content(article, f): continue self.add_source_path(article) if article.status == "published": all_articles.append(article) elif article.status == "draft": self.drafts.append(article) else: logger.warning("Unknown status %s for file %s, skipping it." % (repr(article.status), repr(f))) self.articles, self.translations = process_translations(all_articles) for article in self.articles: # only main articles are listed in categories and tags # not translations self.categories[article.category].append(article) if hasattr(article, 'tags'): for tag in article.tags: self.tags[tag].append(article) # ignore blank authors as well as undefined if hasattr(article, 'author') and article.author.name != '': self.authors[article.author].append(article) # sort the articles by date self.articles.sort(key=attrgetter('date'), reverse=True) self.dates = list(self.articles) self.dates.sort(key=attrgetter('date'), reverse=self.context['NEWEST_FIRST_ARCHIVES']) # create tag cloud tag_cloud = defaultdict(int) for article in self.articles: for tag in getattr(article, 'tags', []): tag_cloud[tag] += 1 tag_cloud = sorted(tag_cloud.items(), key=itemgetter(1), reverse=True) tag_cloud = tag_cloud[:self.settings.get('TAG_CLOUD_MAX_ITEMS')] tags = list(map(itemgetter(1), tag_cloud)) if tags: max_count = max(tags) steps = self.settings.get('TAG_CLOUD_STEPS') # calculate word sizes self.tag_cloud = [ ( tag, int(math.floor(steps - (steps - 1) * math.log(count) / (math.log(max_count)or 1))) ) for tag, count in tag_cloud ] # put words in chaos random.shuffle(self.tag_cloud) # and generate the output :) # order the categories per name self.categories = list(self.categories.items()) self.categories.sort( reverse=self.settings['REVERSE_CATEGORY_ORDER']) self.authors = list(self.authors.items()) self.authors.sort() self._update_context(('articles', 'dates', 'tags', 'categories', 'tag_cloud', 'authors', 'related_posts')) signals.article_generator_finalized.send(self) def generate_output(self, writer): self.generate_feeds(writer) self.generate_pages(writer) class PagesGenerator(Generator): """Generate pages""" def __init__(self, *args, **kwargs): self.pages = [] self.hidden_pages = [] self.hidden_translations = [] super(PagesGenerator, self).__init__(*args, **kwargs) signals.page_generator_init.send(self) def generate_context(self): all_pages = [] hidden_pages = [] for f in self.get_files( self.settings['PAGE_DIR'], exclude=self.settings['PAGE_EXCLUDES']): try: page = self.readers.read_file( base_path=self.path, path=f, content_class=Page, context=self.context, preread_signal=signals.page_generator_preread, preread_sender=self, context_signal=signals.page_generator_context, context_sender=self) except Exception as e: logger.warning('Could not process {}\n{}'.format(f, e)) continue if not is_valid_content(page, f): continue self.add_source_path(page) if page.status == "published": all_pages.append(page) elif page.status == "hidden": hidden_pages.append(page) else: logger.warning("Unknown status %s for file %s, skipping it." % (repr(page.status), repr(f))) self.pages, self.translations = process_translations(all_pages) self.hidden_pages, self.hidden_translations = ( process_translations(hidden_pages)) self._update_context(('pages', )) self.context['PAGES'] = self.pages signals.page_generator_finalized.send(self) def generate_output(self, writer): for page in chain(self.translations, self.pages, self.hidden_translations, self.hidden_pages): writer.write_file(page.save_as, self.get_template(page.template), self.context, page=page, relative_urls=self.settings['RELATIVE_URLS'], override_output=hasattr(page, 'override_save_as')) class StaticGenerator(Generator): """copy static paths (what you want to copy, like images, medias etc. to output""" def _copy_paths(self, paths, source, destination, output_path, final_path=None): """Copy all the paths from source to destination""" for path in paths: copy(path, source, os.path.join(output_path, destination), final_path) def generate_context(self): self.staticfiles = [] # walk static paths for static_path in self.settings['STATIC_PATHS']: for f in self.get_files( static_path, extensions=False): static = self.readers.read_file( base_path=self.path, path=f, content_class=Static, fmt='static', context=self.context, preread_signal=signals.static_generator_preread, preread_sender=self, context_signal=signals.static_generator_context, context_sender=self) self.staticfiles.append(static) self.add_source_path(static) self._update_context(('staticfiles',)) def generate_output(self, writer): self._copy_paths(self.settings['THEME_STATIC_PATHS'], self.theme, self.settings['THEME_STATIC_DIR'], self.output_path, os.curdir) # copy all Static files for sc in self.context['staticfiles']: source_path = os.path.join(self.path, sc.source_path) save_as = os.path.join(self.output_path, sc.save_as) mkdir_p(os.path.dirname(save_as)) shutil.copy(source_path, save_as) logger.info('copying {} to {}'.format(sc.source_path, sc.save_as)) class SourceFileGenerator(Generator): def generate_context(self): self.output_extension = self.settings['OUTPUT_SOURCES_EXTENSION'] def _create_source(self, obj): output_path, _ = os.path.splitext(obj.save_as) dest = os.path.join(self.output_path, output_path + self.output_extension) copy('', obj.source_path, dest) def generate_output(self, writer=None): logger.info(' Generating source files...') for obj in chain(self.context['articles'], self.context['pages']): self._create_source(obj) for obj_trans in obj.translations: self._create_source(obj_trans) pelican-3.3/pelican/log.py0000666000076500000240000000431612130377623015305 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function __all__ = [ 'init' ] import os import sys import logging from logging import Formatter, getLogger, StreamHandler, DEBUG RESET_TERM = '\033[0;m' COLOR_CODES = { 'red': 31, 'yellow': 33, 'cyan': 36, 'white': 37, 'bgred': 41, 'bggrey': 100, } def ansi(color, text): """Wrap text in an ansi escape sequence""" code = COLOR_CODES[color] return '\033[1;{0}m{1}{2}'.format(code, text, RESET_TERM) class ANSIFormatter(Formatter): """Convert a `logging.LogRecord' object into colored text, using ANSI escape sequences. """ def format(self, record): msg = record.getMessage() if record.levelname == 'INFO': return ansi('cyan', '-> ') + msg elif record.levelname == 'WARNING': return ansi('yellow', record.levelname) + ': ' + msg elif record.levelname == 'ERROR': return ansi('red', record.levelname) + ': ' + msg elif record.levelname == 'CRITICAL': return ansi('bgred', record.levelname) + ': ' + msg elif record.levelname == 'DEBUG': return ansi('bggrey', record.levelname) + ': ' + msg else: return ansi('white', record.levelname) + ': ' + msg class TextFormatter(Formatter): """ Convert a `logging.LogRecord' object into text. """ def format(self, record): if not record.levelname or record.levelname == 'INFO': return record.getMessage() else: return record.levelname + ': ' + record.getMessage() def init(level=None, logger=getLogger(), handler=StreamHandler()): logger = logging.getLogger() if (os.isatty(sys.stdout.fileno()) and not sys.platform.startswith('win')): fmt = ANSIFormatter() else: fmt = TextFormatter() handler.setFormatter(fmt) logger.addHandler(handler) if level: logger.setLevel(level) if __name__ == '__main__': init(level=DEBUG) root_logger = logging.getLogger() root_logger.debug('debug') root_logger.info('info') root_logger.warning('warning') root_logger.error('error') root_logger.critical('critical') pelican-3.3/pelican/paginator.py0000644000076500000240000001134212177737636016520 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six # From django.core.paginator from collections import namedtuple import functools import logging import os from math import ceil logger = logging.getLogger(__name__) PaginationRule = namedtuple( 'PaginationRule', 'min_page URL SAVE_AS', ) class Paginator(object): def __init__(self, name, object_list, settings): self.name = name self.object_list = object_list self.settings = settings if settings.get('DEFAULT_PAGINATION'): self.per_page = settings.get('DEFAULT_PAGINATION') self.orphans = settings.get('DEFAULT_ORPHANS') else: self.per_page = len(object_list) self.orphans = 0 self._num_pages = self._count = None def page(self, number): "Returns a Page object for the given 1-based page number." bottom = (number - 1) * self.per_page top = bottom + self.per_page if top + self.orphans >= self.count: top = self.count return Page(self.name, self.object_list[bottom:top], number, self, self.settings) def _get_count(self): "Returns the total number of objects, across all pages." if self._count is None: self._count = len(self.object_list) return self._count count = property(_get_count) def _get_num_pages(self): "Returns the total number of pages." if self._num_pages is None: hits = max(1, self.count - self.orphans) self._num_pages = int(ceil(hits / (float(self.per_page) or 1))) return self._num_pages num_pages = property(_get_num_pages) def _get_page_range(self): """ Returns a 1-based range of pages for iterating through within a template for loop. """ return list(range(1, self.num_pages + 1)) page_range = property(_get_page_range) class Page(object): def __init__(self, name, object_list, number, paginator, settings): self.name = name self.object_list = object_list self.number = number self.paginator = paginator self.settings = settings def __repr__(self): return '' % (self.number, self.paginator.num_pages) def has_next(self): return self.number < self.paginator.num_pages def has_previous(self): return self.number > 1 def has_other_pages(self): return self.has_previous() or self.has_next() def next_page_number(self): return self.number + 1 def previous_page_number(self): return self.number - 1 def start_index(self): """ Returns the 1-based index of the first object on this page, relative to total objects in the paginator. """ # Special case, return zero if no items. if self.paginator.count == 0: return 0 return (self.paginator.per_page * (self.number - 1)) + 1 def end_index(self): """ Returns the 1-based index of the last object on this page, relative to total objects found (hits). """ # Special case for the last page because there can be orphans. if self.number == self.paginator.num_pages: return self.paginator.count return self.number * self.paginator.per_page def _from_settings(self, key): """Returns URL information as defined in settings. Similar to URLWrapper._from_settings, but specialized to deal with pagination logic.""" rule = None # find the last matching pagination rule for p in self.settings['PAGINATION_PATTERNS']: if p.min_page <= self.number: rule = p if not rule: return '' prop_value = getattr(rule, key) if not isinstance(prop_value, six.string_types): logger.warning('%s is set to %s' % (key, prop_value)) return prop_value # URL or SAVE_AS is a string, format it with a controlled context context = { 'name': self.name, 'object_list': self.object_list, 'number': self.number, 'paginator': self.paginator, 'settings': self.settings, 'base_name': os.path.dirname(self.name), 'number_sep': '/', } if self.number == 1: # no page numbers on the first page context['number'] = '' context['number_sep'] = '' ret = prop_value.format(**context) if ret[0] == '/': ret = ret[1:] return ret url = property(functools.partial(_from_settings, key='URL')) save_as = property(functools.partial(_from_settings, key='SAVE_AS')) pelican-3.3/pelican/readers.py0000644000076500000240000004551312207763674016163 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import datetime import logging import os import re try: import docutils import docutils.core import docutils.io from docutils.writers.html4css1 import HTMLTranslator # import the directives to have pygments support from pelican import rstdirectives # NOQA except ImportError: docutils = False try: from markdown import Markdown except ImportError: Markdown = False # NOQA try: from asciidocapi import AsciiDocAPI asciidoc = True except ImportError: asciidoc = False try: from html import escape except ImportError: from cgi import escape try: from html.parser import HTMLParser except ImportError: from HTMLParser import HTMLParser from pelican import signals from pelican.contents import Page, Category, Tag, Author from pelican.utils import get_date, pelican_open METADATA_PROCESSORS = { 'tags': lambda x, y: [Tag(tag, y) for tag in x.split(',')], 'date': lambda x, y: get_date(x), 'status': lambda x, y: x.strip(), 'category': Category, 'author': Author, } logger = logging.getLogger(__name__) class BaseReader(object): """Base class to read files. This class is used to process static files, and it can be inherited for other types of file. A Reader class must have the following attributes: - enabled: (boolean) tell if the Reader class is enabled. It generally depends on the import of some dependency. - file_extensions: a list of file extensions that the Reader will process. - extensions: a list of extensions to use in the reader (typical use is Markdown). """ enabled = True file_extensions = ['static'] extensions = None def __init__(self, settings): self.settings = settings def process_metadata(self, name, value): if name in METADATA_PROCESSORS: return METADATA_PROCESSORS[name](value, self.settings) return value def read(self, source_path): "No-op parser" content = None metadata = {} return content, metadata class _FieldBodyTranslator(HTMLTranslator): def __init__(self, document): HTMLTranslator.__init__(self, document) self.compact_p = None def astext(self): return ''.join(self.body) def visit_field_body(self, node): pass def depart_field_body(self, node): pass def render_node_to_html(document, node): visitor = _FieldBodyTranslator(document) node.walkabout(visitor) return visitor.astext() class PelicanHTMLTranslator(HTMLTranslator): def visit_abbreviation(self, node): attrs = {} if node.hasattr('explanation'): attrs['title'] = node['explanation'] self.body.append(self.starttag(node, 'abbr', '', **attrs)) def depart_abbreviation(self, node): self.body.append('') def visit_image(self, node): # set an empty alt if alt is not specified # avoids that alt is taken from src node['alt'] = node.get('alt', '') return HTMLTranslator.visit_image(self, node) class RstReader(BaseReader): """Reader for reStructuredText files""" enabled = bool(docutils) file_extensions = ['rst'] def __init__(self, *args, **kwargs): super(RstReader, self).__init__(*args, **kwargs) def _parse_metadata(self, document): """Return the dict containing document metadata""" output = {} for docinfo in document.traverse(docutils.nodes.docinfo): for element in docinfo.children: if element.tagname == 'field': # custom fields (e.g. summary) name_elem, body_elem = element.children name = name_elem.astext() if name == 'summary': value = render_node_to_html(document, body_elem) else: value = body_elem.astext() else: # standard fields (e.g. address) name = element.tagname value = element.astext() name = name.lower() output[name] = self.process_metadata(name, value) return output def _get_publisher(self, source_path): extra_params = {'initial_header_level': '2', 'syntax_highlight': 'short', 'input_encoding': 'utf-8'} user_params = self.settings.get('DOCUTILS_SETTINGS') if user_params: extra_params.update(user_params) pub = docutils.core.Publisher( destination_class=docutils.io.StringOutput) pub.set_components('standalone', 'restructuredtext', 'html') pub.writer.translator_class = PelicanHTMLTranslator pub.process_programmatic_settings(None, extra_params, None) pub.set_source(source_path=source_path) pub.publish() return pub def read(self, source_path): """Parses restructured text""" pub = self._get_publisher(source_path) parts = pub.writer.parts content = parts.get('body') metadata = self._parse_metadata(pub.document) metadata.setdefault('title', parts.get('title')) return content, metadata class MarkdownReader(BaseReader): """Reader for Markdown files""" enabled = bool(Markdown) file_extensions = ['md', 'markdown', 'mkd', 'mdown'] def __init__(self, *args, **kwargs): super(MarkdownReader, self).__init__(*args, **kwargs) self.extensions = list(self.settings['MD_EXTENSIONS']) if 'meta' not in self.extensions: self.extensions.append('meta') def _parse_metadata(self, meta): """Return the dict containing document metadata""" output = {} for name, value in meta.items(): name = name.lower() if name == "summary": summary_values = "\n".join(value) # reset the markdown instance to clear any state self._md.reset() summary = self._md.convert(summary_values) output[name] = self.process_metadata(name, summary) else: output[name] = self.process_metadata(name, value[0]) return output def read(self, source_path): """Parse content and metadata of markdown files""" self._md = Markdown(extensions=self.extensions) with pelican_open(source_path) as text: content = self._md.convert(text) metadata = self._parse_metadata(self._md.Meta) return content, metadata class HTMLReader(BaseReader): """Parses HTML files as input, looking for meta, title, and body tags""" file_extensions = ['htm', 'html'] enabled = True class _HTMLParser(HTMLParser): def __init__(self, settings, filename): HTMLParser.__init__(self) self.body = '' self.metadata = {} self.settings = settings self._data_buffer = '' self._filename = filename self._in_top_level = True self._in_head = False self._in_title = False self._in_body = False self._in_tags = False def handle_starttag(self, tag, attrs): if tag == 'head' and self._in_top_level: self._in_top_level = False self._in_head = True elif tag == 'title' and self._in_head: self._in_title = True self._data_buffer = '' elif tag == 'body' and self._in_top_level: self._in_top_level = False self._in_body = True self._data_buffer = '' elif tag == 'meta' and self._in_head: self._handle_meta_tag(attrs) elif self._in_body: self._data_buffer += self.build_tag(tag, attrs, False) def handle_endtag(self, tag): if tag == 'head': if self._in_head: self._in_head = False self._in_top_level = True elif tag == 'title': self._in_title = False self.metadata['title'] = self._data_buffer elif tag == 'body': self.body = self._data_buffer self._in_body = False self._in_top_level = True elif self._in_body: self._data_buffer += ''.format(escape(tag)) def handle_startendtag(self, tag, attrs): if tag == 'meta' and self._in_head: self._handle_meta_tag(attrs) if self._in_body: self._data_buffer += self.build_tag(tag, attrs, True) def handle_comment(self, data): self._data_buffer += ''.format(data) def handle_data(self, data): self._data_buffer += data def handle_entityref(self, data): self._data_buffer += '&{};'.format(data) def handle_charref(self, data): self._data_buffer += '&#{};'.format(data) def build_tag(self, tag, attrs, close_tag): result = '<{}'.format(escape(tag)) for k, v in attrs: result += ' ' + escape(k) if v is not None: result += '="{}"'.format(escape(v)) if close_tag: return result + ' />' return result + '>' def _handle_meta_tag(self, attrs): name = self._attr_value(attrs, 'name').lower() contents = self._attr_value(attrs, 'content', '') if not contents: contents = self._attr_value(attrs, 'contents', '') if contents: logger.warning("Meta tag attribute 'contents' used in file %s, should be changed to 'content'", self._filename) if name == 'keywords': name = 'tags' self.metadata[name] = contents @classmethod def _attr_value(cls, attrs, name, default=None): return next((x[1] for x in attrs if x[0] == name), default) def read(self, filename): """Parse content and metadata of HTML files""" with pelican_open(filename) as content: parser = self._HTMLParser(self.settings, filename) parser.feed(content) parser.close() metadata = {} for k in parser.metadata: metadata[k] = self.process_metadata(k, parser.metadata[k]) return parser.body, metadata class AsciiDocReader(BaseReader): """Reader for AsciiDoc files""" enabled = bool(asciidoc) file_extensions = ['asc'] default_options = ["--no-header-footer", "-a newline=\\n"] def read(self, source_path): """Parse content and metadata of asciidoc files""" from cStringIO import StringIO with pelican_open(source_path) as source: text = StringIO(source) content = StringIO() ad = AsciiDocAPI() options = self.settings['ASCIIDOC_OPTIONS'] if isinstance(options, (str, unicode)): options = [m.strip() for m in options.split(',')] options = self.default_options + options for o in options: ad.options(*o.split()) ad.execute(text, content, backend="html4") content = content.getvalue() metadata = {} for name, value in ad.asciidoc.document.attributes.items(): name = name.lower() metadata[name] = self.process_metadata(name, value) if 'doctitle' in metadata: metadata['title'] = metadata['doctitle'] return content, metadata class Readers(object): """Interface for all readers. This class contains a mapping of file extensions / Reader classes, to know which Reader class must be used to read a file (based on its extension). This is customizable both with the 'READERS' setting, and with the 'readers_init' signall for plugins. """ # used to warn about missing dependencies only once, at the first # instanciation of a Readers object. warn_missing_deps = True def __init__(self, settings=None): self.settings = settings or {} self.readers = {} self.reader_classes = {} for cls in [BaseReader] + BaseReader.__subclasses__(): if not cls.enabled: if self.__class__.warn_missing_deps: logger.debug('Missing dependencies for {}' .format(', '.join(cls.file_extensions))) continue for ext in cls.file_extensions: self.reader_classes[ext] = cls self.__class__.warn_missing_deps = False if self.settings['READERS']: self.reader_classes.update(self.settings['READERS']) signals.readers_init.send(self) for fmt, reader_class in self.reader_classes.items(): if not reader_class: continue self.readers[fmt] = reader_class(self.settings) @property def extensions(self): return self.readers.keys() def read_file(self, base_path, path, content_class=Page, fmt=None, context=None, preread_signal=None, preread_sender=None, context_signal=None, context_sender=None): """Return a content object parsed with the given format.""" path = os.path.abspath(os.path.join(base_path, path)) source_path = os.path.relpath(path, base_path) logger.debug('read file {} -> {}'.format( source_path, content_class.__name__)) if not fmt: _, ext = os.path.splitext(os.path.basename(path)) fmt = ext[1:] if fmt not in self.readers: raise TypeError( 'Pelican does not know how to parse {}'.format(path)) if preread_signal: logger.debug('signal {}.send({})'.format( preread_signal, preread_sender)) preread_signal.send(preread_sender) reader = self.readers[fmt] metadata = default_metadata( settings=self.settings, process=reader.process_metadata) metadata.update(path_metadata( full_path=path, source_path=source_path, settings=self.settings)) metadata.update(parse_path_metadata( source_path=source_path, settings=self.settings, process=reader.process_metadata)) content, reader_metadata = reader.read(path) metadata.update(reader_metadata) if content: # find images with empty alt find_empty_alt(content, path) # eventually filter the content with typogrify if asked so if content and self.settings['TYPOGRIFY']: from typogrify.filters import typogrify content = typogrify(content) metadata['title'] = typogrify(metadata['title']) if context_signal: logger.debug('signal {}.send({}, )'.format( context_signal, context_sender)) context_signal.send(context_sender, metadata=metadata) return content_class(content=content, metadata=metadata, settings=self.settings, source_path=path, context=context) def find_empty_alt(content, path): """Find images with empty alt Create warnings for all images with empty alt (up to a certain number), as they are really likely to be accessibility flaws. """ imgs = re.compile(r""" (?: # src before alt ]* src=(['"])(.*)\1 [^\>]* alt=(['"])\3 )|(?: # alt before src ]* alt=(['"])\4 [^\>]* src=(['"])(.*)\5 ) """, re.X) matches = re.findall(imgs, content) # find a correct threshold nb_warnings = 10 if len(matches) == nb_warnings + 1: nb_warnings += 1 # avoid bad looking case # print one warning per image with empty alt until threshold for match in matches[:nb_warnings]: logger.warning('Empty alt attribute for image {} in {}'.format( os.path.basename(match[1] + match[5]), path)) # print one warning for the other images with empty alt if len(matches) > nb_warnings: logger.warning('{} other images with empty alt attributes' .format(len(matches) - nb_warnings)) def default_metadata(settings=None, process=None): metadata = {} if settings: if 'DEFAULT_CATEGORY' in settings: value = settings['DEFAULT_CATEGORY'] if process: value = process('category', value) metadata['category'] = value if 'DEFAULT_DATE' in settings and settings['DEFAULT_DATE'] != 'fs': metadata['date'] = datetime.datetime(*settings['DEFAULT_DATE']) return metadata def path_metadata(full_path, source_path, settings=None): metadata = {} if settings: if settings.get('DEFAULT_DATE', None) == 'fs': metadata['date'] = datetime.datetime.fromtimestamp( os.stat(full_path).st_ctime) metadata.update(settings.get('EXTRA_PATH_METADATA', {}).get( source_path, {})) return metadata def parse_path_metadata(source_path, settings=None, process=None): """Extract a metadata dictionary from a file's path >>> import pprint >>> settings = { ... 'FILENAME_METADATA': '(?P[^.]*).*', ... 'PATH_METADATA': ... '(?P[^/]*)/(?P\d{4}-\d{2}-\d{2})/.*', ... } >>> reader = BaseReader(settings=settings) >>> metadata = parse_path_metadata( ... source_path='my-cat/2013-01-01/my-slug.html', ... settings=settings, ... process=reader.process_metadata) >>> pprint.pprint(metadata) # doctest: +ELLIPSIS {'category': , 'date': datetime.datetime(2013, 1, 1, 0, 0), 'slug': 'my-slug'} """ metadata = {} dirname, basename = os.path.split(source_path) base, ext = os.path.splitext(basename) subdir = os.path.basename(dirname) if settings: checks = [] for key, data in [('FILENAME_METADATA', base), ('PATH_METADATA', source_path)]: checks.append((settings.get(key, None), data)) if settings.get('USE_FOLDER_AS_CATEGORY', None): checks.insert(0, ('(?P.*)', subdir)) for regexp, data in checks: if regexp and data: match = re.match(regexp, data) if match: # .items() for py3k compat. for k, v in match.groupdict().items(): if k not in metadata: k = k.lower() # metadata must be lowercase if process: v = process(k, v) metadata[k] = v return metadata pelican-3.3/pelican/rstdirectives.py0000644000076500000240000000570012216354256017412 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function from docutils import nodes, utils from docutils.parsers.rst import directives, roles, Directive from pygments.formatters import HtmlFormatter from pygments import highlight from pygments.lexers import get_lexer_by_name, TextLexer import re import six import pelican.settings as pys class Pygments(Directive): """ Source code syntax highlighting. """ required_arguments = 1 optional_arguments = 0 final_argument_whitespace = True option_spec = { 'anchorlinenos': directives.flag, 'classprefix': directives.unchanged, 'hl_lines': directives.unchanged, 'lineanchors': directives.unchanged, 'linenos': directives.unchanged, 'linenospecial': directives.nonnegative_int, 'linenostart': directives.nonnegative_int, 'linenostep': directives.nonnegative_int, 'lineseparator': directives.unchanged, 'linespans': directives.unchanged, 'nobackground': directives.flag, 'nowrap': directives.flag, 'tagsfile': directives.unchanged, 'tagurlformat': directives.unchanged, } has_content = True def run(self): self.assert_has_content() try: lexer = get_lexer_by_name(self.arguments[0]) except ValueError: # no lexer found - use the text one instead of an exception lexer = TextLexer() # Fetch the defaults if pys.PYGMENTS_RST_OPTIONS is not None: for k, v in six.iteritems(pys.PYGMENTS_RST_OPTIONS): # Locally set options overrides the defaults if k not in self.options: self.options[k] = v if ('linenos' in self.options and self.options['linenos'] not in ('table', 'inline')): if self.options['linenos'] == 'none': self.options.pop('linenos') else: self.options['linenos'] = 'table' for flag in ('nowrap', 'nobackground', 'anchorlinenos'): if flag in self.options: self.options[flag] = True # noclasses should already default to False, but just in case... formatter = HtmlFormatter(noclasses=False, **self.options) parsed = highlight('\n'.join(self.content), lexer, formatter) return [nodes.raw('', parsed, format='html')] directives.register_directive('code-block', Pygments) directives.register_directive('sourcecode', Pygments) _abbr_re = re.compile('\((.*)\)$') class abbreviation(nodes.Inline, nodes.TextElement): pass def abbr_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): text = utils.unescape(text) m = _abbr_re.search(text) if m is None: return [abbreviation(text, text)], [] abbr = text[:m.start()].strip() expl = m.group(1) return [abbreviation(abbr, abbr, explanation=expl)], [] roles.register_local_role('abbr', abbr_role) pelican-3.3/pelican/server.py0000644000076500000240000000257612207763674016046 0ustar jmstaff00000000000000from __future__ import print_function import os import sys import logging try: import SimpleHTTPServer as srvmod except ImportError: import http.server as srvmod # NOQA try: import SocketServer as socketserver except ImportError: import socketserver # NOQA PORT = len(sys.argv) == 2 and int(sys.argv[1]) or 8000 SUFFIXES = ['','.html','/index.html'] class ComplexHTTPRequestHandler(srvmod.SimpleHTTPRequestHandler): def do_GET(self): # we are trying to detect the file by having a fallback mechanism r = None for suffix in SUFFIXES: if not hasattr(self,'original_path'): self.original_path = self.path self.path = self.original_path + suffix path = self.translate_path(self.path) if os.path.exists(path): r = srvmod.SimpleHTTPRequestHandler.do_GET(self) if r is not None: break logging.warning("Unable to find %s file." % self.path) return r Handler = ComplexHTTPRequestHandler try: httpd = socketserver.TCPServer(("", PORT), Handler) except OSError as e: logging.error("Could not listen on port %s" % PORT) sys.exit(getattr(e, 'exitcode', 1)) logging.info("serving at port %s" % PORT) try: httpd.serve_forever() except KeyboardInterrupt as e: logging.info("shutting down server") httpd.socket.close()pelican-3.3/pelican/settings.py0000644000076500000240000002515012216354256016361 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six import copy import inspect import os import locale import logging try: # SourceFileLoader is the recommended way in 3.3+ from importlib.machinery import SourceFileLoader load_source = lambda name, path: SourceFileLoader(name, path).load_module() except ImportError: # but it does not exist in 3.2-, so fall back to imp import imp load_source = imp.load_source from os.path import isabs logger = logging.getLogger(__name__) DEFAULT_THEME = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'themes', 'notmyidea') DEFAULT_CONFIG = { 'PATH': os.curdir, 'ARTICLE_DIR': '', 'ARTICLE_EXCLUDES': ('pages',), 'PAGE_DIR': 'pages', 'PAGE_EXCLUDES': (), 'THEME': DEFAULT_THEME, 'OUTPUT_PATH': 'output', 'READERS': {}, 'STATIC_PATHS': ['images', ], 'THEME_STATIC_DIR': 'theme', 'THEME_STATIC_PATHS': ['static', ], 'FEED_ALL_ATOM': os.path.join('feeds', 'all.atom.xml'), 'CATEGORY_FEED_ATOM': os.path.join('feeds', '%s.atom.xml'), 'TRANSLATION_FEED_ATOM': os.path.join('feeds', 'all-%s.atom.xml'), 'FEED_MAX_ITEMS': '', 'SITEURL': '', 'SITENAME': 'A Pelican Blog', 'DISPLAY_PAGES_ON_MENU': True, 'DISPLAY_CATEGORIES_ON_MENU': True, 'OUTPUT_SOURCES': False, 'OUTPUT_SOURCES_EXTENSION': '.text', 'USE_FOLDER_AS_CATEGORY': True, 'DEFAULT_CATEGORY': 'misc', 'WITH_FUTURE_DATES': True, 'CSS_FILE': 'main.css', 'NEWEST_FIRST_ARCHIVES': True, 'REVERSE_CATEGORY_ORDER': False, 'DELETE_OUTPUT_DIRECTORY': False, 'OUTPUT_RETENTION': (), 'ARTICLE_URL': '{slug}.html', 'ARTICLE_SAVE_AS': '{slug}.html', 'ARTICLE_LANG_URL': '{slug}-{lang}.html', 'ARTICLE_LANG_SAVE_AS': '{slug}-{lang}.html', 'PAGE_URL': 'pages/{slug}.html', 'PAGE_SAVE_AS': os.path.join('pages', '{slug}.html'), 'PAGE_LANG_URL': 'pages/{slug}-{lang}.html', 'PAGE_LANG_SAVE_AS': os.path.join('pages', '{slug}-{lang}.html'), 'STATIC_URL': '{path}', 'STATIC_SAVE_AS': '{path}', 'PDF_GENERATOR': False, 'PDF_STYLE_PATH': '', 'PDF_STYLE': 'twelvepoint', 'CATEGORY_URL': 'category/{slug}.html', 'CATEGORY_SAVE_AS': os.path.join('category', '{slug}.html'), 'TAG_URL': 'tag/{slug}.html', 'TAG_SAVE_AS': os.path.join('tag', '{slug}.html'), 'AUTHOR_URL': 'author/{slug}.html', 'AUTHOR_SAVE_AS': os.path.join('author', '{slug}.html'), 'PAGINATION_PATTERNS': [ (0, '{name}{number}.html', '{name}{number}.html'), ], 'YEAR_ARCHIVE_SAVE_AS': False, 'MONTH_ARCHIVE_SAVE_AS': False, 'DAY_ARCHIVE_SAVE_AS': False, 'RELATIVE_URLS': False, 'DEFAULT_LANG': 'en', 'TAG_CLOUD_STEPS': 4, 'TAG_CLOUD_MAX_ITEMS': 100, 'DIRECT_TEMPLATES': ('index', 'tags', 'categories', 'authors', 'archives'), 'EXTRA_TEMPLATES_PATHS': [], 'PAGINATED_DIRECT_TEMPLATES': ('index', ), 'PELICAN_CLASS': 'pelican.Pelican', 'DEFAULT_DATE_FORMAT': '%a %d %B %Y', 'DATE_FORMATS': {}, 'ASCIIDOC_OPTIONS': [], 'MD_EXTENSIONS': ['codehilite(css_class=highlight)', 'extra'], 'JINJA_EXTENSIONS': [], 'JINJA_FILTERS': {}, 'LOCALE': [''], # defaults to user locale 'DEFAULT_PAGINATION': False, 'DEFAULT_ORPHANS': 0, 'DEFAULT_METADATA': (), 'FILENAME_METADATA': '(?P\d{4}-\d{2}-\d{2}).*', 'PATH_METADATA': '', 'EXTRA_PATH_METADATA': {}, 'DEFAULT_STATUS': 'published', 'ARTICLE_PERMALINK_STRUCTURE': '', 'TYPOGRIFY': False, 'SUMMARY_MAX_LENGTH': 50, 'PLUGIN_PATH': '', 'PLUGINS': [], 'PYGMENTS_RST_OPTIONS': {}, 'TEMPLATE_PAGES': {}, 'IGNORE_FILES': ['.#*'], 'SLUG_SUBSTITUTIONS': (), 'INTRASITE_LINK_REGEX': '[{|](?P.*?)[|}]', } PYGMENTS_RST_OPTIONS = None def read_settings(path=None, override=None): if path: local_settings = get_settings_from_file(path) # Make the paths relative to the settings file for p in ['PATH', 'OUTPUT_PATH', 'THEME', 'PLUGIN_PATH']: if p in local_settings and local_settings[p] is not None \ and not isabs(local_settings[p]): absp = os.path.abspath(os.path.normpath(os.path.join( os.path.dirname(path), local_settings[p]))) if p not in ('THEME', 'PLUGIN_PATH') or os.path.exists(absp): local_settings[p] = absp else: local_settings = copy.deepcopy(DEFAULT_CONFIG) if override: local_settings.update(override) parsed_settings = configure_settings(local_settings) # This is because there doesn't seem to be a way to pass extra # parameters to docutils directive handlers, so we have to have a # variable here that we'll import from within Pygments.run (see # rstdirectives.py) to see what the user defaults were. global PYGMENTS_RST_OPTIONS PYGMENTS_RST_OPTIONS = parsed_settings.get('PYGMENTS_RST_OPTIONS', None) return parsed_settings def get_settings_from_module(module=None, default_settings=DEFAULT_CONFIG): """Loads settings from a module, returns a dictionary.""" context = copy.deepcopy(default_settings) if module is not None: context.update( (k, v) for k, v in inspect.getmembers(module) if k.isupper()) return context def get_settings_from_file(path, default_settings=DEFAULT_CONFIG): """Loads settings from a file path, returning a dict.""" name, ext = os.path.splitext(os.path.basename(path)) module = load_source(name, path) return get_settings_from_module(module, default_settings=default_settings) def configure_settings(settings): """Provide optimizations, error checking and warnings for the given settings. """ if not 'PATH' in settings or not os.path.isdir(settings['PATH']): raise Exception('You need to specify a path containing the content' ' (see pelican --help for more information)') # lookup the theme in "pelican/themes" if the given one doesn't exist if not os.path.isdir(settings['THEME']): theme_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), 'themes', settings['THEME']) if os.path.exists(theme_path): settings['THEME'] = theme_path else: raise Exception("Could not find the theme %s" % settings['THEME']) # standardize strings to lowercase strings for key in [ 'DEFAULT_LANG', ]: if key in settings: settings[key] = settings[key].lower() # standardize strings to lists for key in [ 'LOCALE', ]: if key in settings and isinstance(settings[key], six.string_types): settings[key] = [settings[key]] # check settings that must be a particular type for key, types in [ ('OUTPUT_SOURCES_EXTENSION', six.string_types), ('FILENAME_METADATA', six.string_types), ]: if key in settings and not isinstance(settings[key], types): value = settings.pop(key) logger.warn( 'Detected misconfigured {} ({}), ' 'falling back to the default ({})'.format( key, value, DEFAULT_CONFIG[key])) # try to set the different locales, fallback on the default. locales = settings.get('LOCALE', DEFAULT_CONFIG['LOCALE']) for locale_ in locales: try: locale.setlocale(locale.LC_ALL, str(locale_)) break # break if it is successful except locale.Error: pass else: logger.warning("LOCALE option doesn't contain a correct value") if ('SITEURL' in settings): # If SITEURL has a trailing slash, remove it and provide a warning siteurl = settings['SITEURL'] if (siteurl.endswith('/')): settings['SITEURL'] = siteurl[:-1] logger.warning("Removed extraneous trailing slash from SITEURL.") # If SITEURL is defined but FEED_DOMAIN isn't, # set FEED_DOMAIN to SITEURL if not 'FEED_DOMAIN' in settings: settings['FEED_DOMAIN'] = settings['SITEURL'] # Warn if feeds are generated with both SITEURL & FEED_DOMAIN undefined feed_keys = [ 'FEED_ATOM', 'FEED_RSS', 'FEED_ALL_ATOM', 'FEED_ALL_RSS', 'CATEGORY_FEED_ATOM', 'CATEGORY_FEED_RSS', 'TAG_FEED_ATOM', 'TAG_FEED_RSS', 'TRANSLATION_FEED_ATOM', 'TRANSLATION_FEED_RSS', ] if any(settings.get(k) for k in feed_keys): if not settings.get('SITEURL'): logger.warning('Feeds generated without SITEURL set properly may' ' not be valid') if not 'TIMEZONE' in settings: logger.warning( 'No timezone information specified in the settings. Assuming' ' your timezone is UTC for feed generation. Check ' 'http://docs.getpelican.com/en/latest/settings.html#timezone ' 'for more information') # fix up pagination rules from pelican.paginator import PaginationRule pagination_rules = [ PaginationRule(*r) for r in settings.get( 'PAGINATION_PATTERNS', DEFAULT_CONFIG['PAGINATION_PATTERNS'], ) ] settings['PAGINATION_PATTERNS'] = sorted( pagination_rules, key=lambda r: r[0], ) # Save people from accidentally setting a string rather than a list path_keys = ( 'ARTICLE_EXCLUDES', 'DEFAULT_METADATA', 'DIRECT_TEMPLATES', 'EXTRA_TEMPLATES_PATHS', 'FILES_TO_COPY', 'IGNORE_FILES', 'JINJA_EXTENSIONS', 'PAGINATED_DIRECT_TEMPLATES', 'PLUGINS', 'STATIC_PATHS', 'THEME_STATIC_PATHS', ) for PATH_KEY in filter(lambda k: k in settings, path_keys): if isinstance(settings[PATH_KEY], six.string_types): logger.warning("Detected misconfiguration with %s setting " "(must be a list), falling back to the default" % PATH_KEY) settings[PATH_KEY] = DEFAULT_CONFIG[PATH_KEY] for old, new, doc in [ ('LESS_GENERATOR', 'the Webassets plugin', None), ('FILES_TO_COPY', 'STATIC_PATHS and EXTRA_PATH_METADATA', 'https://github.com/getpelican/pelican/blob/master/docs/settings.rst#path-metadata'), ]: if old in settings: message = 'The {} setting has been removed in favor of {}'.format( old, new) if doc: message += ', see {} for details'.format(doc) logger.warning(message) return settings pelican-3.3/pelican/signals.py0000644000076500000240000000235712207763674016175 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function from blinker import signal # Run-level signals: initialized = signal('pelican_initialized') get_generators = signal('get_generators') finalized = signal('pelican_finalized') # Reader-level signals readers_init = signal('readers_init') # Generator-level signals generator_init = signal('generator_init') article_generator_init = signal('article_generator_init') article_generator_finalized = signal('article_generator_finalized') page_generator_init = signal('page_generator_init') page_generator_finalized = signal('page_generator_finalized') static_generator_init = signal('static_generator_init') static_generator_finalized = signal('static_generator_finalized') # Page-level signals article_generator_preread = signal('article_generator_preread') article_generator_context = signal('article_generator_context') page_generator_preread = signal('page_generator_preread') page_generator_context = signal('page_generator_context') static_generator_preread = signal('static_generator_preread') static_generator_context = signal('static_generator_context') content_object_init = signal('content_object_init') # Writers signals content_written = signal('content_written') pelican-3.3/pelican/tests/0000755000076500000240000000000012220367225015301 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/__init__.py0000666000076500000240000000010512130377623017415 0ustar jmstaff00000000000000import logging logging.getLogger().addHandler(logging.NullHandler()) pelican-3.3/pelican/tests/content/0000755000076500000240000000000012220367225016753 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/content/2012-11-29_rst_w_filename_meta#foo-bar.rst0000666000076500000240000000014312130377623026142 0ustar jmstaff00000000000000 Rst with filename metadata ########################## :category: yeah :author: Alexis Métaireau pelican-3.3/pelican/tests/content/2012-11-30_md_w_filename_meta#foo-bar.md0000666000076500000240000000015312130377623025513 0ustar jmstaff00000000000000category: yeah author: Alexis Métaireau Markdown with filename metadata =============================== pelican-3.3/pelican/tests/content/article.rst0000666000076500000240000000022312130377623021134 0ustar jmstaff00000000000000Article title ############# This is some content. With some stuff to "typogrify". Now with added support for :abbr:`TLA (three letter acronym)`. pelican-3.3/pelican/tests/content/article_with_comments.html0000666000076500000240000000023412130377623024232 0ustar jmstaff00000000000000 Body content pelican-3.3/pelican/tests/content/article_with_keywords.html0000644000076500000240000000022312177737636024265 0ustar jmstaff00000000000000 This is a super article ! pelican-3.3/pelican/tests/content/article_with_markdown_and_footnote.md0000644000076500000240000000035712150241517026416 0ustar jmstaff00000000000000Title: Article with markdown containing footnotes Date: 2012-10-31 Summary: Summary with **inline** markup *should* be supported. This is some content[^1] with some footnotes[^footnote] [^1]: Numbered footnote [^footnote]: Named footnotepelican-3.3/pelican/tests/content/article_with_markdown_and_nonascii_summary.md0000666000076500000240000000106412130377623030147 0ustar jmstaff00000000000000Title: マックOS X 10.8でパイソンとVirtualenvをインストールと設定 Slug: python-virtualenv-on-mac-osx-mountain-lion-10.8 Date: 2012-12-20 Tags: パイソン, マック Category: 指導書 Summary: パイソンとVirtualenvをまっくでインストールする方法について明確に説明します。 Writing unicode is certainly fun. パイソンとVirtualenvをまっくでインストールする方法について明確に説明します。 And let's mix languages. первый пост Now another. İlk yazı çok özel değil. pelican-3.3/pelican/tests/content/article_with_markdown_and_summary_metadata_multi.md0000666000076500000240000000027012130377623031334 0ustar jmstaff00000000000000Title: Article with markdown and summary metadata multi Date: 2012-10-31 Summary: A multi-line summary should be supported as well as **inline markup**. This is some content. pelican-3.3/pelican/tests/content/article_with_markdown_and_summary_metadata_single.md0000666000076500000240000000026212130377623031464 0ustar jmstaff00000000000000Title: Article with markdown and summary metadata single Date: 2012-10-30 Summary: A single-line summary should be supported as well as **inline markup**. This is some content. pelican-3.3/pelican/tests/content/article_with_markdown_markup_extensions.md0000666000076500000240000000007712130377623027526 0ustar jmstaff00000000000000Title: Test Markdown extensions [TOC] ## Level1 ### Level2 pelican-3.3/pelican/tests/content/article_with_md_extension.md0000666000076500000240000000040712130377623024537 0ustar jmstaff00000000000000Title: Test md File Category: test Tags: foo, bar, foobar Date: 2010-12-02 10:14 Summary: I have a lot to test Test Markdown File Header ========================= Used for pelican test --------------------- The quick brown fox jumped over the lazy dog's back. pelican-3.3/pelican/tests/content/article_with_metadata.html0000644000076500000240000000105412177737636024201 0ustar jmstaff00000000000000 This is a super article ! Multi-line metadata should be supported as well as inline markup. pelican-3.3/pelican/tests/content/article_with_metadata.rst0000666000076500000240000000041512220367223024025 0ustar jmstaff00000000000000 This is a super article ! ######################### :tags: foo, bar, foobar :date: 2010-12-02 10:14 :category: yeah :author: Alexis Métaireau :summary: Multi-line metadata should be supported as well as **inline markup**. :custom_field: http://notmyidea.org pelican-3.3/pelican/tests/content/article_with_metadata_and_contents.html0000644000076500000240000000106212177737636026737 0ustar jmstaff00000000000000 This is a super article ! Multi-line metadata should be supported as well as inline markup. pelican-3.3/pelican/tests/content/article_with_mkd_extension.mkd0000666000076500000240000000030412130377623025061 0ustar jmstaff00000000000000title: Test mkd File category: test Test Markdown File Header ========================= Used for pelican test --------------------- This is another markdown test file. Uses the mkd extension. pelican-3.3/pelican/tests/content/article_with_null_attributes.html0000666000076500000240000000024712130377623025631 0ustar jmstaff00000000000000 Ensure that empty attributes are copied properly. pelican-3.3/pelican/tests/content/article_with_template.rst0000666000076500000240000000026512130377623024070 0ustar jmstaff00000000000000Article with template ##################### :template: custom This article has a custom template to be called when rendered This is some content. With some stuff to "typogrify". pelican-3.3/pelican/tests/content/article_with_uppercase_metadata.html0000644000076500000240000000020712177737636026247 0ustar jmstaff00000000000000 This is a super article ! pelican-3.3/pelican/tests/content/article_with_uppercase_metadata.rst0000666000076500000240000000010712130377623026077 0ustar jmstaff00000000000000 This is a super article ! ######################### :Category: Yeah pelican-3.3/pelican/tests/content/article_without_category.rst0000666000076500000240000000017712130377623024624 0ustar jmstaff00000000000000 This is an article without category ! ##################################### This article should be in the DEFAULT_CATEGORY. pelican-3.3/pelican/tests/content/TestCategory/0000755000076500000240000000000012220367225021370 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/content/TestCategory/article_with_category.rst0000666000076500000240000000022512130377623026503 0ustar jmstaff00000000000000This is an article with category ! ################################## :category: yeah :date: 1970-01-01 This article should be in 'yeah' category. pelican-3.3/pelican/tests/content/TestCategory/article_without_category.rst0000666000076500000240000000020012130377623027224 0ustar jmstaff00000000000000This is an article without category ! ##################################### This article should be in 'TestCategory' category. pelican-3.3/pelican/tests/content/wordpressexport.xml0000666000076500000240000013165112130377623023005 0ustar jmstaff00000000000000 Pelican test channel http://thisisa.test Not a real feed, just for test Sun, 13 May 2012 01:13:52 +0000 en 1.1 http://thisisa.test http://thisisa.test 2Bobbob@thisisa.test 3Jonhjonh@thisisa.test 7categ-1 11categ-2 1uncategorized 15categ-3 25tag-1 122tag2 68tag-3 http://wordpress.org/?v=3.3.1 Empty post http://thisisa.test/?attachment_id=24 Sat, 04 Feb 2012 03:17:33 +0000 bob https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Pelican_lakes_entrance02.jpg/240px-Pelican_lakes_entrance02.jpg 24 2012-02-04 03:17:33 2012-02-04 03:17:33 open open empty-post inherit 0 0 attachment 0 https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Pelican_lakes_entrance02.jpg/240px-Pelican_lakes_entrance02.jpg _wp_attachment_metadata _wp_attached_file _wp_attachment_image_alt http://thisisa.test/?p=168 Thu, 01 Jan 1970 00:00:00 +0000 bob http://thisisa.test/?p=168 168 2012-02-15 21:23:57 0000-00-00 00:00:00 open open draft 0 0 post 0 _edit_last A normal post http://thisisa.test/?p=174 Thu, 01 Jan 1970 00:00:00 +0000 bob http://thisisa.test/?p=174
  • Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  • Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  • Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.]]>
    174 2012-02-16 15:52:55 0000-00-00 00:00:00 open open draft 0 0 post 0 _edit_last
    Complete draft http://thisisa.test/?p=176 Thu, 01 Jan 1970 00:00:00 +0000 bob http://thisisa.test/?p=176 176 2012-02-17 15:11:55 0000-00-00 00:00:00 open open draft 0 0 post 0 _edit_last Page http://thisisa.test/contact/ Wed, 11 Apr 2012 11:38:08 +0000 bob http://thisisa.test/?page_id=334 334 2012-04-11 06:38:08 2012-04-11 11:38:08 open open contact publish 0 0 page 0 sharing_disabled _wp_page_template _edit_last Empty Page http://thisisa.test/empty/ Wed, 11 Apr 2012 11:38:08 +0000 bob http://thisisa.test/?page_id=334 334 2012-04-11 06:38:08 2012-04-11 11:38:08 open open empty publish 0 0 page 0 sharing_disabled _wp_page_template _edit_last Special chars: l'é http://thisisa.test/?p=471 Thu, 01 Jan 1970 00:00:00 +0000 bob http://thisisa.test/?p=471 471 2012-04-29 09:44:27 0000-00-00 00:00:00 open open draft 0 0 post 0 _edit_last With excerpt http://thisisa.test/with-excerpt/ Sat, 04 Feb 2012 02:03:06 +0000 bob http://thisisa.test/?p=8 8 2012-02-04 02:03:06 2012-02-04 02:03:06 open open with-excerpt publish 0 0 post 0 _edit_last et_bigpost _thumbnail_id With tags http://thisisa.test/tags/ Sat, 04 Feb 2012 21:05:25 +0000 bob http://thisisa.test/?p=25 25 2012-02-04 21:05:25 2012-02-04 21:05:25 open open with-tags publish 0 0 post 0 _edit_last et_bigpost _thumbnail_id With comments http://thisisa.test/with-comments/ Wed, 18 Apr 2012 08:36:26 +0000 john http://thisisa.test/?p=422 422 2012-04-18 03:36:26 2012-04-18 08:36:26 open open with-comments publish 0 0 post 0 _edit_last _thumbnail_id 116 User2@mail.test 127.0.0.1 2012-05-06 15:46:06 2012-05-06 20:46:06 1 0 0 akismet_result akismet_history akismet_as_submitted 117 bob@thisisa.test 127.0.0.1 2012-05-06 17:44:06 2012-05-06 22:44:06 1 116 3 akismet_result akismet_history akismet_as_submitted 156 http://thisisa.test/to-article-you-ping-back/ 127.0.0.1 2012-05-09 19:30:19 2012-05-10 00:30:19 trash pingback 0 0 akismet_history _wp_trash_meta_status _wp_trash_meta_time 122 bob@thisisa.test 127.0.0.1 2012-05-07 14:11:34 2012-05-07 19:11:34 1 121 3 akismet_result akismet_history akismet_as_submitted Post with raw data http://thisisa.test/?p=173 Thu, 01 Jan 1970 00:00:00 +0000 bob http://thisisa.test/?p=173 Pelicans are scary Pelicans are supposed to eat fish, damn it! Bottom line: don't mess up with birds]]> 173 2012-02-16 15:52:55 0000-00-00 00:00:00 open open post-with-raw-data publish 0 0 post 0 _edit_last A normal post with some <html> entities in the title. You can't miss them. http://thisisa.test/?p=175 Thu, 01 Jan 1970 00:00:00 +0000 bob http://thisisa.test/?p=175
  • Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  • Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  • Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.]]>
    175 2012-02-16 15:52:55 0000-00-00 00:00:00 open open html-entity-test publish 0 0 post 0 _edit_last
    Code in List http://thisisa.test/?p=175 Thu, 01 Jan 1970 00:00:00 +0000 bob http://thisisa.test/?p=175
  • List Item One!
  • List Item Two!
  • This is a code sample
    
      a = [1, 2, 3]
      b = [4, 5, 6]
      for i in zip(a, b):
        print i
    
    
  • List Item Four!
  • Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.]]>
    175 2012-02-16 15:52:55 0000-00-00 00:00:00 open open code-in-list-test publish 0 0 post 0 _edit_last
    pelican-3.3/pelican/tests/default_conf.py0000644000076500000240000000244512177737636020333 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function AUTHOR = 'Alexis Métaireau' SITENAME = "Alexis' log" SITEURL = 'http://blog.notmyidea.org' TIMEZONE = 'UTC' GITHUB_URL = 'http://github.com/ametaireau/' DISQUS_SITENAME = "blog-notmyidea" PDF_GENERATOR = False REVERSE_CATEGORY_ORDER = True DEFAULT_PAGINATION = 2 FEED_RSS = 'feeds/all.rss.xml' CATEGORY_FEED_RSS = 'feeds/%s.rss.xml' LINKS = (('Biologeek', 'http://biologeek.org'), ('Filyb', "http://filyb.info/"), ('Libert-fr', "http://www.libert-fr.com"), ('N1k0', "http://prendreuncafe.com/blog/"), ('Tarek Ziadé', "http://ziade.org/blog"), ('Zubin Mithra', "http://zubin71.wordpress.com/"),) SOCIAL = (('twitter', 'http://twitter.com/ametaireau'), ('lastfm', 'http://lastfm.com/user/akounet'), ('github', 'http://github.com/ametaireau'),) # global metadata to all the contents DEFAULT_METADATA = (('yeah', 'it is'),) # path-specific metadata EXTRA_PATH_METADATA = { 'extra/robots.txt': {'path': 'robots.txt'}, } # static paths will be copied without parsing their contents STATIC_PATHS = [ 'pictures', 'extra/robots.txt', ] # foobar will not be used, because it's not in caps. All configuration keys # have to be in caps foobar = "barbaz" pelican-3.3/pelican/tests/output/0000755000076500000240000000000012220367225016641 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/0000755000076500000240000000000012220367225017722 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/a-markdown-powered-article.html0000644000076500000240000000544512215535610025743 0ustar jmstaff00000000000000 A markdown powered article
    pelican-3.3/pelican/tests/output/basic/archives.html0000644000076500000240000000607112215535610022417 0ustar jmstaff00000000000000 A Pelican Blog

    Archives for A Pelican Blog

    Fri 30 November 2012
    FILENAME_METADATA example
    Wed 29 February 2012
    Second article
    Wed 20 April 2011
    A markdown powered article
    Thu 17 February 2011
    Article 1
    Thu 17 February 2011
    Article 2
    Thu 17 February 2011
    Article 3
    Thu 02 December 2010
    This is a super article !
    Wed 20 October 2010
    Oh yeah !
    Fri 15 October 2010
    Unbelievable !
    Sun 14 March 2010
    The baz tag
    pelican-3.3/pelican/tests/output/basic/article-1.html0000644000076500000240000000510112215535610022365 0ustar jmstaff00000000000000 Article 1
    pelican-3.3/pelican/tests/output/basic/article-2.html0000644000076500000240000000510112215535610022366 0ustar jmstaff00000000000000 Article 2
    pelican-3.3/pelican/tests/output/basic/article-3.html0000644000076500000240000000510112215535610022367 0ustar jmstaff00000000000000 Article 3
    pelican-3.3/pelican/tests/output/basic/author/0000755000076500000240000000000012220367225021224 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/author/alexis-metaireau.html0000644000076500000240000001144012215535610025350 0ustar jmstaff00000000000000 A Pelican Blog - Alexis Métaireau

    Other articles


    pelican-3.3/pelican/tests/output/basic/authors.html0000644000076500000240000000427712215535610022306 0ustar jmstaff00000000000000 A Pelican Blog - Authors

    Authors on A Pelican Blog

  • Alexis Métaireau (2)
  • pelican-3.3/pelican/tests/output/basic/categories.html0000644000076500000240000000434412215535610022741 0ustar jmstaff00000000000000 A Pelican Blog
    pelican-3.3/pelican/tests/output/basic/category/0000755000076500000240000000000012220367225021537 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/category/bar.html0000644000076500000240000000611312215535610023171 0ustar jmstaff00000000000000 A Pelican Blog - bar
    pelican-3.3/pelican/tests/output/basic/category/cat1.html0000644000076500000240000001170212215535610023255 0ustar jmstaff00000000000000 A Pelican Blog - cat1

    Other articles


    pelican-3.3/pelican/tests/output/basic/category/misc.html0000644000076500000240000001433012216354256023366 0ustar jmstaff00000000000000 A Pelican Blog - misc

    Other articles


    1. The baz tag

      Sun 14 March 2010

      In misc.

      This article overrides the listening of the articles under the baz tag.

      read more
    pelican-3.3/pelican/tests/output/basic/category/yeah.html0000644000076500000240000000670012215535610023355 0ustar jmstaff00000000000000 A Pelican Blog - yeah
    pelican-3.3/pelican/tests/output/basic/feeds/0000755000076500000240000000000012220367225021010 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/feeds/all-en.atom.xml0000644000076500000240000004260712216354256023657 0ustar jmstaff00000000000000 A Pelican Blog/2012-11-30T00:00:00ZFILENAME_METADATA example2012-11-30T00:00:00Ztag:,2012-11-30:filename_metadata-example.html<p>Some cool stuff!</p> Second article2012-02-29T00:00:00Ztag:,2012-02-29:second-article.html<p>This is some article, in english</p> A markdown powered article2011-04-20T00:00:00Ztag:,2011-04-20:a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="/unbelievable.html">a root-relative link to unbelievable</a> <a href="/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00Ztag:,2011-02-17:article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00Ztag:,2011-02-17:article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00Ztag:,2011-02-17:article-3.html<p>Article 3</p> This is a super article !2010-12-02T10:14:00ZAlexis Métaireautag:,2010-12-02:this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="|filename|/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="|filename|/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> Oh yeah !2010-10-20T10:14:00ZAlexis Métaireautag:,2010-10-20:oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="|filename|/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> Unbelievable !2010-10-15T20:30:00Ztag:,2010-10-15:unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00Ztag:,2010-03-14:tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> pelican-3.3/pelican/tests/output/basic/feeds/all-fr.atom.xml0000666000076500000240000000122612130377623023656 0ustar jmstaff00000000000000 A Pelican Blog/2012-02-29T00:00:00ZDeuxième article2012-02-29T00:00:00Ztag:,2012-02-29:second-article-fr.html<p>Ceci est un article, en français.</p> pelican-3.3/pelican/tests/output/basic/feeds/all.atom.xml0000644000076500000240000004343012216354256023252 0ustar jmstaff00000000000000 A Pelican Blog/2012-11-30T00:00:00ZFILENAME_METADATA example2012-11-30T00:00:00Ztag:,2012-11-30:filename_metadata-example.html<p>Some cool stuff!</p> Second article2012-02-29T00:00:00Ztag:,2012-02-29:second-article.html<p>This is some article, in english</p> Deuxième article2012-02-29T00:00:00Ztag:,2012-02-29:second-article-fr.html<p>Ceci est un article, en français.</p> A markdown powered article2011-04-20T00:00:00Ztag:,2011-04-20:a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="/unbelievable.html">a root-relative link to unbelievable</a> <a href="/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00Ztag:,2011-02-17:article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00Ztag:,2011-02-17:article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00Ztag:,2011-02-17:article-3.html<p>Article 3</p> This is a super article !2010-12-02T10:14:00ZAlexis Métaireautag:,2010-12-02:this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="|filename|/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="|filename|/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> Oh yeah !2010-10-20T10:14:00ZAlexis Métaireautag:,2010-10-20:oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="|filename|/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> Unbelievable !2010-10-15T20:30:00Ztag:,2010-10-15:unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00Ztag:,2010-03-14:tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> pelican-3.3/pelican/tests/output/basic/feeds/bar.atom.xml0000666000076500000240000000162312130377623023246 0ustar jmstaff00000000000000 A Pelican Blog/2010-10-20T10:14:00ZOh yeah !2010-10-20T10:14:00ZAlexis Métaireautag:,2010-10-20:oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="|filename|/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> pelican-3.3/pelican/tests/output/basic/feeds/cat1.atom.xml0000666000076500000240000000300612130377623023327 0ustar jmstaff00000000000000 A Pelican Blog/2011-04-20T00:00:00ZA markdown powered article2011-04-20T00:00:00Ztag:,2011-04-20:a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="/unbelievable.html">a root-relative link to unbelievable</a> <a href="/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00Ztag:,2011-02-17:article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00Ztag:,2011-02-17:article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00Ztag:,2011-02-17:article-3.html<p>Article 3</p> pelican-3.3/pelican/tests/output/basic/feeds/misc.atom.xml0000644000076500000240000003461312216354256023440 0ustar jmstaff00000000000000 A Pelican Blog/2012-11-30T00:00:00ZFILENAME_METADATA example2012-11-30T00:00:00Ztag:,2012-11-30:filename_metadata-example.html<p>Some cool stuff!</p> Second article2012-02-29T00:00:00Ztag:,2012-02-29:second-article.html<p>This is some article, in english</p> Unbelievable !2010-10-15T20:30:00Ztag:,2010-10-15:unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00Ztag:,2010-03-14:tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> pelican-3.3/pelican/tests/output/basic/feeds/yeah.atom.xml0000666000076500000240000000254012130377623023427 0ustar jmstaff00000000000000 A Pelican Blog/2010-12-02T10:14:00ZThis is a super article !2010-12-02T10:14:00ZAlexis Métaireautag:,2010-12-02:this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="|filename|/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="|filename|/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> pelican-3.3/pelican/tests/output/basic/filename_metadata-example.html0000644000076500000240000000521012215535610025656 0ustar jmstaff00000000000000 FILENAME_METADATA example
    pelican-3.3/pelican/tests/output/basic/index.html0000644000076500000240000002653112216354256021733 0ustar jmstaff00000000000000 A Pelican Blog

    Other articles


    1. The baz tag

      Sun 14 March 2010

      In misc.

      This article overrides the listening of the articles under the baz tag.

      read more
    pelican-3.3/pelican/tests/output/basic/oh-yeah.html0000644000076500000240000000610612215535610022144 0ustar jmstaff00000000000000 Oh yeah !

    Oh yeah !

    Why not ?

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

    alternate text
    pelican-3.3/pelican/tests/output/basic/override/0000755000076500000240000000000012220367225021541 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/override/index.html0000644000076500000240000000437212215535610023543 0ustar jmstaff00000000000000 Override url/save_as

    Override url/save_as

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

    pelican-3.3/pelican/tests/output/basic/pages/0000755000076500000240000000000012220367225021021 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/pages/this-is-a-test-hidden-page.html0000644000076500000240000000437412215535610026634 0ustar jmstaff00000000000000 This is a test hidden page

    This is a test hidden page

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

    pelican-3.3/pelican/tests/output/basic/pages/this-is-a-test-page.html0000644000076500000240000000441312215535610025375 0ustar jmstaff00000000000000 This is a test page

    This is a test page

    Just an image.

    alternate text
    pelican-3.3/pelican/tests/output/basic/second-article-fr.html0000644000076500000240000000544012215535610024113 0ustar jmstaff00000000000000 Deuxième article
    pelican-3.3/pelican/tests/output/basic/second-article.html0000644000076500000240000000542512215535610023511 0ustar jmstaff00000000000000 Second article
    pelican-3.3/pelican/tests/output/basic/tag/0000755000076500000240000000000012220367225020475 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/tag/bar.html0000644000076500000240000001226212215535610022131 0ustar jmstaff00000000000000 A Pelican Blog - bar

    Other articles


    pelican-3.3/pelican/tests/output/basic/tag/baz.html0000644000076500000240000000521112215535610022135 0ustar jmstaff00000000000000 The baz tag

    The baz tag

    Sun 14 March 2010

    In misc.

    This article overrides the listening of the articles under the baz tag.

    pelican-3.3/pelican/tests/output/basic/tag/foo.html0000644000076500000240000001000212215535610022136 0ustar jmstaff00000000000000 A Pelican Blog - foo

    Other articles


    pelican-3.3/pelican/tests/output/basic/tag/foobar.html0000644000076500000240000000666312215535610022645 0ustar jmstaff00000000000000 A Pelican Blog - foobar
    pelican-3.3/pelican/tests/output/basic/tag/oh.html0000644000076500000240000000431312215535610021771 0ustar jmstaff00000000000000 Oh Oh Oh

    Oh Oh Oh

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

    pelican-3.3/pelican/tests/output/basic/tag/yeah.html0000644000076500000240000000607512215535610022320 0ustar jmstaff00000000000000 A Pelican Blog - yeah
    pelican-3.3/pelican/tests/output/basic/tags.html0000644000076500000240000000465312215535610021555 0ustar jmstaff00000000000000 A Pelican Blog - Tags

    Tags for A Pelican Blog

  • bar (3)
  • baz (1)
  • foo (2)
  • foobar (1)
  • oh (1)
  • yeah (1)
  • pelican-3.3/pelican/tests/output/basic/theme/0000755000076500000240000000000012220367225021024 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/theme/css/0000755000076500000240000000000012220367225021614 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/theme/css/main.css0000666000076500000240000002531012171064114023253 0ustar jmstaff00000000000000/* Name: Smashing HTML5 Date: July 2009 Description: Sample layout for HTML5 and CSS3 goodness. Version: 1.0 License: MIT Licensed by: Smashing Media GmbH Original author: Enrique Ramírez */ /* Imports */ @import url("reset.css"); @import url("pygment.css"); @import url("typogrify.css"); @import url(//fonts.googleapis.com/css?family=Yanone+Kaffeesatz&subset=latin); /***** Global *****/ /* Body */ body { background: #F5F4EF; color: #000305; font-size: 87.5%; /* Base font size: 14px */ font-family: 'Trebuchet MS', Trebuchet, 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; line-height: 1.429; margin: 0; padding: 0; text-align: left; } /* Headings */ h1 {font-size: 2em } h2 {font-size: 1.571em} /* 22px */ h3 {font-size: 1.429em} /* 20px */ h4 {font-size: 1.286em} /* 18px */ h5 {font-size: 1.143em} /* 16px */ h6 {font-size: 1em} /* 14px */ h1, h2, h3, h4, h5, h6 { font-weight: 400; line-height: 1.1; margin-bottom: .8em; font-family: 'Yanone Kaffeesatz', arial, serif; } h3, h4, h5, h6 { margin-top: .8em; } hr { border: 2px solid #EEEEEE; } /* Anchors */ a {outline: 0;} a img {border: 0px; text-decoration: none;} a:link, a:visited { color: #C74350; padding: 0 1px; text-decoration: underline; } a:hover, a:active { background-color: #C74350; color: #fff; text-decoration: none; text-shadow: 1px 1px 1px #333; } h1 a:hover { background-color: inherit } /* Paragraphs */ div.line-block, p { margin-top: 1em; margin-bottom: 1em;} strong, b {font-weight: bold;} em, i {font-style: italic;} /* Lists */ ul { list-style: outside disc; margin: 0em 0 0 1.5em; } ol { list-style: outside decimal; margin: 0em 0 0 1.5em; } li { margin-top: 0.5em;} .post-info { float:right; margin:10px; padding:5px; } .post-info p{ margin-top: 1px; margin-bottom: 1px; } .readmore { float: right } dl {margin: 0 0 1.5em 0;} dt {font-weight: bold;} dd {margin-left: 1.5em;} pre{background-color: rgb(238, 238, 238); padding: 10px; margin: 10px; overflow: auto;} /* Quotes */ blockquote { margin: 20px; font-style: italic; } cite {} q {} div.note { float: right; margin: 5px; font-size: 85%; max-width: 300px; } /* Tables */ table {margin: .5em auto 1.5em auto; width: 98%;} /* Thead */ thead th {padding: .5em .4em; text-align: left;} thead td {} /* Tbody */ tbody td {padding: .5em .4em;} tbody th {} tbody .alt td {} tbody .alt th {} /* Tfoot */ tfoot th {} tfoot td {} /* HTML5 tags */ header, section, footer, aside, nav, article, figure { display: block; } /***** Layout *****/ .body {clear: both; margin: 0 auto; width: 800px;} img.right, figure.right {float: right; margin: 0 0 2em 2em;} img.left, figure.left {float: left; margin: 0 2em 2em 0;} /* Header *****************/ #banner { margin: 0 auto; padding: 2.5em 0 0 0; } /* Banner */ #banner h1 {font-size: 3.571em; line-height: 0;} #banner h1 a:link, #banner h1 a:visited { color: #000305; display: block; font-weight: bold; margin: 0 0 .6em .2em; text-decoration: none; } #banner h1 a:hover, #banner h1 a:active { background: none; color: #C74350; text-shadow: none; } #banner h1 strong {font-size: 0.36em; font-weight: normal;} /* Main Nav */ #banner nav { background: #000305; font-size: 1.143em; height: 40px; line-height: 30px; margin: 0 auto 2em auto; padding: 0; text-align: center; width: 800px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #banner nav ul {list-style: none; margin: 0 auto; width: 800px;} #banner nav li {float: left; display: inline; margin: 0;} #banner nav a:link, #banner nav a:visited { color: #fff; display: inline-block; height: 30px; padding: 5px 1.5em; text-decoration: none; } #banner nav a:hover, #banner nav a:active, #banner nav .active a:link, #banner nav .active a:visited { background: #C74451; color: #fff; text-shadow: none !important; } #banner nav li:first-child a { border-top-left-radius: 5px; -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; } /* Featured *****************/ #featured { background: #fff; margin-bottom: 2em; overflow: hidden; padding: 20px; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #featured figure { border: 2px solid #eee; float: right; margin: 0.786em 2em 0 5em; width: 248px; } #featured figure img {display: block; float: right;} #featured h2 {color: #C74451; font-size: 1.714em; margin-bottom: 0.333em;} #featured h3 {font-size: 1.429em; margin-bottom: .5em;} #featured h3 a:link, #featured h3 a:visited {color: #000305; text-decoration: none;} #featured h3 a:hover, #featured h3 a:active {color: #fff;} /* Body *****************/ #content { background: #fff; margin-bottom: 2em; overflow: hidden; padding: 20px 20px; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } /* Extras *****************/ #extras {margin: 0 auto 3em auto; overflow: hidden;} #extras ul {list-style: none; margin: 0;} #extras li {border-bottom: 1px solid #fff;} #extras h2 { color: #C74350; font-size: 1.429em; margin-bottom: .25em; padding: 0 3px; } #extras a:link, #extras a:visited { color: #444; display: block; border-bottom: 1px solid #F4E3E3; text-decoration: none; padding: .3em .25em; } #extras a:hover, #extras a:active {color: #fff;} /* Blogroll */ #extras .blogroll { float: left; width: 615px; } #extras .blogroll li {float: left; margin: 0 20px 0 0; width: 185px;} /* Social */ #extras .social { float: right; width: 175px; } #extras div[class='social'] a { background-repeat: no-repeat; background-position: 3px 6px; padding-left: 25px; } /* Icons */ .social a[href*='about.me'] {background-image: url('../images/icons/aboutme.png');} .social a[href*='bitbucket.org'] {background-image: url('../images/icons/bitbucket.png');} .social a[href*='delicious.com'] {background-image: url('../images/icons/delicious.png');} .social a[href*='digg.com'] {background-image: url('../images/icons/digg.png');} .social a[href*='facebook.com'] {background-image: url('../images/icons/facebook.png');} .social a[href*='gitorious.org'] {background-image: url('../images/icons/gitorious.png');} .social a[href*='github.com'], .social a[href*='git.io'] {background-image: url('../images/icons/github.png');} .social a[href*='gittip.com'] {background-image: url('../images/icons/gittip.png');} .social a[href*='plus.google.com'] {background-image: url('../images/icons/google-plus.png');} .social a[href*='groups.google.com'] {background-image: url('../images/icons/google-groups.png');} .social a[href*='news.ycombinator.com'], .social a[href*='hackernewsers.com'] {background-image: url('../images/icons/hackernews.png');} .social a[href*='last.fm'], .social a[href*='lastfm.'] {background-image: url('../images/icons/lastfm.png');} .social a[href*='linkedin.com'] {background-image: url('../images/icons/linkedin.png');} .social a[href*='reddit.com'] {background-image: url('../images/icons/reddit.png');} .social a[type$='atom+xml'], .social a[type$='rss+xml'] {background-image: url('../images/icons/rss.png');} .social a[href*='slideshare.net'] {background-image: url('../images/icons/slideshare.png');} .social a[href*='speakerdeck.com'] {background-image: url('../images/icons/speakerdeck.png');} .social a[href*='stackoverflow.com'] {background-image: url('../images/icons/stackoverflow.png');} .social a[href*='twitter.com'] {background-image: url('../images/icons/twitter.png');} .social a[href*='vimeo.com'] {background-image: url('../images/icons/vimeo.png');} .social a[href*='youtube.com'] {background-image: url('../images/icons/youtube.png');} /* About *****************/ #about { background: #fff; font-style: normal; margin-bottom: 2em; overflow: hidden; padding: 20px; text-align: left; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #about .primary {float: left; width: 165px;} #about .primary strong {color: #C64350; display: block; font-size: 1.286em;} #about .photo {float: left; margin: 5px 20px;} #about .url:link, #about .url:visited {text-decoration: none;} #about .bio {float: right; width: 500px;} /* Footer *****************/ #contentinfo {padding-bottom: 2em; text-align: right;} /***** Sections *****/ /* Blog */ .hentry { display: block; clear: both; border-bottom: 1px solid #eee; padding: 1.5em 0; } li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} #content > .hentry {padding: 1em 0;} .hentry img{display : none ;} .entry-title {font-size: 3em; margin-bottom: 10px; margin-top: 0;} .entry-title a:link, .entry-title a:visited {text-decoration: none; color: #333;} .entry-title a:visited {background-color: #fff;} .hentry .post-info * {font-style: normal;} /* Content */ .hentry footer {margin-bottom: 2em;} .hentry footer address {display: inline;} #posts-list footer address {display: block;} /* Blog Index */ #posts-list {list-style: none; margin: 0;} #posts-list .hentry {padding-left: 10px; position: relative;} #posts-list footer { left: 10px; position: relative; float: left; top: 0.5em; width: 190px; } /* About the Author */ #about-author { background: #f9f9f9; clear: both; font-style: normal; margin: 2em 0; padding: 10px 20px 15px 20px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #about-author strong { color: #C64350; clear: both; display: block; font-size: 1.429em; } #about-author .photo {border: 1px solid #ddd; float: left; margin: 5px 1em 0 0;} /* Comments */ #comments-list {list-style: none; margin: 0 1em;} #comments-list blockquote { background: #f8f8f8; clear: both; font-style: normal; margin: 0; padding: 15px 20px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #comments-list footer {color: #888; padding: .5em 1em 0 0; text-align: right;} #comments-list li:nth-child(2n) blockquote {background: #F5f5f5;} /* Add a Comment */ #add-comment label {clear: left; float: left; text-align: left; width: 150px;} #add-comment input[type='text'], #add-comment input[type='email'], #add-comment input[type='url'] {float: left; width: 200px;} #add-comment textarea {float: left; height: 150px; width: 495px;} #add-comment p.req {clear: both; margin: 0 .5em 1em 0; text-align: right;} #add-comment input[type='submit'] {float: right; margin: 0 .5em;} #add-comment * {margin-bottom: .5em;} pelican-3.3/pelican/tests/output/basic/theme/css/pygment.css0000666000076500000240000000345212130377623024024 0ustar jmstaff00000000000000.hll { background-color:#eee; } .c { color:#408090; font-style:italic; } .err { border:1px solid #FF0000; } .k { color:#007020; font-weight:bold; } .o { color:#666666; } .cm { color:#408090; font-style:italic; } .cp { color:#007020; } .c1 { color:#408090; font-style:italic; } .cs { background-color:#FFF0F0; color:#408090; } .gd { color:#A00000; } .ge { font-style:italic; } .gr { color:#FF0000; } .gh { color:#000080; font-weight:bold; } .gi { color:#00A000; } .go { color:#303030; } .gp { color:#C65D09; font-weight:bold; } .gs { font-weight:bold; } .gu { color:#800080; font-weight:bold; } .gt { color:#0040D0; } .kc { color:#007020; font-weight:bold; } .kd { color:#007020; font-weight:bold; } .kn { color:#007020; font-weight:bold; } .kp { color:#007020; } .kr { color:#007020; font-weight:bold; } .kt { color:#902000; } .m { color:#208050; } .s { color:#4070A0; } .na { color:#4070A0; } .nb { color:#007020; } .nc { color:#0E84B5; font-weight:bold; } .no { color:#60ADD5; } .nd { color:#555555; font-weight:bold; } .ni { color:#D55537; font-weight:bold; } .ne { color:#007020; } .nf { color:#06287E; } .nl { color:#002070; font-weight:bold; } .nn { color:#0E84B5; font-weight:bold; } .nt { color:#062873; font-weight:bold; } .nv { color:#BB60D5; } .ow { color:#007020; font-weight:bold; } .w { color:#BBBBBB; } .mf { color:#208050; } .mh { color:#208050; } .mi { color:#208050; } .mo { color:#208050; } .sb { color:#4070A0; } .sc { color:#4070A0; } .sd { color:#4070A0; font-style:italic; } .s2 { color:#4070A0; } .se { color:#4070A0; font-weight:bold; } .sh { color:#4070A0; } .si { color:#70A0D0; font-style:italic; } .sx { color:#C65D09; } .sr { color:#235388; } .s1 { color:#4070A0; } .ss { color:#517918; } .bp { color:#007020; } .vc { color:#BB60D5; } .vg { color:#BB60D5; } .vi { color:#BB60D5; } .il { color:#208050; } pelican-3.3/pelican/tests/output/basic/theme/css/reset.css0000666000076500000240000000211712130377623023460 0ustar jmstaff00000000000000/* Name: Reset Stylesheet Description: Resets browser's default CSS Author: Eric Meyer Author URI: http://meyerweb.com/eric/tools/css/reset/ */ /* v1.0 | 20080212 */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { background: transparent; border: 0; font-size: 100%; margin: 0; outline: 0; padding: 0; vertical-align: baseline; } body {line-height: 1;} ol, ul {list-style: none;} blockquote, q {quotes: none;} blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } /* remember to define focus styles! */ :focus { outline: 0; } /* remember to highlight inserts somehow! */ ins {text-decoration: none;} del {text-decoration: line-through;} /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: collapse; border-spacing: 0; }pelican-3.3/pelican/tests/output/basic/theme/css/typogrify.css0000666000076500000240000000027612130377623024376 0ustar jmstaff00000000000000.caps {font-size:.92em;} .amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;} .dquo {margin-left:-.38em;} pelican-3.3/pelican/tests/output/basic/theme/css/wide.css0000666000076500000240000000115012130377623023262 0ustar jmstaff00000000000000@import url("main.css"); body { font:1.3em/1.3 "Hoefler Text","Georgia",Georgia,serif,sans-serif; } .post-info{ display: none; } #banner nav { display: none; -moz-border-radius: 0px; margin-bottom: 20px; overflow: hidden; font-size: 1em; background: #F5F4EF; } #banner nav ul{ padding-right: 50px; } #banner nav li{ float: right; color: #000; } #banner nav li a { color: #000; } #banner h1 { margin-bottom: -18px; } #featured, #extras { padding: 50px; } #featured { padding-top: 20px; } #extras { padding-top: 0px; padding-bottom: 0px; } pelican-3.3/pelican/tests/output/basic/theme/images/0000755000076500000240000000000012220367225022271 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/theme/images/icons/0000755000076500000240000000000012220367225023404 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/basic/theme/images/icons/aboutme.png0000666000076500000240000000135712132103620025545 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ< PLTE >b :\a``__^][XNz 8Y]\\ZZXVS Js Ch 6UXXWVUTRQ~N{ Lw El @d4S P} O| Nz Mx Lw Ku Js Hq Fn Ek @e >a2O Mw3 Ip Dj Bg >a <]0L Hp Ho Gn Bg Cg;]9Y ;[.I Dk :ZAf 7U=_0K,F@e(>=_%:6U"4*D2O'@/K &=-G#:*D!7(@4%=1k/tRNS@f pHYsHHFk>IDATURPEcJP t(P)RcB]7p $YpܪHWUU?9'g^DXz&[|y6:dd#'r7_4L˚7L?`ZW|;h%tEXtdate:create2013-03-15T18:16:20-07:00#6%tEXtdate:modify2013-03-15T18:16:16-07:00SIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/bitbucket.png0000666000076500000240000000720212132103620026060 0ustar jmstaff00000000000000PNG  IHDRh6 AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ pHYs  niTXtXML:com.adobe.xmp ? AmIDAT(ERkAtIݐۤ?jִPЖRD {$xP"1FlҺ>t GTЂ}FD%BdD,>[ēPR@+*ȌFՍJpL +x~,*p*K$ћBJ{iqne6;Ĉv}vpn`k KӲW7ͅ'tՅ |ZWotL,(w,}+WҩP8d״ˍJsP\ C$IAk筕sGt*JB\׆\08Sֿ#/9bSs\&_t@z8vIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/delicious.png0000666000076500000240000000167612132103620026075 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zcIDAT8ou}Kn6IKb*K D(B1/ 1Ll,t@JtCDڦIIS׉o{}yX,Vq#jKZxwv~}z;mgӃ`ڮfOk̙{~5޻~~n4i3/}{׃g½cW=>֚./}p B:m&tkJFLi_ ?ԓIrR "&bi?3$bZ)Hէڲ @8L !:(NDm2yqrK)I%dCesG J) ?ϧJ>2pF> 6`CAsJﳽG7qG52/}Cca@\Ş.M[9rʲ W*YR=*;{"""H$""_}47u6wD*x~8Q3̱P!L4֖j$FH|q  ƾJg0.q!`x@0^5"1"`E^'81ZB`0Kׯh'a.W Ox^8G,b89.~/T+^`c`j )efЩ2},W${{b1}x'mmnko}w㰻u`}?=}yf;wZ?W.72 䭘fIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/facebook.png0000666000076500000240000000031212132103620025650 0ustar jmstaff00000000000000PNG  IHDRRPLTE;Y;Y`xEbmgtRNSACbKGDH pHYsHHFk>=IDATc`F%0``0 e C%P RBeBT\Cp0K 0ef>IENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/github.png0000666000076500000240000000053212132103620025365 0ustar jmstaff00000000000000PNG  IHDRa pHYs  ~ IDAT8˕ӱJa VVB*A>m [[_*  MTl&.Og!hhr7"nq\r &0E,]3m+xLQ>嶝9y`C_ N]kEN!7 g-.@iF6XN_0J > 2#z okm|<˲U,,pt*+X4NO7m9KIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/gitorious.png0000666000076500000240000000034312132103620026127 0ustar jmstaff00000000000000PNG  IHDR(-SLbIDAT}1 % h#"#M 홴z)} .?_"{B4!>}HVU8T% )mu CbD, F IIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/gittip.png0000666000076500000240000000074712132103620025413 0ustar jmstaff00000000000000PNG  IHDRasRGBbKGD pHYs  tIME  mgIDAT8c`o0cm=H_P| *0CF`1d=6_LԄj.d*LsHg#MM@v7S!0lÕs' m`=-oqEv 4plٰl$.4g4ܴb)f ā@,`.&@yjB P q7!UA?~p11?FhhDd"EDm j4'$MOH(I%^V8ǟ)LfgoǑXIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/google-groups.png0000666000076500000240000000144312132103620026676 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<5PLTE,r#bFEB@>=:875}3{1zDB@<7~4|CA>=986~?>6~4|2{1x>2z0x=98;9/w1y0w2{.v3|.uʡ-ṭ,s+qtRNS}abKGD-IDAT5y[QW-q̄13p}(B/繞j;.{`(E( )-O$9dAL#B /$Jryu]Bpp2OiR.;7EBpNb>cã}%bP}fC}(,ggxE)_Oz70Yn`-:9@ 3$%ts%tEXtdate:create2013-01-13T02:11:01-08:00̕%tEXtdate:modify2013-01-13T02:10:36-08:00&zIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/google-plus.png0000666000076500000240000000101712132103620026337 0ustar jmstaff00000000000000PNG  IHDRh6IDAT(cmIbeq&nt9@ A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ pHYs  niTXtXML:com.adobe.xmp ? AIDAT8cD^V4?PAuLU?7g0arp m3Fpu06L.d s`]8bw3lfd ьP#<= Is aLd6\<(A_&#Ft6ab/$eqoIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/lastfm.png0000666000076500000240000000171712132103620025377 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zc(IDAT8OlU{v6*U(D Qc@#'ăO=sp1 ϩD--4Pv{??=~.KxNyfƤTH'*"1֮Br:i$k.>7HXy?؁s(I HrwL.Ig~ Ig9R  (%c5y@F6CH,D ? N6(!cQ6{dPȡpsJ0j0e$pNU.x " 8zZ^5˫3uh`{#at0:Nh`/F1%쑔}#l̮qo2^'#rxqS'ɽshb@c;2I~7;{U,J,yoɾq[ bYBE2'y:fIMw.);#,8vmJK"",7%KRd'""6Q,yJ泓'w>׍j﯒ܹ.P.3_XDz]e?n g_)G_{!bGժԡhvdKAg^䋅kwЕ!dOCPY.cЉ#[{AbXM~bѻD\k-3rUe<$7V%-e?O=k;ʆQFxD0UmTgjzϯ|psO?ϕsݪCIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/linkedin.png0000666000076500000240000000160012132103620025675 0ustar jmstaff00000000000000PNG  IHDR(-S7PLTEhiklklmmoommnnoonopqoqprrpqstsutv vw w v w y yx y yy { {zzzz{|{|~ !"#$%&',-21223E9:9::<=~^|^X۳~#rӯ#"{:(#u;p )*R)j NA^AT kk1HgO\(vo84QImÏY`e)S IENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/reddit.png0000666000076500000240000000126512132103620025362 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<PLTER[eeq}bjsdeg|_ju_lz`][JNSiup|VZ^ߍy)/6w]dknyo~djm{[aflpv><:w{qpoGGG20nprS\eɨFJNˁ~~~U^gjklգxgscmx6 pHYsHHFk>IDATePﵻ;X("6蠎s!/^`4-V-r{>]44"O$S > b\8!Vo4[xj65Bڝ.z6!0'c`4ԢS|j|,sMō6spy /R1$ DBTr\ߤ0^|xfNܸ !bT S<~C# %g;$/)QEuM"I`^~.:%n課~| wV :&15R§w 3OPvmd)$ỵ_%YBڶȦ3_JndW|Ui#5Lf:JS8d$7ԈPwɸ^?3u}ȜmEfS쮉 A*bk;K/T1UcDjVz_3:T80}wNpJɠAke,}:{m;?[/4E5[񮺱馕ny'}^8+` x<IENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/slideshare.png0000666000076500000240000000102712132103620026226 0ustar jmstaff00000000000000PNG  IHDR(-SPLTEâz既d{o˦K>dHk;}unw;97o&wE4fpA,]_z|r]+,$zqfmaHtRNS-)IDATNP^oea01Hc\iGL89qM,n$$LzROQ ]vgchKl#u_וb?oQܔ! . k;GW/ JD44!9ԛIENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/speakerdeck.png0000666000076500000240000000203112132103620026360 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<PLTE9,2tU7]6~\6\7]3uU.qSF~G/qS.vW(qS(pS#kO"jNeKdK_I`I[GXFXETDQCOAMAM@K@I?H?I@A;`VaVB;$!F@F@E??|>{>{@|?{?|;x7u6u6u6t7v;y6u4s3r3q3r4s2r/o0p0q1q,m,l*i*h*g)g)g)f+j,m)j'f\FP>O<VCYGUCN<\F(g%g#bM<K3A7Dd]@d\Ed^A8 =2G:|bv_r\^MXHXHUEUFVGVF_Ns]o\n[p\o\o[n[hXgXgWgXfWfWhYbVaU`T `TcV^U ]U ]T ]S \SǶ(tRNS{{m pHYsHHFk> IDATc``dbfaef&6v M-m]-mN.n=}}C}C#c}nS333s KKKs+3+S^>k[ "[{~G'gWW77wgOA!/o_? /aаȨظ$Դ̬d1¢⒒ҲJqںƦ*Iֶ֎ֶήVi }d&MIDATHT;H+A3;dU (AĀ [(#l"Z GVjaF% PPD$dd;!Oŧ»a̜{a|exc)]^ Cnw4LrtW ݛ&ơ_(r:_6ndkcTRgR@@ W>Ez8>8;0Gi!D)c oԌ󳢌vu qÍeGi|ee.'F_ `l!XE|v TՍ BfgE㹻BHr9!R}Aq==E"T[kO` cR)t] Tt]Υ[JK eYL@J)憳WW$oo׽ssD6{yrUUe##V+!>5c`LmߗM`?ZZLbRJ(eLI4fRBU֦iU.! d2vN3qGg;;!!Ðee]7 !qE'`0dw$ jQ盛 hכl ''PO5(6V\Q(u>~ [e(~@~;IɅT%tEXtdate:create2013-07-03T22:30:09-07:001D%tEXtdate:modify2013-07-01T14:56:54-07:00IENDB`pelican-3.3/pelican/tests/output/basic/theme/images/icons/twitter.png0000666000076500000240000000147612132103620025615 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zcIDAT8Kk]U߻D :;8ळE*"A/ M/i^2n$J) Qe This is a super article !
    pelican-3.3/pelican/tests/output/basic/unbelievable.html0000644000076500000240000002757012216354256023265 0ustar jmstaff00000000000000 Unbelievable !

    Unbelievable !

    Fri 15 October 2010

    In misc.

    Or completely awesome. Depends the needs.

    a root-relative link to markdown-article a file-relative link to markdown-article

    Testing sourcecode directive

    1
    formatter = self.options and VARIANTS[self.options.keys()[0]]
    

    Testing another case

    This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.

    formatter = self.options and VARIANTS[self.options.keys()[0]]
    

    Lovely.

    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')]

    Lovely.

    Testing even more sourcecode directives

    formatter = self.options and VARIANTS[self.options.keys()[0]]

    Lovely.

    Testing overriding config defaults

    Even if the default is line numbers, we can override it here

    formatter = self.options and VARIANTS[self.options.keys()[0]]
    

    Lovely.

    pelican-3.3/pelican/tests/output/custom/0000755000076500000240000000000012220367225020153 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/a-markdown-powered-article.html0000644000076500000240000001261212215535610026166 0ustar jmstaff00000000000000 A markdown powered article Fork me on GitHub

    A markdown powered article

    You're mutually oblivious.

    a root-relative link to unbelievable a file-relative link to unbelievable

    Comments !

    pelican-3.3/pelican/tests/output/custom/archives.html0000644000076500000240000001165712215535610022656 0ustar jmstaff00000000000000 Alexis' log Fork me on GitHub

    Archives for Alexis' log

    Fri 30 November 2012
    FILENAME_METADATA example
    Wed 29 February 2012
    Second article
    Wed 20 April 2011
    A markdown powered article
    Thu 17 February 2011
    Article 1
    Thu 17 February 2011
    Article 2
    Thu 17 February 2011
    Article 3
    Thu 02 December 2010
    This is a super article !
    Wed 20 October 2010
    Oh yeah !
    Fri 15 October 2010
    Unbelievable !
    Sun 14 March 2010
    The baz tag
    pelican-3.3/pelican/tests/output/custom/article-1.html0000644000076500000240000001220212215535610022616 0ustar jmstaff00000000000000 Article 1 Fork me on GitHub

    Article 1

    Article 1

    Comments !

    pelican-3.3/pelican/tests/output/custom/article-2.html0000644000076500000240000001220212215535610022617 0ustar jmstaff00000000000000 Article 2 Fork me on GitHub

    Article 2

    Article 2

    Comments !

    pelican-3.3/pelican/tests/output/custom/article-3.html0000644000076500000240000001220212215535610022620 0ustar jmstaff00000000000000 Article 3 Fork me on GitHub

    Article 3

    Article 3

    Comments !

    pelican-3.3/pelican/tests/output/custom/author/0000755000076500000240000000000012220367225021455 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/author/alexis-metaireau.html0000644000076500000240000002022612215535610025603 0ustar jmstaff00000000000000 Alexis' log - Alexis Métaireau Fork me on GitHub

    Other articles


    Page 1 / 3 »

    pelican-3.3/pelican/tests/output/custom/author/alexis-metaireau2.html0000644000076500000240000002103212215535610025661 0ustar jmstaff00000000000000 Alexis' log - Alexis Métaireau Fork me on GitHub

    « Page 2 / 3 »

    pelican-3.3/pelican/tests/output/custom/author/alexis-metaireau3.html0000644000076500000240000001632512216354256025701 0ustar jmstaff00000000000000 Alexis' log - Alexis Métaireau Fork me on GitHub

    « Page 3 / 3

    pelican-3.3/pelican/tests/output/custom/authors.html0000644000076500000240000001005512215535610022526 0ustar jmstaff00000000000000 Alexis' log - Authors Fork me on GitHub

    Authors on Alexis' log

  • Alexis Métaireau (10)
  • pelican-3.3/pelican/tests/output/custom/categories.html0000644000076500000240000001012712215535610023166 0ustar jmstaff00000000000000 Alexis' log Fork me on GitHub
    pelican-3.3/pelican/tests/output/custom/category/0000755000076500000240000000000012220367225021770 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/category/bar.html0000644000076500000240000001216112215535610023422 0ustar jmstaff00000000000000 Alexis' log - bar Fork me on GitHub
    pelican-3.3/pelican/tests/output/custom/category/cat1.html0000644000076500000240000001743712215535610023521 0ustar jmstaff00000000000000 Alexis' log - cat1 Fork me on GitHub

    Other articles


    Page 1 / 1

    pelican-3.3/pelican/tests/output/custom/category/misc.html0000644000076500000240000002210212216354256023613 0ustar jmstaff00000000000000 Alexis' log - misc Fork me on GitHub

    Other articles


    Page 1 / 1

    pelican-3.3/pelican/tests/output/custom/category/yeah.html0000644000076500000240000001266412215535610023614 0ustar jmstaff00000000000000 Alexis' log - yeah Fork me on GitHub
    pelican-3.3/pelican/tests/output/custom/drafts/0000755000076500000240000000000012220367225021436 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/drafts/a-draft-article.html0000644000076500000240000001131212215535610025260 0ustar jmstaff00000000000000 A draft article Fork me on GitHub
    pelican-3.3/pelican/tests/output/custom/feeds/0000755000076500000240000000000012220367225021241 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/feeds/all-en.atom.xml0000644000076500000240000004463412216354256024112 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/2012-11-30T00:00:00+01:00FILENAME_METADATA example2012-11-30T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-11-30:filename_metadata-example.html<p>Some cool stuff!</p> Second article2012-02-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-02-29:second-article.html<p>This is some article, in english</p> A markdown powered article2011-04-20T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-04-20:a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="http://blog.notmyidea.org/unbelievable.html">a root-relative link to unbelievable</a> <a href="http://blog.notmyidea.org/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-3.html<p>Article 3</p> This is a super article !2010-12-02T10:14:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-12-02:this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> Oh yeah !2010-10-20T10:14:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-20:oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> Unbelievable !2010-10-15T20:30:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-15:unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="http://blog.notmyidea.org/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <a class="reference external" href="http://blog.notmyidea.org/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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><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><p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> pelican-3.3/pelican/tests/output/custom/feeds/all-fr.atom.xml0000666000076500000240000000220312130377623024103 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/2012-03-02T14:01:01+01:00Trop bien !2012-03-02T14:01:01+01:00Alexis Métaireautag:blog.notmyidea.org,2012-03-02:oh-yeah-fr.html<p>Et voila du contenu en français</p> Deuxième article2012-02-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-02-29:second-article-fr.html<p>Ceci est un article, en français.</p> pelican-3.3/pelican/tests/output/custom/feeds/all.atom.xml0000644000076500000240000004631512216354256023510 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/2012-11-30T00:00:00+01:00FILENAME_METADATA example2012-11-30T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-11-30:filename_metadata-example.html<p>Some cool stuff!</p> Trop bien !2012-03-02T14:01:01+01:00Alexis Métaireautag:blog.notmyidea.org,2012-03-02:oh-yeah-fr.html<p>Et voila du contenu en français</p> Second article2012-02-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-02-29:second-article.html<p>This is some article, in english</p> Deuxième article2012-02-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-02-29:second-article-fr.html<p>Ceci est un article, en français.</p> A markdown powered article2011-04-20T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-04-20:a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="http://blog.notmyidea.org/unbelievable.html">a root-relative link to unbelievable</a> <a href="http://blog.notmyidea.org/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-3.html<p>Article 3</p> This is a super article !2010-12-02T10:14:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-12-02:this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> Oh yeah !2010-10-20T10:14:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-20:oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> Unbelievable !2010-10-15T20:30:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-15:unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="http://blog.notmyidea.org/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <a class="reference external" href="http://blog.notmyidea.org/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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><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><p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> pelican-3.3/pelican/tests/output/custom/feeds/all.rss.xml0000644000076500000240000004656012216354256023361 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/Fri, 30 Nov 2012 00:00:00 +0100FILENAME_METADATA examplehttp://blog.notmyidea.org/filename_metadata-example.html<p>Some cool stuff!</p> Alexis MétaireauFri, 30 Nov 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-11-30:filename_metadata-example.htmlTrop bien !http://blog.notmyidea.org/oh-yeah-fr.html<p>Et voila du contenu en français</p> Alexis MétaireauFri, 02 Mar 2012 14:01:01 +0100tag:blog.notmyidea.org,2012-03-02:oh-yeah-fr.htmlSecond articlehttp://blog.notmyidea.org/second-article.html<p>This is some article, in english</p> Alexis MétaireauWed, 29 Feb 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-02-29:second-article.htmlfoobarbazDeuxième articlehttp://blog.notmyidea.org/second-article-fr.html<p>Ceci est un article, en français.</p> Alexis MétaireauWed, 29 Feb 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-02-29:second-article-fr.htmlfoobarbazA markdown powered articlehttp://blog.notmyidea.org/a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="http://blog.notmyidea.org/unbelievable.html">a root-relative link to unbelievable</a> <a href="http://blog.notmyidea.org/unbelievable.html">a file-relative link to unbelievable</a></p>Alexis MétaireauWed, 20 Apr 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-04-20:a-markdown-powered-article.htmlArticle 1http://blog.notmyidea.org/article-1.html<p>Article 1</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:article-1.htmlArticle 2http://blog.notmyidea.org/article-2.html<p>Article 2</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:article-2.htmlArticle 3http://blog.notmyidea.org/article-3.html<p>Article 3</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:article-3.htmlThis is a super article !http://blog.notmyidea.org/this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> Alexis MétaireauThu, 02 Dec 2010 10:14:00 +0100tag:blog.notmyidea.org,2010-12-02:this-is-a-super-article.htmlfoobarfoobarOh yeah !http://blog.notmyidea.org/oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0200tag:blog.notmyidea.org,2010-10-20:oh-yeah.htmlohbaryeahUnbelievable !http://blog.notmyidea.org/unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="http://blog.notmyidea.org/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <a class="reference external" href="http://blog.notmyidea.org/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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><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><p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:unbelievable.htmlThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:tag/baz.htmlpelican-3.3/pelican/tests/output/custom/feeds/bar.atom.xml0000644000076500000240000000203712157356651023502 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/2010-10-20T10:14:00+02:00Oh yeah !2010-10-20T10:14:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-20:oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> pelican-3.3/pelican/tests/output/custom/feeds/bar.rss.xml0000644000076500000240000000207112157356651023347 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/Wed, 20 Oct 2010 10:14:00 +0200Oh yeah !http://blog.notmyidea.org/oh-yeah.html<div class="section" id="why-not"> <h2>Why not ?</h2> <p>After all, why not ? It's pretty simple to do it, and it will allow me to write my blogposts in rst ! YEAH !</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> </div> Alexis MétaireauWed, 20 Oct 2010 10:14:00 +0200tag:blog.notmyidea.org,2010-10-20:oh-yeah.htmlohbaryeahpelican-3.3/pelican/tests/output/custom/feeds/cat1.atom.xml0000666000076500000240000000361112130377623023562 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/2011-04-20T00:00:00+02:00A markdown powered article2011-04-20T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-04-20:a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="http://blog.notmyidea.org/unbelievable.html">a root-relative link to unbelievable</a> <a href="http://blog.notmyidea.org/unbelievable.html">a file-relative link to unbelievable</a></p>Article 12011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-1.html<p>Article 1</p> Article 22011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-2.html<p>Article 2</p> Article 32011-02-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-02-17:article-3.html<p>Article 3</p> pelican-3.3/pelican/tests/output/custom/feeds/cat1.rss.xml0000666000076500000240000000376412153236656023447 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/Wed, 20 Apr 2011 00:00:00 +0200A markdown powered articlehttp://blog.notmyidea.org/a-markdown-powered-article.html<p>You're mutually oblivious.</p> <p><a href="http://blog.notmyidea.org/unbelievable.html">a root-relative link to unbelievable</a> <a href="http://blog.notmyidea.org/unbelievable.html">a file-relative link to unbelievable</a></p>Alexis MétaireauWed, 20 Apr 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-04-20:a-markdown-powered-article.htmlArticle 1http://blog.notmyidea.org/article-1.html<p>Article 1</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:article-1.htmlArticle 2http://blog.notmyidea.org/article-2.html<p>Article 2</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:article-2.htmlArticle 3http://blog.notmyidea.org/article-3.html<p>Article 3</p> Alexis MétaireauThu, 17 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-17:article-3.htmlpelican-3.3/pelican/tests/output/custom/feeds/misc.atom.xml0000644000076500000240000003573512216354256023677 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/2012-11-30T00:00:00+01:00FILENAME_METADATA example2012-11-30T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-11-30:filename_metadata-example.html<p>Some cool stuff!</p> Second article2012-02-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-02-29:second-article.html<p>This is some article, in english</p> Unbelievable !2010-10-15T20:30:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-15:unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="http://blog.notmyidea.org/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <a class="reference external" href="http://blog.notmyidea.org/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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><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><p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> The baz tag2010-03-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-14:tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> pelican-3.3/pelican/tests/output/custom/feeds/misc.rss.xml0000644000076500000240000003606012216354256023536 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/Fri, 30 Nov 2012 00:00:00 +0100FILENAME_METADATA examplehttp://blog.notmyidea.org/filename_metadata-example.html<p>Some cool stuff!</p> Alexis MétaireauFri, 30 Nov 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-11-30:filename_metadata-example.htmlSecond articlehttp://blog.notmyidea.org/second-article.html<p>This is some article, in english</p> Alexis MétaireauWed, 29 Feb 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-02-29:second-article.htmlfoobarbazUnbelievable !http://blog.notmyidea.org/unbelievable.html<p>Or completely awesome. Depends the needs.</p> <p><a class="reference external" href="http://blog.notmyidea.org/a-markdown-powered-article.html">a root-relative link to markdown-article</a> <a class="reference external" href="http://blog.notmyidea.org/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 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"> <h2>Testing another case</h2> <p>This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.</p> <table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre>1</pre></div></td><td class="code"><div class="highlight"><pre><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><p>Lovely.</p> </div> <div class="section" id="testing-more-sourcecode-directives"> <h2>Testing more sourcecode directives</h2> <div class="highlight"><pre><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="testingc"># 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="testings">&#39;linenos&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingow">not</span> <span class="testingow">in</span> <span class="testingp">(</span><span class="testings">&#39;table&#39;</span><span class="testingp">,</span> <span class="testings">&#39;inline&#39;</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="testings">&#39;linenos&#39;</span><span class="testingp">]</span> <span class="testingo">=</span> <span class="testings">&#39;table&#39;</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="testings">&#39;nowrap&#39;</span><span class="testingp">,</span> <span class="testings">&#39;nobackground&#39;</span><span class="testingp">,</span> <span class="testings">&#39;anchorlinenos&#39;</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="testingbp">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="testingc"># 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="testingbp">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="testings">&#39;</span><span class="testingse">\n</span><span class="testings">&#39;</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="testings">&#39;&#39;</span><span class="testingp">,</span> <span class="testingn">parsed</span><span class="testingp">,</span> <span class="testingn">format</span><span class="testingo">=</span><span class="testings">&#39;html&#39;</span><span class="testingp">)]</span><br></span></pre></div> <p>Lovely.</p> </div> <div class="section" id="testing-even-more-sourcecode-directives"> <h2>Testing even more sourcecode directives</h2> <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> <p>Lovely.</p> </div> <div class="section" id="testing-overriding-config-defaults"> <h2>Testing overriding config defaults</h2> <p>Even if the default is line numbers, we can override it here</p> <div class="highlight"><pre><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> <p>Lovely.</p> </div> Alexis MétaireauFri, 15 Oct 2010 20:30:00 +0200tag:blog.notmyidea.org,2010-10-15:unbelievable.htmlThe baz taghttp://blog.notmyidea.org/tag/baz.html<p>This article overrides the listening of the articles under the <em>baz</em> tag.</p> Alexis MétaireauSun, 14 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-14:tag/baz.htmlpelican-3.3/pelican/tests/output/custom/feeds/yeah.atom.xml0000644000076500000240000000277312157356651023673 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/2010-12-02T10:14:00+01:00This is a super article !2010-12-02T10:14:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-12-02:this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> pelican-3.3/pelican/tests/output/custom/feeds/yeah.rss.xml0000644000076500000240000000302512157356651023531 0ustar jmstaff00000000000000 Alexis' loghttp://blog.notmyidea.org/Thu, 02 Dec 2010 10:14:00 +0100This is a super article !http://blog.notmyidea.org/this-is-a-super-article.html<p>Some content here !</p> <div class="section" id="this-is-a-simple-title"> <h2>This is a simple title</h2> <p>And here comes the cool <a class="reference external" href="http://books.couchdb.org/relax/design-documents/views">stuff</a>.</p> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi.jpg" style="width: 600px; height: 450px;" /> <img alt="alternate text" src="http://blog.notmyidea.org/pictures/Sushi_Macro.jpg" style="width: 600px; height: 450px;" /> <pre class="literal-block"> &gt;&gt;&gt; from ipdb import set_trace &gt;&gt;&gt; set_trace() </pre> <p>→ And now try with some utf8 hell: ééé</p> </div> Alexis MétaireauThu, 02 Dec 2010 10:14:00 +0100tag:blog.notmyidea.org,2010-12-02:this-is-a-super-article.htmlfoobarfoobarpelican-3.3/pelican/tests/output/custom/filename_metadata-example.html0000644000076500000240000001235112215535610026113 0ustar jmstaff00000000000000 FILENAME_METADATA example Fork me on GitHub

    FILENAME_METADATA example

    Some cool stuff!

    Comments !

    pelican-3.3/pelican/tests/output/custom/index.html0000644000076500000240000002011512215535610022146 0ustar jmstaff00000000000000 Alexis' log Fork me on GitHub

    Other articles


    Page 1 / 3 »

    pelican-3.3/pelican/tests/output/custom/index2.html0000644000076500000240000002067312215535610022241 0ustar jmstaff00000000000000 Alexis' log Fork me on GitHub

    « Page 2 / 3 »

    pelican-3.3/pelican/tests/output/custom/index3.html0000644000076500000240000001623112216354256022243 0ustar jmstaff00000000000000 Alexis' log Fork me on GitHub

    « Page 3 / 3

    pelican-3.3/pelican/tests/output/custom/jinja2_template.html0000644000076500000240000000760612215535610024121 0ustar jmstaff00000000000000 Alexis' log Fork me on GitHub Some text
    pelican-3.3/pelican/tests/output/custom/oh-yeah-fr.html0000644000076500000240000001232512215535610023002 0ustar jmstaff00000000000000 Trop bien ! Fork me on GitHub

    Trop bien !

    Et voila du contenu en français

    Comments !

    pelican-3.3/pelican/tests/output/custom/oh-yeah.html0000644000076500000240000001303412215535610022373 0ustar jmstaff00000000000000 Oh yeah ! Fork me on GitHub

    Oh yeah !

    Why not ?

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

    alternate text

    Comments !

    pelican-3.3/pelican/tests/output/custom/override/0000755000076500000240000000000012220367225021772 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/override/index.html0000644000076500000240000001016512215535610023771 0ustar jmstaff00000000000000 Override url/save_as Fork me on GitHub

    Override url/save_as

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

    pelican-3.3/pelican/tests/output/custom/pages/0000755000076500000240000000000012220367225021252 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/pages/this-is-a-test-hidden-page.html0000644000076500000240000001016712215535610027062 0ustar jmstaff00000000000000 This is a test hidden page Fork me on GitHub

    This is a test hidden page

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

    pelican-3.3/pelican/tests/output/custom/pages/this-is-a-test-page.html0000644000076500000240000001017612215535610025631 0ustar jmstaff00000000000000 This is a test page Fork me on GitHub

    This is a test page

    Just an image.

    alternate text
    pelican-3.3/pelican/tests/output/custom/second-article-fr.html0000644000076500000240000001256512215535610024352 0ustar jmstaff00000000000000 Deuxième article Fork me on GitHub

    Deuxième article

    Ceci est un article, en français.

    Comments !

    pelican-3.3/pelican/tests/output/custom/second-article.html0000644000076500000240000001254412215535610023742 0ustar jmstaff00000000000000 Second article Fork me on GitHub

    Second article

    This is some article, in english

    Comments !

    pelican-3.3/pelican/tests/output/custom/tag/0000755000076500000240000000000012220367225020726 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/tag/bar.html0000644000076500000240000001706312215535610022366 0ustar jmstaff00000000000000 Alexis' log - bar Fork me on GitHub

    Other articles


    Page 1 / 1

    pelican-3.3/pelican/tests/output/custom/tag/baz.html0000644000076500000240000001232312215535610022370 0ustar jmstaff00000000000000 The baz tag Fork me on GitHub

    The baz tag

    This article overrides the listening of the articles under the baz tag.

    Comments !

    pelican-3.3/pelican/tests/output/custom/tag/foo.html0000644000076500000240000001437512215535610022410 0ustar jmstaff00000000000000 Alexis' log - foo Fork me on GitHub

    Other articles


    Page 1 / 1

    pelican-3.3/pelican/tests/output/custom/tag/foobar.html0000644000076500000240000001264712215535610023075 0ustar jmstaff00000000000000 Alexis' log - foobar Fork me on GitHub
    pelican-3.3/pelican/tests/output/custom/tag/oh.html0000644000076500000240000001010612215535610022217 0ustar jmstaff00000000000000 Oh Oh Oh Fork me on GitHub

    Oh Oh Oh

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

    pelican-3.3/pelican/tests/output/custom/tag/yeah.html0000644000076500000240000001214312215535610022542 0ustar jmstaff00000000000000 Alexis' log - yeah Fork me on GitHub
    pelican-3.3/pelican/tests/output/custom/tags.html0000644000076500000240000001043512215535610022001 0ustar jmstaff00000000000000 Alexis' log - Tags Fork me on GitHub

    Tags for Alexis' log

  • bar (3)
  • baz (1)
  • foo (2)
  • foobar (1)
  • oh (1)
  • yeah (1)
  • pelican-3.3/pelican/tests/output/custom/theme/0000755000076500000240000000000012220367225021255 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/theme/css/0000755000076500000240000000000012220367225022045 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/theme/css/main.css0000666000076500000240000002531012171064114023504 0ustar jmstaff00000000000000/* Name: Smashing HTML5 Date: July 2009 Description: Sample layout for HTML5 and CSS3 goodness. Version: 1.0 License: MIT Licensed by: Smashing Media GmbH Original author: Enrique Ramírez */ /* Imports */ @import url("reset.css"); @import url("pygment.css"); @import url("typogrify.css"); @import url(//fonts.googleapis.com/css?family=Yanone+Kaffeesatz&subset=latin); /***** Global *****/ /* Body */ body { background: #F5F4EF; color: #000305; font-size: 87.5%; /* Base font size: 14px */ font-family: 'Trebuchet MS', Trebuchet, 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; line-height: 1.429; margin: 0; padding: 0; text-align: left; } /* Headings */ h1 {font-size: 2em } h2 {font-size: 1.571em} /* 22px */ h3 {font-size: 1.429em} /* 20px */ h4 {font-size: 1.286em} /* 18px */ h5 {font-size: 1.143em} /* 16px */ h6 {font-size: 1em} /* 14px */ h1, h2, h3, h4, h5, h6 { font-weight: 400; line-height: 1.1; margin-bottom: .8em; font-family: 'Yanone Kaffeesatz', arial, serif; } h3, h4, h5, h6 { margin-top: .8em; } hr { border: 2px solid #EEEEEE; } /* Anchors */ a {outline: 0;} a img {border: 0px; text-decoration: none;} a:link, a:visited { color: #C74350; padding: 0 1px; text-decoration: underline; } a:hover, a:active { background-color: #C74350; color: #fff; text-decoration: none; text-shadow: 1px 1px 1px #333; } h1 a:hover { background-color: inherit } /* Paragraphs */ div.line-block, p { margin-top: 1em; margin-bottom: 1em;} strong, b {font-weight: bold;} em, i {font-style: italic;} /* Lists */ ul { list-style: outside disc; margin: 0em 0 0 1.5em; } ol { list-style: outside decimal; margin: 0em 0 0 1.5em; } li { margin-top: 0.5em;} .post-info { float:right; margin:10px; padding:5px; } .post-info p{ margin-top: 1px; margin-bottom: 1px; } .readmore { float: right } dl {margin: 0 0 1.5em 0;} dt {font-weight: bold;} dd {margin-left: 1.5em;} pre{background-color: rgb(238, 238, 238); padding: 10px; margin: 10px; overflow: auto;} /* Quotes */ blockquote { margin: 20px; font-style: italic; } cite {} q {} div.note { float: right; margin: 5px; font-size: 85%; max-width: 300px; } /* Tables */ table {margin: .5em auto 1.5em auto; width: 98%;} /* Thead */ thead th {padding: .5em .4em; text-align: left;} thead td {} /* Tbody */ tbody td {padding: .5em .4em;} tbody th {} tbody .alt td {} tbody .alt th {} /* Tfoot */ tfoot th {} tfoot td {} /* HTML5 tags */ header, section, footer, aside, nav, article, figure { display: block; } /***** Layout *****/ .body {clear: both; margin: 0 auto; width: 800px;} img.right, figure.right {float: right; margin: 0 0 2em 2em;} img.left, figure.left {float: left; margin: 0 2em 2em 0;} /* Header *****************/ #banner { margin: 0 auto; padding: 2.5em 0 0 0; } /* Banner */ #banner h1 {font-size: 3.571em; line-height: 0;} #banner h1 a:link, #banner h1 a:visited { color: #000305; display: block; font-weight: bold; margin: 0 0 .6em .2em; text-decoration: none; } #banner h1 a:hover, #banner h1 a:active { background: none; color: #C74350; text-shadow: none; } #banner h1 strong {font-size: 0.36em; font-weight: normal;} /* Main Nav */ #banner nav { background: #000305; font-size: 1.143em; height: 40px; line-height: 30px; margin: 0 auto 2em auto; padding: 0; text-align: center; width: 800px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #banner nav ul {list-style: none; margin: 0 auto; width: 800px;} #banner nav li {float: left; display: inline; margin: 0;} #banner nav a:link, #banner nav a:visited { color: #fff; display: inline-block; height: 30px; padding: 5px 1.5em; text-decoration: none; } #banner nav a:hover, #banner nav a:active, #banner nav .active a:link, #banner nav .active a:visited { background: #C74451; color: #fff; text-shadow: none !important; } #banner nav li:first-child a { border-top-left-radius: 5px; -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; } /* Featured *****************/ #featured { background: #fff; margin-bottom: 2em; overflow: hidden; padding: 20px; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #featured figure { border: 2px solid #eee; float: right; margin: 0.786em 2em 0 5em; width: 248px; } #featured figure img {display: block; float: right;} #featured h2 {color: #C74451; font-size: 1.714em; margin-bottom: 0.333em;} #featured h3 {font-size: 1.429em; margin-bottom: .5em;} #featured h3 a:link, #featured h3 a:visited {color: #000305; text-decoration: none;} #featured h3 a:hover, #featured h3 a:active {color: #fff;} /* Body *****************/ #content { background: #fff; margin-bottom: 2em; overflow: hidden; padding: 20px 20px; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } /* Extras *****************/ #extras {margin: 0 auto 3em auto; overflow: hidden;} #extras ul {list-style: none; margin: 0;} #extras li {border-bottom: 1px solid #fff;} #extras h2 { color: #C74350; font-size: 1.429em; margin-bottom: .25em; padding: 0 3px; } #extras a:link, #extras a:visited { color: #444; display: block; border-bottom: 1px solid #F4E3E3; text-decoration: none; padding: .3em .25em; } #extras a:hover, #extras a:active {color: #fff;} /* Blogroll */ #extras .blogroll { float: left; width: 615px; } #extras .blogroll li {float: left; margin: 0 20px 0 0; width: 185px;} /* Social */ #extras .social { float: right; width: 175px; } #extras div[class='social'] a { background-repeat: no-repeat; background-position: 3px 6px; padding-left: 25px; } /* Icons */ .social a[href*='about.me'] {background-image: url('../images/icons/aboutme.png');} .social a[href*='bitbucket.org'] {background-image: url('../images/icons/bitbucket.png');} .social a[href*='delicious.com'] {background-image: url('../images/icons/delicious.png');} .social a[href*='digg.com'] {background-image: url('../images/icons/digg.png');} .social a[href*='facebook.com'] {background-image: url('../images/icons/facebook.png');} .social a[href*='gitorious.org'] {background-image: url('../images/icons/gitorious.png');} .social a[href*='github.com'], .social a[href*='git.io'] {background-image: url('../images/icons/github.png');} .social a[href*='gittip.com'] {background-image: url('../images/icons/gittip.png');} .social a[href*='plus.google.com'] {background-image: url('../images/icons/google-plus.png');} .social a[href*='groups.google.com'] {background-image: url('../images/icons/google-groups.png');} .social a[href*='news.ycombinator.com'], .social a[href*='hackernewsers.com'] {background-image: url('../images/icons/hackernews.png');} .social a[href*='last.fm'], .social a[href*='lastfm.'] {background-image: url('../images/icons/lastfm.png');} .social a[href*='linkedin.com'] {background-image: url('../images/icons/linkedin.png');} .social a[href*='reddit.com'] {background-image: url('../images/icons/reddit.png');} .social a[type$='atom+xml'], .social a[type$='rss+xml'] {background-image: url('../images/icons/rss.png');} .social a[href*='slideshare.net'] {background-image: url('../images/icons/slideshare.png');} .social a[href*='speakerdeck.com'] {background-image: url('../images/icons/speakerdeck.png');} .social a[href*='stackoverflow.com'] {background-image: url('../images/icons/stackoverflow.png');} .social a[href*='twitter.com'] {background-image: url('../images/icons/twitter.png');} .social a[href*='vimeo.com'] {background-image: url('../images/icons/vimeo.png');} .social a[href*='youtube.com'] {background-image: url('../images/icons/youtube.png');} /* About *****************/ #about { background: #fff; font-style: normal; margin-bottom: 2em; overflow: hidden; padding: 20px; text-align: left; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #about .primary {float: left; width: 165px;} #about .primary strong {color: #C64350; display: block; font-size: 1.286em;} #about .photo {float: left; margin: 5px 20px;} #about .url:link, #about .url:visited {text-decoration: none;} #about .bio {float: right; width: 500px;} /* Footer *****************/ #contentinfo {padding-bottom: 2em; text-align: right;} /***** Sections *****/ /* Blog */ .hentry { display: block; clear: both; border-bottom: 1px solid #eee; padding: 1.5em 0; } li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} #content > .hentry {padding: 1em 0;} .hentry img{display : none ;} .entry-title {font-size: 3em; margin-bottom: 10px; margin-top: 0;} .entry-title a:link, .entry-title a:visited {text-decoration: none; color: #333;} .entry-title a:visited {background-color: #fff;} .hentry .post-info * {font-style: normal;} /* Content */ .hentry footer {margin-bottom: 2em;} .hentry footer address {display: inline;} #posts-list footer address {display: block;} /* Blog Index */ #posts-list {list-style: none; margin: 0;} #posts-list .hentry {padding-left: 10px; position: relative;} #posts-list footer { left: 10px; position: relative; float: left; top: 0.5em; width: 190px; } /* About the Author */ #about-author { background: #f9f9f9; clear: both; font-style: normal; margin: 2em 0; padding: 10px 20px 15px 20px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #about-author strong { color: #C64350; clear: both; display: block; font-size: 1.429em; } #about-author .photo {border: 1px solid #ddd; float: left; margin: 5px 1em 0 0;} /* Comments */ #comments-list {list-style: none; margin: 0 1em;} #comments-list blockquote { background: #f8f8f8; clear: both; font-style: normal; margin: 0; padding: 15px 20px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #comments-list footer {color: #888; padding: .5em 1em 0 0; text-align: right;} #comments-list li:nth-child(2n) blockquote {background: #F5f5f5;} /* Add a Comment */ #add-comment label {clear: left; float: left; text-align: left; width: 150px;} #add-comment input[type='text'], #add-comment input[type='email'], #add-comment input[type='url'] {float: left; width: 200px;} #add-comment textarea {float: left; height: 150px; width: 495px;} #add-comment p.req {clear: both; margin: 0 .5em 1em 0; text-align: right;} #add-comment input[type='submit'] {float: right; margin: 0 .5em;} #add-comment * {margin-bottom: .5em;} pelican-3.3/pelican/tests/output/custom/theme/css/pygment.css0000666000076500000240000000345212130377623024255 0ustar jmstaff00000000000000.hll { background-color:#eee; } .c { color:#408090; font-style:italic; } .err { border:1px solid #FF0000; } .k { color:#007020; font-weight:bold; } .o { color:#666666; } .cm { color:#408090; font-style:italic; } .cp { color:#007020; } .c1 { color:#408090; font-style:italic; } .cs { background-color:#FFF0F0; color:#408090; } .gd { color:#A00000; } .ge { font-style:italic; } .gr { color:#FF0000; } .gh { color:#000080; font-weight:bold; } .gi { color:#00A000; } .go { color:#303030; } .gp { color:#C65D09; font-weight:bold; } .gs { font-weight:bold; } .gu { color:#800080; font-weight:bold; } .gt { color:#0040D0; } .kc { color:#007020; font-weight:bold; } .kd { color:#007020; font-weight:bold; } .kn { color:#007020; font-weight:bold; } .kp { color:#007020; } .kr { color:#007020; font-weight:bold; } .kt { color:#902000; } .m { color:#208050; } .s { color:#4070A0; } .na { color:#4070A0; } .nb { color:#007020; } .nc { color:#0E84B5; font-weight:bold; } .no { color:#60ADD5; } .nd { color:#555555; font-weight:bold; } .ni { color:#D55537; font-weight:bold; } .ne { color:#007020; } .nf { color:#06287E; } .nl { color:#002070; font-weight:bold; } .nn { color:#0E84B5; font-weight:bold; } .nt { color:#062873; font-weight:bold; } .nv { color:#BB60D5; } .ow { color:#007020; font-weight:bold; } .w { color:#BBBBBB; } .mf { color:#208050; } .mh { color:#208050; } .mi { color:#208050; } .mo { color:#208050; } .sb { color:#4070A0; } .sc { color:#4070A0; } .sd { color:#4070A0; font-style:italic; } .s2 { color:#4070A0; } .se { color:#4070A0; font-weight:bold; } .sh { color:#4070A0; } .si { color:#70A0D0; font-style:italic; } .sx { color:#C65D09; } .sr { color:#235388; } .s1 { color:#4070A0; } .ss { color:#517918; } .bp { color:#007020; } .vc { color:#BB60D5; } .vg { color:#BB60D5; } .vi { color:#BB60D5; } .il { color:#208050; } pelican-3.3/pelican/tests/output/custom/theme/css/reset.css0000666000076500000240000000211712130377623023711 0ustar jmstaff00000000000000/* Name: Reset Stylesheet Description: Resets browser's default CSS Author: Eric Meyer Author URI: http://meyerweb.com/eric/tools/css/reset/ */ /* v1.0 | 20080212 */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { background: transparent; border: 0; font-size: 100%; margin: 0; outline: 0; padding: 0; vertical-align: baseline; } body {line-height: 1;} ol, ul {list-style: none;} blockquote, q {quotes: none;} blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } /* remember to define focus styles! */ :focus { outline: 0; } /* remember to highlight inserts somehow! */ ins {text-decoration: none;} del {text-decoration: line-through;} /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: collapse; border-spacing: 0; }pelican-3.3/pelican/tests/output/custom/theme/css/typogrify.css0000666000076500000240000000027612130377623024627 0ustar jmstaff00000000000000.caps {font-size:.92em;} .amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;} .dquo {margin-left:-.38em;} pelican-3.3/pelican/tests/output/custom/theme/css/wide.css0000666000076500000240000000115012130377623023513 0ustar jmstaff00000000000000@import url("main.css"); body { font:1.3em/1.3 "Hoefler Text","Georgia",Georgia,serif,sans-serif; } .post-info{ display: none; } #banner nav { display: none; -moz-border-radius: 0px; margin-bottom: 20px; overflow: hidden; font-size: 1em; background: #F5F4EF; } #banner nav ul{ padding-right: 50px; } #banner nav li{ float: right; color: #000; } #banner nav li a { color: #000; } #banner h1 { margin-bottom: -18px; } #featured, #extras { padding: 50px; } #featured { padding-top: 20px; } #extras { padding-top: 0px; padding-bottom: 0px; } pelican-3.3/pelican/tests/output/custom/theme/images/0000755000076500000240000000000012220367225022522 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/theme/images/icons/0000755000076500000240000000000012220367225023635 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/output/custom/theme/images/icons/aboutme.png0000666000076500000240000000135712132103620025776 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ< PLTE >b :\a``__^][XNz 8Y]\\ZZXVS Js Ch 6UXXWVUTRQ~N{ Lw El @d4S P} O| Nz Mx Lw Ku Js Hq Fn Ek @e >a2O Mw3 Ip Dj Bg >a <]0L Hp Ho Gn Bg Cg;]9Y ;[.I Dk :ZAf 7U=_0K,F@e(>=_%:6U"4*D2O'@/K &=-G#:*D!7(@4%=1k/tRNS@f pHYsHHFk>IDATURPEcJP t(P)RcB]7p $YpܪHWUU?9'g^DXz&[|y6:dd#'r7_4L˚7L?`ZW|;h%tEXtdate:create2013-03-15T18:16:20-07:00#6%tEXtdate:modify2013-03-15T18:16:16-07:00SIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/bitbucket.png0000666000076500000240000000720212132103620026311 0ustar jmstaff00000000000000PNG  IHDRh6 AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ pHYs  niTXtXML:com.adobe.xmp ? AmIDAT(ERkAtIݐۤ?jִPЖRD {$xP"1FlҺ>t GTЂ}FD%BdD,>[ēPR@+*ȌFՍJpL +x~,*p*K$ћBJ{iqne6;Ĉv}vpn`k KӲW7ͅ'tՅ |ZWotL,(w,}+WҩP8d״ˍJsP\ C$IAk筕sGt*JB\׆\08Sֿ#/9bSs\&_t@z8vIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/delicious.png0000666000076500000240000000167612132103620026326 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zcIDAT8ou}Kn6IKb*K D(B1/ 1Ll,t@JtCDڦIIS׉o{}yX,Vq#jKZxwv~}z;mgӃ`ڮfOk̙{~5޻~~n4i3/}{׃g½cW=>֚./}p B:m&tkJFLi_ ?ԓIrR "&bi?3$bZ)Hէڲ @8L !:(NDm2yqrK)I%dCesG J) ?ϧJ>2pF> 6`CAsJﳽG7qG52/}Cca@\Ş.M[9rʲ W*YR=*;{"""H$""_}47u6wD*x~8Q3̱P!L4֖j$FH|q  ƾJg0.q!`x@0^5"1"`E^'81ZB`0Kׯh'a.W Ox^8G,b89.~/T+^`c`j )efЩ2},W${{b1}x'mmnko}w㰻u`}?=}yf;wZ?W.72 䭘fIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/facebook.png0000666000076500000240000000031212132103620026101 0ustar jmstaff00000000000000PNG  IHDRRPLTE;Y;Y`xEbmgtRNSACbKGDH pHYsHHFk>=IDATc`F%0``0 e C%P RBeBT\Cp0K 0ef>IENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/github.png0000666000076500000240000000053212132103620025616 0ustar jmstaff00000000000000PNG  IHDRa pHYs  ~ IDAT8˕ӱJa VVB*A>m [[_*  MTl&.Og!hhr7"nq\r &0E,]3m+xLQ>嶝9y`C_ N]kEN!7 g-.@iF6XN_0J > 2#z okm|<˲U,,pt*+X4NO7m9KIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/gitorious.png0000666000076500000240000000034312132103620026360 0ustar jmstaff00000000000000PNG  IHDR(-SLbIDAT}1 % h#"#M 홴z)} .?_"{B4!>}HVU8T% )mu CbD, F IIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/gittip.png0000666000076500000240000000074712132103620025644 0ustar jmstaff00000000000000PNG  IHDRasRGBbKGD pHYs  tIME  mgIDAT8c`o0cm=H_P| *0CF`1d=6_LԄj.d*LsHg#MM@v7S!0lÕs' m`=-oqEv 4plٰl$.4g4ܴb)f ā@,`.&@yjB P q7!UA?~p11?FhhDd"EDm j4'$MOH(I%^V8ǟ)LfgoǑXIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/google-groups.png0000666000076500000240000000144312132103620027127 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<5PLTE,r#bFEB@>=:875}3{1zDB@<7~4|CA>=986~?>6~4|2{1x>2z0x=98;9/w1y0w2{.v3|.uʡ-ṭ,s+qtRNS}abKGD-IDAT5y[QW-q̄13p}(B/繞j;.{`(E( )-O$9dAL#B /$Jryu]Bpp2OiR.;7EBpNb>cã}%bP}fC}(,ggxE)_Oz70Yn`-:9@ 3$%ts%tEXtdate:create2013-01-13T02:11:01-08:00̕%tEXtdate:modify2013-01-13T02:10:36-08:00&zIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/google-plus.png0000666000076500000240000000101712132103620026570 0ustar jmstaff00000000000000PNG  IHDRh6IDAT(cmIbeq&nt9@ A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ pHYs  niTXtXML:com.adobe.xmp ? AIDAT8cD^V4?PAuLU?7g0arp m3Fpu06L.d s`]8bw3lfd ьP#<= Is aLd6\<(A_&#Ft6ab/$eqoIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/lastfm.png0000666000076500000240000000171712132103620025630 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zc(IDAT8OlU{v6*U(D Qc@#'ăO=sp1 ϩD--4Pv{??=~.KxNyfƤTH'*"1֮Br:i$k.>7HXy?؁s(I HrwL.Ig~ Ig9R  (%c5y@F6CH,D ? N6(!cQ6{dPȡpsJ0j0e$pNU.x " 8zZ^5˫3uh`{#at0:Nh`/F1%쑔}#l̮qo2^'#rxqS'ɽshb@c;2I~7;{U,J,yoɾq[ bYBE2'y:fIMw.);#,8vmJK"",7%KRd'""6Q,yJ泓'w>׍j﯒ܹ.P.3_XDz]e?n g_)G_{!bGժԡhvdKAg^䋅kwЕ!dOCPY.cЉ#[{AbXM~bѻD\k-3rUe<$7V%-e?O=k;ʆQFxD0UmTgjzϯ|psO?ϕsݪCIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/linkedin.png0000666000076500000240000000160012132103620026126 0ustar jmstaff00000000000000PNG  IHDR(-S7PLTEhiklklmmoommnnoonopqoqprrpqstsutv vw w v w y yx y yy { {zzzz{|{|~ !"#$%&',-21223E9:9::<=~^|^X۳~#rӯ#"{:(#u;p )*R)j NA^AT kk1HgO\(vo84QImÏY`e)S IENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/reddit.png0000666000076500000240000000126512132103620025613 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<PLTER[eeq}bjsdeg|_ju_lz`][JNSiup|VZ^ߍy)/6w]dknyo~djm{[aflpv><:w{qpoGGG20nprS\eɨFJNˁ~~~U^gjklգxgscmx6 pHYsHHFk>IDATePﵻ;X("6蠎s!/^`4-V-r{>]44"O$S > b\8!Vo4[xj65Bڝ.z6!0'c`4ԢS|j|,sMō6spy /R1$ DBTr\ߤ0^|xfNܸ !bT S<~C# %g;$/)QEuM"I`^~.:%n課~| wV :&15R§w 3OPvmd)$ỵ_%YBڶȦ3_JndW|Ui#5Lf:JS8d$7ԈPwɸ^?3u}ȜmEfS쮉 A*bk;K/T1UcDjVz_3:T80}wNpJɠAke,}:{m;?[/4E5[񮺱馕ny'}^8+` x<IENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/slideshare.png0000666000076500000240000000102712132103620026457 0ustar jmstaff00000000000000PNG  IHDR(-SPLTEâz既d{o˦K>dHk;}unw;97o&wE4fpA,]_z|r]+,$zqfmaHtRNS-)IDATNP^oea01Hc\iGL89qM,n$$LzROQ ]vgchKl#u_וb?oQܔ! . k;GW/ JD44!9ԛIENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/speakerdeck.png0000666000076500000240000000203112132103620026611 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<PLTE9,2tU7]6~\6\7]3uU.qSF~G/qS.vW(qS(pS#kO"jNeKdK_I`I[GXFXETDQCOAMAM@K@I?H?I@A;`VaVB;$!F@F@E??|>{>{@|?{?|;x7u6u6u6t7v;y6u4s3r3q3r4s2r/o0p0q1q,m,l*i*h*g)g)g)f+j,m)j'f\FP>O<VCYGUCN<\F(g%g#bM<K3A7Dd]@d\Ed^A8 =2G:|bv_r\^MXHXHUEUFVGVF_Ns]o\n[p\o\o[n[hXgXgWgXfWfWhYbVaU`T `TcV^U ]U ]T ]S \SǶ(tRNS{{m pHYsHHFk> IDATc``dbfaef&6v M-m]-mN.n=}}C}C#c}nS333s KKKs+3+S^>k[ "[{~G'gWW77wgOA!/o_? /aаȨظ$Դ̬d1¢⒒ҲJqںƦ*Iֶ֎ֶήVi }d&MIDATHT;H+A3;dU (AĀ [(#l"Z GVjaF% PPD$dd;!Oŧ»a̜{a|exc)]^ Cnw4LrtW ݛ&ơ_(r:_6ndkcTRgR@@ W>Ez8>8;0Gi!D)c oԌ󳢌vu qÍeGi|ee.'F_ `l!XE|v TՍ BfgE㹻BHr9!R}Aq==E"T[kO` cR)t] Tt]Υ[JK eYL@J)憳WW$oo׽ssD6{yrUUe##V+!>5c`LmߗM`?ZZLbRJ(eLI4fRBU֦iU.! d2vN3qGg;;!!Ðee]7 !qE'`0dw$ jQ盛 hכl ''PO5(6V\Q(u>~ [e(~@~;IɅT%tEXtdate:create2013-07-03T22:30:09-07:001D%tEXtdate:modify2013-07-01T14:56:54-07:00IENDB`pelican-3.3/pelican/tests/output/custom/theme/images/icons/twitter.png0000666000076500000240000000147612132103620026046 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zcIDAT8Kk]U߻D :;8ळE*"A/ M/i^2n$J) Qe This is a super article ! Fork me on GitHub

    This is a super article !

    Some content here !

    This is a simple title

    And here comes the cool stuff.

    alternate text alternate text
    >>> from ipdb import set_trace
    >>> set_trace()
    

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

    Comments !

    pelican-3.3/pelican/tests/output/custom/unbelievable.html0000644000076500000240000003511012216354256023503 0ustar jmstaff00000000000000 Unbelievable ! Fork me on GitHub

    Unbelievable !

    Or completely awesome. Depends the needs.

    a root-relative link to markdown-article a file-relative link to markdown-article

    Testing sourcecode directive

    1
    formatter = self.options and VARIANTS[self.options.keys()[0]]
    

    Testing another case

    This will now have a line number in 'custom' since it's the default in pelican.conf, it will have nothing in default.

    1
    formatter = self.options and VARIANTS[self.options.keys()[0]]
    

    Lovely.

    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')]

    Lovely.

    Testing even more sourcecode directives

    formatter = self.options and VARIANTS[self.options.keys()[0]]

    Lovely.

    Testing overriding config defaults

    Even if the default is line numbers, we can override it here

    formatter = self.options and VARIANTS[self.options.keys()[0]]
    

    Lovely.

    Comments !

    pelican-3.3/pelican/tests/support.py0000666000076500000240000001272012153236656017405 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function __all__ = ['get_article', 'unittest', ] import os import re import subprocess import sys from six import StringIO import logging from logging.handlers import BufferingHandler import unittest import locale from functools import wraps from contextlib import contextmanager from tempfile import mkdtemp from shutil import rmtree from pelican.contents import Article from pelican.settings import DEFAULT_CONFIG @contextmanager def temporary_folder(): """creates a temporary folder, return it and delete it afterwards. This allows to do something like this in tests: >>> with temporary_folder() as d: # do whatever you want """ tempdir = mkdtemp() try: yield tempdir finally: rmtree(tempdir) def isplit(s, sep=None): """Behaves like str.split but returns a generator instead of a list. >>> list(isplit('\tUse the force\n')) == '\tUse the force\n'.split() True >>> list(isplit('\tUse the force\n')) == ['Use', 'the', 'force'] True >>> (list(isplit('\tUse the force\n', "e")) == '\tUse the force\n'.split("e")) True >>> list(isplit('Use the force', "e")) == 'Use the force'.split("e") True >>> list(isplit('Use the force', "e")) == ['Us', ' th', ' forc', ''] True """ sep, hardsep = r'\s+' if sep is None else re.escape(sep), sep is not None exp, pos, l = re.compile(sep), 0, len(s) while True: m = exp.search(s, pos) if not m: if pos < l or hardsep: # ^ mimic "split()": ''.split() returns [] yield s[pos:] break start = m.start() if pos < start or hardsep: # ^ mimic "split()": includes trailing empty string yield s[pos:start] pos = m.end() def mute(returns_output=False): """Decorate a function that prints to stdout, intercepting the output. If "returns_output" is True, the function will return a generator yielding the printed lines instead of the return values. The decorator litterally hijack sys.stdout during each function execution, so be careful with what you apply it to. >>> def numbers(): print "42" print "1984" ... >>> numbers() 42 1984 >>> mute()(numbers)() >>> list(mute(True)(numbers)()) ['42', '1984'] """ def decorator(func): @wraps(func) def wrapper(*args, **kwargs): saved_stdout = sys.stdout sys.stdout = StringIO() try: out = func(*args, **kwargs) if returns_output: out = isplit(sys.stdout.getvalue().strip()) finally: sys.stdout = saved_stdout return out return wrapper return decorator def get_article(title, slug, content, lang, extra_metadata=None): metadata = {'slug': slug, 'title': title, 'lang': lang} if extra_metadata is not None: metadata.update(extra_metadata) return Article(content, metadata=metadata) def skipIfNoExecutable(executable): """Skip test if `executable` is not found Tries to run `executable` with subprocess to make sure it's in the path, and skips the tests if not found (if subprocess raises a `OSError`). """ with open(os.devnull, 'w') as fnull: try: res = subprocess.call(executable, stdout=fnull, stderr=fnull) except OSError: res = None if res is None: return unittest.skip('{0} executable not found'.format(executable)) return lambda func: func def module_exists(module_name): """Test if a module is importable.""" try: __import__(module_name) except ImportError: return False else: return True def locale_available(locale_): old_locale = locale.setlocale(locale.LC_TIME) try: locale.setlocale(locale.LC_TIME, str(locale_)) except locale.Error: return False else: locale.setlocale(locale.LC_TIME, old_locale) return True def get_settings(**kwargs): """Provide tweaked setting dictionaries for testing Set keyword arguments to override specific settings. """ settings = DEFAULT_CONFIG.copy() for key,value in kwargs.items(): settings[key] = value return settings class LogCountHandler(BufferingHandler): """Capturing and counting logged messages.""" def __init__(self, capacity=1000): logging.handlers.BufferingHandler.__init__(self, capacity) def count_logs(self, msg=None, level=None): return len([l for l in self.buffer if (msg is None or re.match(msg, l.getMessage())) and (level is None or l.levelno == level) ]) class LoggedTestCase(unittest.TestCase): """A test case that captures log messages.""" def setUp(self): super(LoggedTestCase, self).setUp() self._logcount_handler = LogCountHandler() logging.getLogger().addHandler(self._logcount_handler) def tearDown(self): logging.getLogger().removeHandler(self._logcount_handler) super(LoggedTestCase, self).tearDown() def assertLogCountEqual(self, count=None, msg=None, **kwargs): actual = self._logcount_handler.count_logs(msg=msg, **kwargs) self.assertEqual( actual, count, msg='expected {} occurrences of {!r}, but found {}'.format( count, msg, actual)) pelican-3.3/pelican/tests/test_contents.py0000644000076500000240000002410012207763674020561 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals from datetime import datetime from sys import platform from .support import unittest, get_settings from pelican.contents import Page, Article, URLWrapper from pelican.settings import DEFAULT_CONFIG from pelican.utils import truncate_html_words from pelican.signals import content_object_init from jinja2.utils import generate_lorem_ipsum # generate one paragraph, enclosed with

    TEST_CONTENT = str(generate_lorem_ipsum(n=1)) TEST_SUMMARY = generate_lorem_ipsum(n=1, html=False) class TestPage(unittest.TestCase): def setUp(self): super(TestPage, self).setUp() self.page_kwargs = { 'content': TEST_CONTENT, 'context': { 'localsiteurl': '', }, 'metadata': { 'summary': TEST_SUMMARY, 'title': 'foo bar', 'author': 'Blogger', }, } def test_use_args(self): # Creating a page with arguments passed to the constructor should use # them to initialise object's attributes. metadata = {'foo': 'bar', 'foobar': 'baz', 'title': 'foobar', } page = Page(TEST_CONTENT, metadata=metadata, context={'localsiteurl': ''}) for key, value in metadata.items(): self.assertTrue(hasattr(page, key)) self.assertEqual(value, getattr(page, key)) self.assertEqual(page.content, TEST_CONTENT) def test_mandatory_properties(self): # If the title is not set, must throw an exception. page = Page('content') with self.assertRaises(NameError): page.check_properties() page = Page('content', metadata={'title': 'foobar'}) page.check_properties() def test_summary_from_metadata(self): # If a :summary: metadata is given, it should be used page = Page(**self.page_kwargs) self.assertEqual(page.summary, TEST_SUMMARY) def test_summary_max_length(self): # If a :SUMMARY_MAX_LENGTH: is set, and there is no other summary, # generated summary should not exceed the given length. page_kwargs = self._copy_page_kwargs() settings = get_settings() page_kwargs['settings'] = settings del page_kwargs['metadata']['summary'] settings['SUMMARY_MAX_LENGTH'] = None page = Page(**page_kwargs) self.assertEqual(page.summary, TEST_CONTENT) settings['SUMMARY_MAX_LENGTH'] = 10 page = Page(**page_kwargs) self.assertEqual(page.summary, truncate_html_words(TEST_CONTENT, 10)) settings['SUMMARY_MAX_LENGTH'] = 0 page = Page(**page_kwargs) self.assertEqual(page.summary, '') def test_slug(self): # If a title is given, it should be used to generate the slug. page = Page(**self.page_kwargs) self.assertEqual(page.slug, 'foo-bar') def test_defaultlang(self): # If no lang is given, default to the default one. page = Page(**self.page_kwargs) self.assertEqual(page.lang, DEFAULT_CONFIG['DEFAULT_LANG']) # it is possible to specify the lang in the metadata infos self.page_kwargs['metadata'].update({'lang': 'fr', }) page = Page(**self.page_kwargs) self.assertEqual(page.lang, 'fr') def test_save_as(self): # If a lang is not the default lang, save_as should be set # accordingly. # if a title is defined, save_as should be set page = Page(**self.page_kwargs) self.assertEqual(page.save_as, "pages/foo-bar.html") # if a language is defined, save_as should include it accordingly self.page_kwargs['metadata'].update({'lang': 'fr', }) page = Page(**self.page_kwargs) self.assertEqual(page.save_as, "pages/foo-bar-fr.html") def test_metadata_url_format(self): # Arbitrary metadata should be passed through url_format() page = Page(**self.page_kwargs) self.assertIn('summary', page.url_format.keys()) page.metadata['directory'] = 'test-dir' page.settings = get_settings(PAGE_SAVE_AS='{directory}/{slug}') self.assertEqual(page.save_as, 'test-dir/foo-bar') def test_datetime(self): # If DATETIME is set to a tuple, it should be used to override LOCALE dt = datetime(2015, 9, 13) page_kwargs = self._copy_page_kwargs() # set its date to dt page_kwargs['metadata']['date'] = dt page = Page(**page_kwargs) self.assertEqual(page.locale_date, dt.strftime(DEFAULT_CONFIG['DEFAULT_DATE_FORMAT'])) page_kwargs['settings'] = get_settings() # I doubt this can work on all platforms ... if platform == "win32": locale = 'jpn' else: locale = 'ja_JP.utf8' page_kwargs['settings']['DATE_FORMATS'] = {'jp': (locale, '%Y-%m-%d(%a)')} page_kwargs['metadata']['lang'] = 'jp' import locale as locale_module try: page = Page(**page_kwargs) self.assertEqual(page.locale_date, '2015-09-13(\u65e5)') except locale_module.Error: # The constructor of ``Page`` will try to set the locale to # ``ja_JP.utf8``. But this attempt will failed when there is no # such locale in the system. You can see which locales there are # in your system with ``locale -a`` command. # # Until we find some other method to test this functionality, we # will simply skip this test. unittest.skip("There is no locale %s in this system." % locale) def test_template(self): # Pages default to page, metadata overwrites default_page = Page(**self.page_kwargs) self.assertEqual('page', default_page.template) page_kwargs = self._copy_page_kwargs() page_kwargs['metadata']['template'] = 'custom' custom_page = Page(**page_kwargs) self.assertEqual('custom', custom_page.template) def _copy_page_kwargs(self): # make a deep copy of page_kwargs page_kwargs = dict([(key, self.page_kwargs[key]) for key in self.page_kwargs]) for key in page_kwargs: if not isinstance(page_kwargs[key], dict): break page_kwargs[key] = dict([(subkey, page_kwargs[key][subkey]) for subkey in page_kwargs[key]]) return page_kwargs def test_signal(self): # If a title is given, it should be used to generate the slug. def receiver_test_function(sender, instance): pass content_object_init.connect(receiver_test_function, sender=Page) Page(**self.page_kwargs) self.assertTrue(content_object_init.has_receivers_for(Page)) def test_get_content(self): # Test that the content is updated with the relative links to # filenames, tags and categories. settings = get_settings() args = self.page_kwargs.copy() args['settings'] = settings # Tag args['content'] = ('A simple test, with a ' 'link') page = Page(**args) content = page.get_content('http://notmyidea.org') self.assertEquals(content, ('A simple test, with a ' 'link')) # Category args['content'] = ('A simple test, with a ' 'link') page = Page(**args) content = page.get_content('http://notmyidea.org') self.assertEquals(content, ('A simple test, with a ' 'link')) class TestArticle(TestPage): def test_template(self): # Articles default to article, metadata overwrites default_article = Article(**self.page_kwargs) self.assertEqual('article', default_article.template) article_kwargs = self._copy_page_kwargs() article_kwargs['metadata']['template'] = 'custom' custom_article = Article(**article_kwargs) self.assertEqual('custom', custom_article.template) def test_slugify_category_author(self): settings = get_settings() settings['SLUG_SUBSTITUTIONS'] = [ ('C#', 'csharp') ] settings['ARTICLE_URL'] = '{author}/{category}/{slug}/' settings['ARTICLE_SAVE_AS'] = '{author}/{category}/{slug}/index.html' article_kwargs = self._copy_page_kwargs() article_kwargs['metadata']['author'] = "O'Brien" article_kwargs['metadata']['category'] = 'C# & stuff' article_kwargs['metadata']['title'] = 'fnord' article_kwargs['settings'] = settings article = Article(**article_kwargs) self.assertEqual(article.url, 'obrien/csharp-stuff/fnord/') self.assertEqual(article.save_as, 'obrien/csharp-stuff/fnord/index.html') class TestURLWrapper(unittest.TestCase): def test_comparisons(self): # URLWrappers are sorted by name wrapper_a = URLWrapper(name='first', settings={}) wrapper_b = URLWrapper(name='last', settings={}) self.assertFalse(wrapper_a > wrapper_b) self.assertFalse(wrapper_a >= wrapper_b) self.assertFalse(wrapper_a == wrapper_b) self.assertTrue(wrapper_a != wrapper_b) self.assertTrue(wrapper_a <= wrapper_b) self.assertTrue(wrapper_a < wrapper_b) wrapper_b.name = 'first' self.assertFalse(wrapper_a > wrapper_b) self.assertTrue(wrapper_a >= wrapper_b) self.assertTrue(wrapper_a == wrapper_b) self.assertFalse(wrapper_a != wrapper_b) self.assertTrue(wrapper_a <= wrapper_b) self.assertFalse(wrapper_a < wrapper_b) wrapper_a.name = 'last' self.assertTrue(wrapper_a > wrapper_b) self.assertTrue(wrapper_a >= wrapper_b) self.assertFalse(wrapper_a == wrapper_b) self.assertTrue(wrapper_a != wrapper_b) self.assertFalse(wrapper_a <= wrapper_b) self.assertFalse(wrapper_a < wrapper_b) pelican-3.3/pelican/tests/test_generators.py0000644000076500000240000002725012200765023021065 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import os from codecs import open from mock import MagicMock from shutil import rmtree from tempfile import mkdtemp from pelican.generators import (Generator, ArticlesGenerator, PagesGenerator, TemplatePagesGenerator) from pelican.writers import Writer from pelican.tests.support import unittest, get_settings CUR_DIR = os.path.dirname(__file__) CONTENT_DIR = os.path.join(CUR_DIR, 'content') class TestGenerator(unittest.TestCase): def setUp(self): self.settings = get_settings() self.settings['READERS'] = {'asc': None} self.generator = Generator(self.settings.copy(), self.settings, CUR_DIR, self.settings['THEME'], None) def test_include_path(self): filename = os.path.join(CUR_DIR, 'content', 'article.rst') include_path = self.generator._include_path self.assertTrue(include_path(filename)) self.assertTrue(include_path(filename, extensions=('rst',))) self.assertFalse(include_path(filename, extensions=('md',))) class TestArticlesGenerator(unittest.TestCase): @classmethod def setUpClass(cls): settings = get_settings(filenames={}) settings['DEFAULT_CATEGORY'] = 'Default' settings['DEFAULT_DATE'] = (1970, 1, 1) settings['READERS'] = {'asc': None} cls.generator = ArticlesGenerator( context=settings.copy(), settings=settings, path=CONTENT_DIR, theme=settings['THEME'], output_path=None) cls.generator.generate_context() cls.articles = [[page.title, page.status, page.category.name, page.template] for page in cls.generator.articles] def test_generate_feeds(self): settings = get_settings() generator = ArticlesGenerator( context=settings, settings=settings, path=None, theme=settings['THEME'], output_path=None) writer = MagicMock() generator.generate_feeds(writer) writer.write_feed.assert_called_with([], settings, 'feeds/all.atom.xml') generator = ArticlesGenerator( context=settings, settings=get_settings(FEED_ALL_ATOM=None), path=None, theme=settings['THEME'], output_path=None) writer = MagicMock() generator.generate_feeds(writer) self.assertFalse(writer.write_feed.called) def test_generate_context(self): articles_expected = [ ['Article title', 'published', 'Default', 'article'], ['Article with markdown and summary metadata multi', 'published', 'Default', 'article'], ['Article with markdown and summary metadata single', 'published', 'Default', 'article'], ['Article with markdown containing footnotes', 'published', 'Default', 'article'], ['Article with template', 'published', 'Default', 'custom'], ['Rst with filename metadata', 'published', 'yeah', 'article'], ['Test Markdown extensions', 'published', 'Default', 'article'], ['Test markdown File', 'published', 'test', 'article'], ['Test md File', 'published', 'test', 'article'], ['Test mdown File', 'published', 'test', 'article'], ['Test mkd File', 'published', 'test', 'article'], ['This is a super article !', 'published', 'Yeah', 'article'], ['This is a super article !', 'published', 'Yeah', 'article'], ['This is a super article !', 'published', 'yeah', 'article'], ['This is a super article !', 'published', 'yeah', 'article'], ['This is a super article !', 'published', 'yeah', 'article'], ['This is a super article !', 'published', 'Default', 'article'], ['This is an article with category !', 'published', 'yeah', 'article'], ['This is an article without category !', 'published', 'Default', 'article'], ['This is an article without category !', 'published', 'TestCategory', 'article'], ['マックOS X 10.8でパイソンとVirtualenvをインストールと設定', 'published', '指導書', 'article'], ] self.assertEqual(sorted(articles_expected), sorted(self.articles)) def test_generate_categories(self): # test for name # categories are grouped by slug; if two categories have the same slug # but different names they will be grouped together, the first one in # terms of process order will define the name for that category categories = [cat.name for cat, _ in self.generator.categories] categories_alternatives = ( sorted(['Default', 'TestCategory', 'Yeah', 'test', '指導書']), sorted(['Default', 'TestCategory', 'yeah', 'test', '指導書']), ) self.assertIn(sorted(categories), categories_alternatives) # test for slug categories = [cat.slug for cat, _ in self.generator.categories] categories_expected = ['default', 'testcategory', 'yeah', 'test', 'zhi-dao-shu'] self.assertEqual(sorted(categories), sorted(categories_expected)) def test_do_not_use_folder_as_category(self): settings = get_settings(filenames={}) settings['DEFAULT_CATEGORY'] = 'Default' settings['DEFAULT_DATE'] = (1970, 1, 1) settings['USE_FOLDER_AS_CATEGORY'] = False settings['READERS'] = {'asc': None} settings['filenames'] = {} generator = ArticlesGenerator( context=settings.copy(), settings=settings, path=CONTENT_DIR, theme=settings['THEME'], output_path=None) generator.generate_context() # test for name # categories are grouped by slug; if two categories have the same slug # but different names they will be grouped together, the first one in # terms of process order will define the name for that category categories = [cat.name for cat, _ in generator.categories] categories_alternatives = ( sorted(['Default', 'Yeah', 'test', '指導書']), sorted(['Default', 'yeah', 'test', '指導書']), ) self.assertIn(sorted(categories), categories_alternatives) # test for slug categories = [cat.slug for cat, _ in generator.categories] categories_expected = ['default', 'yeah', 'test', 'zhi-dao-shu'] self.assertEqual(sorted(categories), sorted(categories_expected)) def test_direct_templates_save_as_default(self): settings = get_settings(filenames={}) generator = ArticlesGenerator( context=settings, settings=settings, path=None, theme=settings['THEME'], output_path=None) write = MagicMock() generator.generate_direct_templates(write) write.assert_called_with("archives.html", generator.get_template("archives"), settings, blog=True, paginated={}, page_name='archives') def test_direct_templates_save_as_modified(self): settings = get_settings() settings['DIRECT_TEMPLATES'] = ['archives'] settings['ARCHIVES_SAVE_AS'] = 'archives/index.html' generator = ArticlesGenerator( context=settings, settings=settings, path=None, theme=settings['THEME'], output_path=None) write = MagicMock() generator.generate_direct_templates(write) write.assert_called_with("archives/index.html", generator.get_template("archives"), settings, blog=True, paginated={}, page_name='archives/index') def test_direct_templates_save_as_false(self): settings = get_settings() settings['DIRECT_TEMPLATES'] = ['archives'] settings['ARCHIVES_SAVE_AS'] = 'archives/index.html' generator = ArticlesGenerator( context=settings, settings=settings, path=None, theme=settings['THEME'], output_path=None) write = MagicMock() generator.generate_direct_templates(write) write.assert_called_count == 0 def test_per_article_template(self): """ Custom template articles get the field but standard/unset are None """ custom_template = ['Article with template', 'published', 'Default', 'custom'] standard_template = ['This is a super article !', 'published', 'Yeah', 'article'] self.assertIn(custom_template, self.articles) self.assertIn(standard_template, self.articles) class TestPageGenerator(unittest.TestCase): # Note: Every time you want to test for a new field; Make sure the test # pages in "TestPages" have all the fields Add it to distilled in # distill_pages Then update the assertEqual in test_generate_context # to match expected def distill_pages(self, pages): return [[page.title, page.status, page.template] for page in pages] def test_generate_context(self): settings = get_settings(filenames={}) settings['PAGE_DIR'] = 'TestPages' # relative to CUR_DIR settings['DEFAULT_DATE'] = (1970, 1, 1) generator = PagesGenerator( context=settings.copy(), settings=settings, path=CUR_DIR, theme=settings['THEME'], output_path=None) generator.generate_context() pages = self.distill_pages(generator.pages) hidden_pages = self.distill_pages(generator.hidden_pages) pages_expected = [ ['This is a test page', 'published', 'page'], ['This is a markdown test page', 'published', 'page'], ['This is a test page with a preset template', 'published', 'custom'] ] hidden_pages_expected = [ ['This is a test hidden page', 'hidden', 'page'], ['This is a markdown test hidden page', 'hidden', 'page'], ['This is a test hidden page with a custom template', 'hidden', 'custom'] ] self.assertEqual(sorted(pages_expected), sorted(pages)) self.assertEqual(sorted(hidden_pages_expected), sorted(hidden_pages)) class TestTemplatePagesGenerator(unittest.TestCase): TEMPLATE_CONTENT = "foo: {{ foo }}" def setUp(self): self.temp_content = mkdtemp(prefix='pelicantests.') self.temp_output = mkdtemp(prefix='pelicantests.') def tearDown(self): rmtree(self.temp_content) rmtree(self.temp_output) def test_generate_output(self): settings = get_settings() settings['STATIC_PATHS'] = ['static'] settings['TEMPLATE_PAGES'] = { 'template/source.html': 'generated/file.html' } generator = TemplatePagesGenerator( context={'foo': 'bar'}, settings=settings, path=self.temp_content, theme='', output_path=self.temp_output) # create a dummy template file template_dir = os.path.join(self.temp_content, 'template') template_path = os.path.join(template_dir, 'source.html') os.makedirs(template_dir) with open(template_path, 'w') as template_file: template_file.write(self.TEMPLATE_CONTENT) writer = Writer(self.temp_output, settings=settings) generator.generate_output(writer) output_path = os.path.join(self.temp_output, 'generated', 'file.html') # output file has been generated self.assertTrue(os.path.exists(output_path)) # output content is correct with open(output_path, 'r') as output_file: self.assertEqual(output_file.read(), 'foo: bar') pelican-3.3/pelican/tests/test_importer.py0000666000076500000240000001310012156435150020553 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import os import re from pelican.tools.pelican_import import wp2fields, fields2pelican, decode_wp_content from pelican.tests.support import (unittest, temporary_folder, mute, skipIfNoExecutable) CUR_DIR = os.path.dirname(__file__) WORDPRESS_XML_SAMPLE = os.path.join(CUR_DIR, 'content', 'wordpressexport.xml') WORDPRESS_ENCODED_CONTENT_SAMPLE = os.path.join(CUR_DIR, 'content', 'wordpress_content_encoded') WORDPRESS_DECODED_CONTENT_SAMPLE = os.path.join(CUR_DIR, 'content', 'wordpress_content_decoded') try: from bs4 import BeautifulSoup except ImportError: BeautifulSoup = False # NOQA @skipIfNoExecutable(['pandoc', '--version']) @unittest.skipUnless(BeautifulSoup, 'Needs BeautifulSoup module') class TestWordpressXmlImporter(unittest.TestCase): def setUp(self): self.posts = list(wp2fields(WORDPRESS_XML_SAMPLE)) def test_ignore_empty_posts(self): self.assertTrue(self.posts) for title, content, fname, date, author, categ, tags, kind, format in self.posts: self.assertTrue(title.strip()) def test_recognise_page_kind(self): """ Check that we recognise pages in wordpress, as opposed to posts """ self.assertTrue(self.posts) # Collect (title, filename, kind) of non-empty posts recognised as page pages_data = [] for title, content, fname, date, author, categ, tags, kind, format in self.posts: if kind == 'page': pages_data.append((title, fname)) self.assertEqual(2, len(pages_data)) self.assertEqual(('Page', 'contact'), pages_data[0]) self.assertEqual(('Empty Page', 'empty'), pages_data[1]) def test_dirpage_directive_for_page_kind(self): silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Empty Page"), self.posts) with temporary_folder() as temp: fname = list(silent_f2p(test_post, 'markdown', temp, dirpage=True))[0] self.assertTrue(fname.endswith('pages%sempty.md' % os.path.sep)) def test_can_toggle_raw_html_code_parsing(self): def r(f): with open(f) as infile: return infile.read() silent_f2p = mute(True)(fields2pelican) with temporary_folder() as temp: rst_files = (r(f) for f in silent_f2p(self.posts, 'markdown', temp)) self.assertTrue(any(' entities in the" " title. You can't miss them.") self.assertNotIn('&', title) def test_decode_wp_content_returns_empty(self): """ Check that given an empty string we return an empty string.""" self.assertEqual(decode_wp_content(""), "") def test_decode_wp_content(self): """ Check that we can decode a wordpress content string.""" with open(WORDPRESS_ENCODED_CONTENT_SAMPLE, 'r') as encoded_file: encoded_content = encoded_file.read() with open(WORDPRESS_DECODED_CONTENT_SAMPLE, 'r') as decoded_file: decoded_content = decoded_file.read() self.assertEqual(decode_wp_content(encoded_content, br=False), decoded_content) def test_preserve_verbatim_formatting(self): def r(f): with open(f) as infile: return infile.read() silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Code in List"), self.posts) with temporary_folder() as temp: md = [r(f) for f in silent_f2p(test_post, 'markdown', temp)][0] self.assertTrue(re.search(r'\s+a = \[1, 2, 3\]', md)) self.assertTrue(re.search(r'\s+b = \[4, 5, 6\]', md)) for_line = re.search(r'\s+for i in zip\(a, b\):', md).group(0) print_line = re.search(r'\s+print i', md).group(0) self.assertTrue(for_line.rindex('for') < print_line.rindex('print')) def test_code_in_list(self): def r(f): with open(f) as infile: return infile.read() silent_f2p = mute(True)(fields2pelican) test_post = filter(lambda p: p[0].startswith("Code in List"), self.posts) with temporary_folder() as temp: md = [r(f) for f in silent_f2p(test_post, 'markdown', temp)][0] sample_line = re.search(r'- This is a code sample', md).group(0) code_line = re.search(r'\s+a = \[1, 2, 3\]', md).group(0) self.assertTrue(sample_line.rindex('This') < code_line.rindex('a')) pelican-3.3/pelican/tests/test_pelican.py0000644000076500000240000001211012216354256020325 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import os from filecmp import dircmp from tempfile import mkdtemp from shutil import rmtree import locale import logging from pelican import Pelican from pelican.settings import read_settings from pelican.tests.support import LoggedTestCase, mute CURRENT_DIR = os.path.dirname(os.path.abspath(__file__)) SAMPLES_PATH = os.path.abspath(os.path.join( CURRENT_DIR, os.pardir, os.pardir, 'samples')) OUTPUT_PATH = os.path.abspath(os.path.join(CURRENT_DIR, 'output')) INPUT_PATH = os.path.join(SAMPLES_PATH, "content") SAMPLE_CONFIG = os.path.join(SAMPLES_PATH, "pelican.conf.py") def recursiveDiff(dcmp): diff = { 'diff_files': [os.path.join(dcmp.right, f) for f in dcmp.diff_files], 'left_only': [os.path.join(dcmp.right, f) for f in dcmp.left_only], 'right_only': [os.path.join(dcmp.right, f) for f in dcmp.right_only], } for sub_dcmp in dcmp.subdirs.values(): for k, v in recursiveDiff(sub_dcmp).items(): diff[k] += v return diff class TestPelican(LoggedTestCase): # general functional testing for pelican. Basically, this test case tries # to run pelican in different situations and see how it behaves def setUp(self): super(TestPelican, self).setUp() self.temp_path = mkdtemp(prefix='pelicantests.') self.old_locale = locale.setlocale(locale.LC_ALL) self.maxDiff = None locale.setlocale(locale.LC_ALL, str('C')) def tearDown(self): rmtree(self.temp_path) locale.setlocale(locale.LC_ALL, self.old_locale) super(TestPelican, self).tearDown() def assertFilesEqual(self, diff): msg = ("some generated files differ from the expected functional " "tests output.\n" "This is probably because the HTML generated files " "changed. If these changes are normal, please refer " "to docs/contribute.rst to update the expected " "output of the functional tests.") self.assertEqual(diff['left_only'], [], msg=msg) self.assertEqual(diff['right_only'], [], msg=msg) self.assertEqual(diff['diff_files'], [], msg=msg) def test_basic_generation_works(self): # when running pelican without settings, it should pick up the default # ones and generate correct output without raising any exception settings = read_settings(path=None, override={ 'PATH': INPUT_PATH, 'OUTPUT_PATH': self.temp_path, 'LOCALE': locale.normalize('en_US'), }) pelican = Pelican(settings=settings) mute(True)(pelican.run)() dcmp = dircmp(self.temp_path, os.path.join(OUTPUT_PATH, 'basic')) self.assertFilesEqual(recursiveDiff(dcmp)) self.assertLogCountEqual( count=4, msg="Unable to find.*skipping url replacement", level=logging.WARNING) def test_custom_generation_works(self): # the same thing with a specified set of settings should work settings = read_settings(path=SAMPLE_CONFIG, override={ 'PATH': INPUT_PATH, 'OUTPUT_PATH': self.temp_path, 'LOCALE': locale.normalize('en_US'), }) pelican = Pelican(settings=settings) mute(True)(pelican.run)() dcmp = dircmp(self.temp_path, os.path.join(OUTPUT_PATH, 'custom')) self.assertFilesEqual(recursiveDiff(dcmp)) def test_theme_static_paths_copy(self): # the same thing with a specified set of settings should work settings = read_settings(path=SAMPLE_CONFIG, override={ 'PATH': INPUT_PATH, 'OUTPUT_PATH': self.temp_path, 'THEME_STATIC_PATHS': [os.path.join(SAMPLES_PATH, 'very'), os.path.join(SAMPLES_PATH, 'kinda'), os.path.join(SAMPLES_PATH, 'theme_standard')] }) pelican = Pelican(settings=settings) mute(True)(pelican.run)() theme_output = os.path.join(self.temp_path, 'theme') extra_path = os.path.join(theme_output, 'exciting', 'new', 'files') for file in ['a_stylesheet', 'a_template']: self.assertTrue(os.path.exists(os.path.join(theme_output, file))) for file in ['wow!', 'boom!', 'bap!', 'zap!']: self.assertTrue(os.path.exists(os.path.join(extra_path, file))) def test_theme_static_paths_copy_single_file(self): # the same thing with a specified set of settings should work settings = read_settings(path=SAMPLE_CONFIG, override={ 'PATH': INPUT_PATH, 'OUTPUT_PATH': self.temp_path, 'THEME_STATIC_PATHS': [os.path.join(SAMPLES_PATH, 'theme_standard')] }) pelican = Pelican(settings=settings) mute(True)(pelican.run)() theme_output = os.path.join(self.temp_path, 'theme') for file in ['a_stylesheet', 'a_template']: self.assertTrue(os.path.exists(os.path.join(theme_output, file))) pelican-3.3/pelican/tests/test_readers.py0000644000076500000240000003721512207763674020364 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import datetime import os from pelican import readers from pelican.tests.support import unittest, get_settings CUR_DIR = os.path.dirname(__file__) CONTENT_PATH = os.path.join(CUR_DIR, 'content') def _path(*args): return os.path.join(CONTENT_PATH, *args) class ReaderTest(unittest.TestCase): def read_file(self, path, **kwargs): # Isolate from future API changes to readers.read_file r = readers.Readers(settings=get_settings(**kwargs)) return r.read_file(base_path=CONTENT_PATH, path=path) class DefaultReaderTest(ReaderTest): def test_readfile_unknown_extension(self): with self.assertRaises(TypeError): self.read_file(path='article_with_metadata.unknownextension') class RstReaderTest(ReaderTest): def test_article_with_metadata(self): page = self.read_file(path='article_with_metadata.rst') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'This is a super article !', 'summary': '

    Multi-line metadata should be' ' supported\nas well as inline' ' markup.

    \n', 'date': datetime.datetime(2010, 12, 2, 10, 14), 'tags': ['foo', 'bar', 'foobar'], 'custom_field': 'http://notmyidea.org', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) def test_article_with_filename_metadata(self): page = self.read_file( path='2012-11-29_rst_w_filename_meta#foo-bar.rst', FILENAME_METADATA=None) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'Rst with filename metadata', } for key, value in page.metadata.items(): self.assertEqual(value, expected[key], key) page = self.read_file( path='2012-11-29_rst_w_filename_meta#foo-bar.rst', FILENAME_METADATA='(?P\d{4}-\d{2}-\d{2}).*') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'Rst with filename metadata', 'date': datetime.datetime(2012, 11, 29), } for key, value in page.metadata.items(): self.assertEqual(value, expected[key], key) page = self.read_file( path='2012-11-29_rst_w_filename_meta#foo-bar.rst', FILENAME_METADATA=( '(?P\d{4}-\d{2}-\d{2})_' '_(?P.*)' '#(?P.*)-(?P.*)')) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'Rst with filename metadata', 'date': datetime.datetime(2012, 11, 29), 'slug': 'article_with_filename_metadata', 'mymeta': 'foo', } for key, value in page.metadata.items(): self.assertEqual(value, expected[key], key) def test_article_metadata_key_lowercase(self): # Keys of metadata should be lowercase. reader = readers.RstReader(settings=get_settings()) content, metadata = reader.read( _path('article_with_uppercase_metadata.rst')) self.assertIn('category', metadata, 'Key should be lowercase.') self.assertEqual('Yeah', metadata.get('category'), 'Value keeps case.') def test_typogrify(self): # if nothing is specified in the settings, the content should be # unmodified page = self.read_file(path='article.rst') expected = ('

    This is some content. With some stuff to ' '"typogrify".

    \n

    Now with added ' 'support for ' 'TLA.

    \n') self.assertEqual(page.content, expected) try: # otherwise, typogrify should be applied page = self.read_file(path='article.rst', TYPOGRIFY=True) expected = ('

    This is some content. With some stuff to ' '“typogrify”.

    \n

    Now with added ' 'support for ' 'TLA.

    \n') self.assertEqual(page.content, expected) except ImportError: return unittest.skip('need the typogrify distribution') class MdReaderTest(ReaderTest): @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_metadata(self): reader = readers.MarkdownReader(settings=get_settings()) content, metadata = reader.read( _path('article_with_md_extension.md')) expected = { 'category': 'test', 'title': 'Test md File', 'summary': '

    I have a lot to test

    ', 'date': datetime.datetime(2010, 12, 2, 10, 14), 'tags': ['foo', 'bar', 'foobar'], } for key, value in metadata.items(): self.assertEqual(value, expected[key], key) content, metadata = reader.read( _path('article_with_markdown_and_nonascii_summary.md')) expected = { 'title': 'マックOS X 10.8でパイソンとVirtualenvをインストールと設定', 'summary': '

    パイソンとVirtualenvをまっくでインストールする方法について明確に説明します。

    ', 'category': '指導書', 'date': datetime.datetime(2012, 12, 20), 'tags': ['パイソン', 'マック'], 'slug': 'python-virtualenv-on-mac-osx-mountain-lion-10.8', } for key, value in metadata.items(): self.assertEqual(value, expected[key], key) @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_footnote(self): reader = readers.MarkdownReader(settings=get_settings()) content, metadata = reader.read( _path('article_with_markdown_and_footnote.md')) expected_content = ( '

    This is some content' '1' ' with some footnotes' '2

    \n' '
    \n' '
    \n
      \n
    1. \n' '

      Numbered footnote ' '

      \n' '
    2. \n
    3. \n' '

      Named footnote ' '

      \n' '
    4. \n
    \n
    ') expected_metadata = { 'title': 'Article with markdown containing footnotes', 'summary': ( '

    Summary with inline markup ' 'should be supported.

    '), 'date': datetime.datetime(2012, 10, 31), 'slug': 'article-with-markdown-containing-footnotes', } self.assertEqual(content, expected_content) for key, value in metadata.items(): self.assertEqual(value, expected_metadata[key], key) @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_file_extensions(self): reader = readers.MarkdownReader(settings=get_settings()) # test to ensure the md file extension is being processed by the # correct reader content, metadata = reader.read( _path('article_with_md_extension.md')) expected = ( "

    Test Markdown File Header

    \n" "

    Used for pelican test

    \n" "

    The quick brown fox jumped over the lazy dog's back.

    ") self.assertEqual(content, expected) # test to ensure the mkd file extension is being processed by the # correct reader content, metadata = reader.read( _path('article_with_mkd_extension.mkd')) expected = ("

    Test Markdown File Header

    \n

    Used for pelican" " test

    \n

    This is another markdown test file. Uses" " the mkd extension.

    ") self.assertEqual(content, expected) # test to ensure the markdown file extension is being processed by the # correct reader content, metadata = reader.read( _path('article_with_markdown_extension.markdown')) expected = ("

    Test Markdown File Header

    \n

    Used for pelican" " test

    \n

    This is another markdown test file. Uses" " the markdown extension.

    ") self.assertEqual(content, expected) # test to ensure the mdown file extension is being processed by the # correct reader content, metadata = reader.read( _path('article_with_mdown_extension.mdown')) expected = ("

    Test Markdown File Header

    \n

    Used for pelican" " test

    \n

    This is another markdown test file. Uses" " the mdown extension.

    ") self.assertEqual(content, expected) @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_markdown_markup_extension(self): # test to ensure the markdown markup extension is being processed as # expected page = self.read_file( path='article_with_markdown_markup_extensions.md', MD_EXTENSIONS=['toc', 'codehilite', 'extra']) expected = ('
    \n' '\n' '
    \n' '

    Level1

    \n' '

    Level2

    ') self.assertEqual(page.content, expected) @unittest.skipUnless(readers.Markdown, "markdown isn't installed") def test_article_with_filename_metadata(self): page = self.read_file( path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA=None) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) page = self.read_file( path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA='(?P\d{4}-\d{2}-\d{2}).*') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'date': datetime.datetime(2012, 11, 30), } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) page = self.read_file( path='2012-11-30_md_w_filename_meta#foo-bar.md', FILENAME_METADATA=( '(?P\d{4}-\d{2}-\d{2})' '_(?P.*)' '#(?P.*)-(?P.*)')) expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'date': datetime.datetime(2012, 11, 30), 'slug': 'md_w_filename_meta', 'mymeta': 'foo', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) class AdReaderTest(ReaderTest): @unittest.skipUnless(readers.asciidoc, "asciidoc isn't installed") def test_article_with_asc_extension(self): # Ensure the asc extension is being processed by the correct reader page = self.read_file( path='article_with_asc_extension.asc') expected = ('
    \n

    ' 'Used for pelican test

    \n' '

    The quick brown fox jumped over' ' the lazy dog’s back.

    \n') self.assertEqual(page.content, expected) expected = { 'category': 'Blog', 'author': 'Author O. Article', 'title': 'Test AsciiDoc File Header', 'date': datetime.datetime(2011, 9, 15, 9, 5), 'tags': ['Linux', 'Python', 'Pelican'], } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) @unittest.skipUnless(readers.asciidoc, "asciidoc isn't installed") def test_article_with_asc_options(self): # test to ensure the ASCIIDOC_OPTIONS is being used reader = readers.AsciiDocReader( dict(ASCIIDOC_OPTIONS=["-a revision=1.0.42"])) content, metadata = reader.read(_path('article_with_asc_options.asc')) expected = ('
    \n

    Used for' ' pelican test

    \n

    version 1.0.42

    \n' '

    The quick brown fox jumped over the lazy' ' dog’s back.

    \n') self.assertEqual(content, expected) class HTMLReaderTest(ReaderTest): def test_article_with_comments(self): page = self.read_file(path='article_with_comments.html') self.assertEqual(''' Body content ''', page.content) def test_article_with_keywords(self): page = self.read_file(path='article_with_keywords.html') expected = { 'tags': ['foo', 'bar', 'foobar'], } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) def test_article_with_metadata(self): page = self.read_file(path='article_with_metadata.html') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'This is a super article !', 'summary': 'Summary and stuff', 'date': datetime.datetime(2010, 12, 2, 10, 14), 'tags': ['foo', 'bar', 'foobar'], 'custom_field': 'http://notmyidea.org', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) def test_article_with_metadata_and_contents_attrib(self): page = self.read_file(path='article_with_metadata_and_contents.html') expected = { 'category': 'yeah', 'author': 'Alexis Métaireau', 'title': 'This is a super article !', 'summary': 'Summary and stuff', 'date': datetime.datetime(2010, 12, 2, 10, 14), 'tags': ['foo', 'bar', 'foobar'], 'custom_field': 'http://notmyidea.org', } for key, value in expected.items(): self.assertEqual(value, page.metadata[key], key) def test_article_with_null_attributes(self): page = self.read_file(path='article_with_null_attributes.html') self.assertEqual(''' Ensure that empty attributes are copied properly. ''', page.content) def test_article_metadata_key_lowercase(self): # Keys of metadata should be lowercase. page = self.read_file(path='article_with_uppercase_metadata.html') self.assertIn('category', page.metadata, 'Key should be lowercase.') self.assertEqual('Yeah', page.metadata.get('category'), 'Value keeps cases.') pelican-3.3/pelican/tests/test_settings.py0000644000076500000240000001027212177737636020576 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import copy import os import locale from os.path import dirname, abspath, join from pelican.settings import (read_settings, configure_settings, DEFAULT_CONFIG, DEFAULT_THEME) from pelican.tests.support import unittest class TestSettingsConfiguration(unittest.TestCase): """Provided a file, it should read it, replace the default values, append new values to the settings (if any), and apply basic settings optimizations. """ def setUp(self): self.PATH = abspath(dirname(__file__)) default_conf = join(self.PATH, 'default_conf.py') self.settings = read_settings(default_conf) def test_overwrite_existing_settings(self): self.assertEqual(self.settings.get('SITENAME'), "Alexis' log") self.assertEqual(self.settings.get('SITEURL'), 'http://blog.notmyidea.org') def test_keep_default_settings(self): # Keep default settings if not defined. self.assertEqual(self.settings.get('DEFAULT_CATEGORY'), DEFAULT_CONFIG['DEFAULT_CATEGORY']) def test_dont_copy_small_keys(self): # Do not copy keys not in caps. self.assertNotIn('foobar', self.settings) def test_read_empty_settings(self): # Providing no file should return the default values. settings = read_settings(None) expected = copy.deepcopy(DEFAULT_CONFIG) expected['FEED_DOMAIN'] = '' # Added by configure settings self.maxDiff = None self.assertDictEqual(settings, expected) def test_settings_return_independent(self): # Make sure that the results from one settings call doesn't # effect past or future instances. self.PATH = abspath(dirname(__file__)) default_conf = join(self.PATH, 'default_conf.py') settings = read_settings(default_conf) settings['SITEURL'] = 'new-value' new_settings = read_settings(default_conf) self.assertNotEqual(new_settings['SITEURL'], settings['SITEURL']) def test_defaults_not_overwritten(self): # This assumes 'SITENAME': 'A Pelican Blog' settings = read_settings(None) settings['SITENAME'] = 'Not a Pelican Blog' self.assertNotEqual(settings['SITENAME'], DEFAULT_CONFIG['SITENAME']) def test_path_settings_safety(self): """Don't let people setting the static path listings to strs""" settings = {'STATIC_PATHS': 'foo/bar', 'THEME_STATIC_PATHS': 'bar/baz', # These 4 settings are required to run configure_settings 'PATH': '.', 'THEME': DEFAULT_THEME, 'SITEURL': 'http://blog.notmyidea.org/', 'LOCALE': '', } configure_settings(settings) self.assertEqual(settings['STATIC_PATHS'], DEFAULT_CONFIG['STATIC_PATHS']) self.assertEqual(settings['THEME_STATIC_PATHS'], DEFAULT_CONFIG['THEME_STATIC_PATHS']) def test_configure_settings(self): #Manipulations to settings should be applied correctly. settings = { 'SITEURL': 'http://blog.notmyidea.org/', 'LOCALE': '', 'PATH': os.curdir, 'THEME': DEFAULT_THEME, } configure_settings(settings) # SITEURL should not have a trailing slash self.assertEqual(settings['SITEURL'], 'http://blog.notmyidea.org') # FEED_DOMAIN, if undefined, should default to SITEURL self.assertEqual(settings['FEED_DOMAIN'], 'http://blog.notmyidea.org') settings['FEED_DOMAIN'] = 'http://feeds.example.com' configure_settings(settings) self.assertEqual(settings['FEED_DOMAIN'], 'http://feeds.example.com') def test_default_encoding(self): # test that the default locale is set if # locale is not specified in the settings #reset locale to python default locale.setlocale(locale.LC_ALL, str('C')) self.assertEqual(self.settings['LOCALE'], DEFAULT_CONFIG['LOCALE']) configure_settings(self.settings) self.assertEqual(locale.getlocale(), locale.getdefaultlocale()) pelican-3.3/pelican/tests/test_utils.py0000644000076500000240000003743712200765023020064 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import logging import shutil import os import datetime import time import locale from sys import platform, version_info from tempfile import mkdtemp import pytz from pelican.generators import TemplatePagesGenerator from pelican.writers import Writer from pelican.settings import read_settings from pelican import utils from .support import get_article, LoggedTestCase, locale_available, unittest class TestUtils(LoggedTestCase): _new_attribute = 'new_value' @utils.deprecated_attribute( old='_old_attribute', new='_new_attribute', since=(3, 1, 0), remove=(4, 1, 3)) def _old_attribute(): return None def test_deprecated_attribute(self): value = self._old_attribute self.assertEqual(value, self._new_attribute) self.assertLogCountEqual( count=1, msg=('_old_attribute has been deprecated since 3.1.0 and will be ' 'removed by version 4.1.3. Use _new_attribute instead'), level=logging.WARNING) def test_get_date(self): # valid ones date = datetime.datetime(year=2012, month=11, day=22) date_hour = datetime.datetime( year=2012, month=11, day=22, hour=22, minute=11) date_hour_sec = datetime.datetime( year=2012, month=11, day=22, hour=22, minute=11, second=10) date_hour_sec_z = datetime.datetime( year=2012, month=11, day=22, hour=22, minute=11, second=10, tzinfo=pytz.timezone('UTC')) date_hour_sec_est = datetime.datetime( year=2012, month=11, day=22, hour=22, minute=11, second=10, tzinfo=pytz.timezone('EST')) date_hour_sec_frac_z = datetime.datetime( year=2012, month=11, day=22, hour=22, minute=11, second=10, microsecond=123000, tzinfo=pytz.timezone('UTC')) dates = { '2012-11-22': date, '2012/11/22': date, '2012-11-22 22:11': date_hour, '2012/11/22 22:11': date_hour, '22-11-2012': date, '22/11/2012': date, '22.11.2012': date, '22.11.2012 22:11': date_hour, '2012-11-22 22:11:10': date_hour_sec, '2012-11-22T22:11:10Z': date_hour_sec_z, '2012-11-22T22:11:10-0500': date_hour_sec_est, '2012-11-22T22:11:10.123Z': date_hour_sec_frac_z, } # invalid ones invalid_dates = ['2010-110-12', 'yay'] if version_info < (3, 2): dates.pop('2012-11-22T22:11:10-0500') invalid_dates.append('2012-11-22T22:11:10-0500') for value, expected in dates.items(): self.assertEqual(utils.get_date(value), expected, value) for item in invalid_dates: self.assertRaises(ValueError, utils.get_date, item) def test_slugify(self): samples = (('this is a test', 'this-is-a-test'), ('this is a test', 'this-is-a-test'), ('this → is ← a ↑ test', 'this-is-a-test'), ('this--is---a test', 'this-is-a-test'), ('unicode測試許功蓋,你看到了嗎?', 'unicodece-shi-xu-gong-gai-ni-kan-dao-liao-ma'), ('大飯原発4号機、18日夜起動へ', 'da-fan-yuan-fa-4hao-ji-18ri-ye-qi-dong-he'),) for value, expected in samples: self.assertEqual(utils.slugify(value), expected) def test_slugify_substitute(self): samples = (('C++ is based on C', 'cpp-is-based-on-c'), ('C+++ test C+ test', 'cpp-test-c-test'), ('c++, c#, C#, C++', 'cpp-c-sharp-c-sharp-cpp'), ('c++-streams', 'cpp-streams'),) subs = (('C++', 'CPP'), ('C#', 'C-SHARP')) for value, expected in samples: self.assertEqual(utils.slugify(value, subs), expected) def test_get_relative_path(self): samples = ((os.path.join('test', 'test.html'), os.pardir), (os.path.join('test', 'test', 'test.html'), os.path.join(os.pardir, os.pardir)), ('test.html', os.curdir), (os.path.join('/test', 'test.html'), os.pardir), (os.path.join('/test', 'test', 'test.html'), os.path.join(os.pardir, os.pardir)), ('/test.html', os.curdir),) for value, expected in samples: self.assertEqual(utils.get_relative_path(value), expected) def test_process_translations(self): # create a bunch of articles # 1: no translation metadata fr_article1 = get_article(lang='fr', slug='yay', title='Un titre', content='en français') en_article1 = get_article(lang='en', slug='yay', title='A title', content='in english') # 2: reverse which one is the translation thanks to metadata fr_article2 = get_article(lang='fr', slug='yay2', title='Un titre', content='en français') en_article2 = get_article(lang='en', slug='yay2', title='A title', content='in english', extra_metadata={'translation': 'true'}) # 3: back to default language detection if all items have the # translation metadata fr_article3 = get_article(lang='fr', slug='yay3', title='Un titre', content='en français', extra_metadata={'translation': 'yep'}) en_article3 = get_article(lang='en', slug='yay3', title='A title', content='in english', extra_metadata={'translation': 'yes'}) articles = [fr_article1, en_article1, fr_article2, en_article2, fr_article3, en_article3] index, trans = utils.process_translations(articles) self.assertIn(en_article1, index) self.assertIn(fr_article1, trans) self.assertNotIn(en_article1, trans) self.assertNotIn(fr_article1, index) self.assertIn(fr_article2, index) self.assertIn(en_article2, trans) self.assertNotIn(fr_article2, trans) self.assertNotIn(en_article2, index) self.assertIn(en_article3, index) self.assertIn(fr_article3, trans) self.assertNotIn(en_article3, trans) self.assertNotIn(fr_article3, index) def test_watchers(self): # Test if file changes are correctly detected # Make sure to handle not getting any files correctly. dirname = os.path.join(os.path.dirname(__file__), 'content') folder_watcher = utils.folder_watcher(dirname, ['rst']) path = os.path.join(dirname, 'article_with_metadata.rst') file_watcher = utils.file_watcher(path) # first check returns True self.assertEqual(next(folder_watcher), True) self.assertEqual(next(file_watcher), True) # next check without modification returns False self.assertEqual(next(folder_watcher), False) self.assertEqual(next(file_watcher), False) # after modification, returns True t = time.time() os.utime(path, (t, t)) self.assertEqual(next(folder_watcher), True) self.assertEqual(next(file_watcher), True) # file watcher with None or empty path should return None self.assertEqual(next(utils.file_watcher('')), None) self.assertEqual(next(utils.file_watcher(None)), None) empty_path = os.path.join(os.path.dirname(__file__), 'empty') try: os.mkdir(empty_path) os.mkdir(os.path.join(empty_path, "empty_folder")) shutil.copy(__file__, empty_path) # if no files of interest, returns None watcher = utils.folder_watcher(empty_path, ['rst']) self.assertEqual(next(watcher), None) except OSError: self.fail("OSError Exception in test_files_changed test") finally: shutil.rmtree(empty_path, True) def test_clean_output_dir(self): retention = () test_directory = os.path.join(os.path.dirname(__file__), 'clean_output') content = os.path.join(os.path.dirname(__file__), 'content') shutil.copytree(content, test_directory) utils.clean_output_dir(test_directory, retention) self.assertTrue(os.path.isdir(test_directory)) self.assertListEqual([], os.listdir(test_directory)) shutil.rmtree(test_directory) def test_clean_output_dir_not_there(self): retention = () test_directory = os.path.join(os.path.dirname(__file__), 'does_not_exist') utils.clean_output_dir(test_directory, retention) self.assertFalse(os.path.exists(test_directory)) def test_clean_output_dir_is_file(self): retention = () test_directory = os.path.join(os.path.dirname(__file__), 'this_is_a_file') f = open(test_directory, 'w') f.write('') f.close() utils.clean_output_dir(test_directory, retention) self.assertFalse(os.path.exists(test_directory)) def test_strftime(self): d = datetime.date(2012, 8, 29) # simple formatting self.assertEqual(utils.strftime(d, '%d/%m/%y'), '29/08/12') self.assertEqual(utils.strftime(d, '%d/%m/%Y'), '29/08/2012') # % escaped self.assertEqual(utils.strftime(d, '%d%%%m%%%y'), '29%08%12') self.assertEqual(utils.strftime(d, '%d %% %m %% %y'), '29 % 08 % 12') # not valid % formatter self.assertEqual(utils.strftime(d, '10% reduction in %Y'), '10% reduction in 2012') self.assertEqual(utils.strftime(d, '%10 reduction in %Y'), '%10 reduction in 2012') # with text self.assertEqual(utils.strftime(d, 'Published in %d-%m-%Y'), 'Published in 29-08-2012') # with non-ascii text self.assertEqual(utils.strftime(d, '%d/%m/%Y Øl trinken beim Besäufnis'), '29/08/2012 Øl trinken beim Besäufnis') # test the output of utils.strftime in a different locale # Turkish locale @unittest.skipUnless(locale_available('tr_TR.UTF-8') or locale_available('Turkish'), 'Turkish locale needed') def test_strftime_locale_dependent_turkish(self): # store current locale old_locale = locale.setlocale(locale.LC_TIME) if platform == 'win32': locale.setlocale(locale.LC_TIME, str('Turkish')) else: locale.setlocale(locale.LC_TIME, str('tr_TR.UTF-8')) d = datetime.date(2012, 8, 29) # simple self.assertEqual(utils.strftime(d, '%d %B %Y'), '29 Ağustos 2012') self.assertEqual(utils.strftime(d, '%A, %d %B %Y'), 'Çarşamba, 29 Ağustos 2012') # with text self.assertEqual(utils.strftime(d, 'Yayınlanma tarihi: %A, %d %B %Y'), 'Yayınlanma tarihi: Çarşamba, 29 Ağustos 2012') # non-ascii format candidate (someone might pass it... for some reason) self.assertEqual(utils.strftime(d, '%Y yılında %üretim artışı'), '2012 yılında %üretim artışı') # restore locale back locale.setlocale(locale.LC_TIME, old_locale) # test the output of utils.strftime in a different locale # French locale @unittest.skipUnless(locale_available('fr_FR.UTF-8') or locale_available('French'), 'French locale needed') def test_strftime_locale_dependent_french(self): # store current locale old_locale = locale.setlocale(locale.LC_TIME) if platform == 'win32': locale.setlocale(locale.LC_TIME, str('French')) else: locale.setlocale(locale.LC_TIME, str('fr_FR.UTF-8')) d = datetime.date(2012, 8, 29) # simple self.assertEqual(utils.strftime(d, '%d %B %Y'), '29 août 2012') # depending on OS, the first letter is m or M self.assertTrue(utils.strftime(d, '%A') in ('mercredi', 'Mercredi')) # with text self.assertEqual(utils.strftime(d, 'Écrit le %d %B %Y'), 'Écrit le 29 août 2012') # non-ascii format candidate (someone might pass it... for some reason) self.assertEqual(utils.strftime(d, '%écrits en %Y'), '%écrits en 2012') # restore locale back locale.setlocale(locale.LC_TIME, old_locale) class TestDateFormatter(unittest.TestCase): '''Tests that the output of DateFormatter jinja filter is same as utils.strftime''' def setUp(self): # prepare a temp content and output folder self.temp_content = mkdtemp(prefix='pelicantests.') self.temp_output = mkdtemp(prefix='pelicantests.') # prepare a template file template_dir = os.path.join(self.temp_content, 'template') template_path = os.path.join(template_dir, 'source.html') os.makedirs(template_dir) with open(template_path, 'w') as template_file: template_file.write('date = {{ date|strftime("%A, %d %B %Y") }}') self.date = datetime.date(2012, 8, 29) def tearDown(self): shutil.rmtree(self.temp_content) shutil.rmtree(self.temp_output) # reset locale to default locale.setlocale(locale.LC_ALL, '') @unittest.skipUnless(locale_available('fr_FR.UTF-8') or locale_available('French'), 'French locale needed') def test_french_locale(self): settings = read_settings( override={'LOCALE': locale.normalize('fr_FR.UTF-8'), 'TEMPLATE_PAGES': {'template/source.html': 'generated/file.html'}}) generator = TemplatePagesGenerator( {'date': self.date}, settings, self.temp_content, '', self.temp_output) generator.env.filters.update({'strftime': utils.DateFormatter()}) writer = Writer(self.temp_output, settings=settings) generator.generate_output(writer) output_path = os.path.join( self.temp_output, 'generated', 'file.html') # output file has been generated self.assertTrue(os.path.exists(output_path)) # output content is correct with utils.pelican_open(output_path) as output_file: self.assertEqual(output_file, utils.strftime(self.date, 'date = %A, %d %B %Y')) @unittest.skipUnless(locale_available('tr_TR.UTF-8') or locale_available('Turkish'), 'Turkish locale needed') def test_turkish_locale(self): settings = read_settings( override = {'LOCALE': locale.normalize('tr_TR.UTF-8'), 'TEMPLATE_PAGES': {'template/source.html': 'generated/file.html'}}) generator = TemplatePagesGenerator( {'date': self.date}, settings, self.temp_content, '', self.temp_output) generator.env.filters.update({'strftime': utils.DateFormatter()}) writer = Writer(self.temp_output, settings=settings) generator.generate_output(writer) output_path = os.path.join( self.temp_output, 'generated', 'file.html') # output file has been generated self.assertTrue(os.path.exists(output_path)) # output content is correct with utils.pelican_open(output_path) as output_file: self.assertEqual(output_file, utils.strftime(self.date, 'date = %A, %d %B %Y')) pelican-3.3/pelican/tests/TestPages/0000755000076500000240000000000012220367225017200 5ustar jmstaff00000000000000pelican-3.3/pelican/tests/TestPages/bad_page.rst0000666000076500000240000000026112130377623021462 0ustar jmstaff00000000000000This is a test bad page ####################### :status: invalid The quick brown fox jumped over the lazy dog's back. The status here is invalid, the page should not render. pelican-3.3/pelican/tests/TestPages/hidden_page.rst0000666000076500000240000000022212130377623022164 0ustar jmstaff00000000000000This is a test hidden page ########################## :status: hidden The quick brown fox jumped over the lazy dog's back. This page is hidden pelican-3.3/pelican/tests/TestPages/hidden_page_markdown.md0000666000076500000240000000034712130377623023666 0ustar jmstaff00000000000000title: This is a markdown test hidden page status: hidden Test Markdown File Header ========================= Used for pelican test --------------------- The quick brown fox jumped over the lazy dog's back. This page is hidden pelican-3.3/pelican/tests/TestPages/hidden_page_with_template.rst0000666000076500000240000000041612130377623025117 0ustar jmstaff00000000000000This is a test hidden page with a custom template ################################################# :status: hidden :template: custom The quick brown fox jumped over the lazy dog's back. This page is hidden This page has a custom template to be called when rendered pelican-3.3/pelican/tests/TestPages/page.rst0000666000076500000240000000013612130377623020655 0ustar jmstaff00000000000000This is a test page ################### The quick brown fox jumped over the lazy dog's back. pelican-3.3/pelican/tests/TestPages/page_markdown.md0000666000076500000240000000027412130377623022352 0ustar jmstaff00000000000000title: This is a markdown test page Test Markdown File Header ========================= Used for pelican test --------------------- The quick brown fox jumped over the lazy dog's back. pelican-3.3/pelican/tests/TestPages/page_with_template.rst0000666000076500000240000000033612130377623023605 0ustar jmstaff00000000000000This is a test page with a preset template ########################################## :template: custom The quick brown fox jumped over the lazy dog's back. This article has a custom template to be called when rendered pelican-3.3/pelican/themes/0000755000076500000240000000000012220367225015424 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/notmyidea/0000755000076500000240000000000012220367225017415 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/notmyidea/static/0000755000076500000240000000000012220367225020704 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/notmyidea/static/css/0000755000076500000240000000000012220367225021474 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/notmyidea/static/css/main.css0000666000076500000240000002531012171064114023133 0ustar jmstaff00000000000000/* Name: Smashing HTML5 Date: July 2009 Description: Sample layout for HTML5 and CSS3 goodness. Version: 1.0 License: MIT Licensed by: Smashing Media GmbH Original author: Enrique Ramírez */ /* Imports */ @import url("reset.css"); @import url("pygment.css"); @import url("typogrify.css"); @import url(//fonts.googleapis.com/css?family=Yanone+Kaffeesatz&subset=latin); /***** Global *****/ /* Body */ body { background: #F5F4EF; color: #000305; font-size: 87.5%; /* Base font size: 14px */ font-family: 'Trebuchet MS', Trebuchet, 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif; line-height: 1.429; margin: 0; padding: 0; text-align: left; } /* Headings */ h1 {font-size: 2em } h2 {font-size: 1.571em} /* 22px */ h3 {font-size: 1.429em} /* 20px */ h4 {font-size: 1.286em} /* 18px */ h5 {font-size: 1.143em} /* 16px */ h6 {font-size: 1em} /* 14px */ h1, h2, h3, h4, h5, h6 { font-weight: 400; line-height: 1.1; margin-bottom: .8em; font-family: 'Yanone Kaffeesatz', arial, serif; } h3, h4, h5, h6 { margin-top: .8em; } hr { border: 2px solid #EEEEEE; } /* Anchors */ a {outline: 0;} a img {border: 0px; text-decoration: none;} a:link, a:visited { color: #C74350; padding: 0 1px; text-decoration: underline; } a:hover, a:active { background-color: #C74350; color: #fff; text-decoration: none; text-shadow: 1px 1px 1px #333; } h1 a:hover { background-color: inherit } /* Paragraphs */ div.line-block, p { margin-top: 1em; margin-bottom: 1em;} strong, b {font-weight: bold;} em, i {font-style: italic;} /* Lists */ ul { list-style: outside disc; margin: 0em 0 0 1.5em; } ol { list-style: outside decimal; margin: 0em 0 0 1.5em; } li { margin-top: 0.5em;} .post-info { float:right; margin:10px; padding:5px; } .post-info p{ margin-top: 1px; margin-bottom: 1px; } .readmore { float: right } dl {margin: 0 0 1.5em 0;} dt {font-weight: bold;} dd {margin-left: 1.5em;} pre{background-color: rgb(238, 238, 238); padding: 10px; margin: 10px; overflow: auto;} /* Quotes */ blockquote { margin: 20px; font-style: italic; } cite {} q {} div.note { float: right; margin: 5px; font-size: 85%; max-width: 300px; } /* Tables */ table {margin: .5em auto 1.5em auto; width: 98%;} /* Thead */ thead th {padding: .5em .4em; text-align: left;} thead td {} /* Tbody */ tbody td {padding: .5em .4em;} tbody th {} tbody .alt td {} tbody .alt th {} /* Tfoot */ tfoot th {} tfoot td {} /* HTML5 tags */ header, section, footer, aside, nav, article, figure { display: block; } /***** Layout *****/ .body {clear: both; margin: 0 auto; width: 800px;} img.right, figure.right {float: right; margin: 0 0 2em 2em;} img.left, figure.left {float: left; margin: 0 2em 2em 0;} /* Header *****************/ #banner { margin: 0 auto; padding: 2.5em 0 0 0; } /* Banner */ #banner h1 {font-size: 3.571em; line-height: 0;} #banner h1 a:link, #banner h1 a:visited { color: #000305; display: block; font-weight: bold; margin: 0 0 .6em .2em; text-decoration: none; } #banner h1 a:hover, #banner h1 a:active { background: none; color: #C74350; text-shadow: none; } #banner h1 strong {font-size: 0.36em; font-weight: normal;} /* Main Nav */ #banner nav { background: #000305; font-size: 1.143em; height: 40px; line-height: 30px; margin: 0 auto 2em auto; padding: 0; text-align: center; width: 800px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #banner nav ul {list-style: none; margin: 0 auto; width: 800px;} #banner nav li {float: left; display: inline; margin: 0;} #banner nav a:link, #banner nav a:visited { color: #fff; display: inline-block; height: 30px; padding: 5px 1.5em; text-decoration: none; } #banner nav a:hover, #banner nav a:active, #banner nav .active a:link, #banner nav .active a:visited { background: #C74451; color: #fff; text-shadow: none !important; } #banner nav li:first-child a { border-top-left-radius: 5px; -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; } /* Featured *****************/ #featured { background: #fff; margin-bottom: 2em; overflow: hidden; padding: 20px; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #featured figure { border: 2px solid #eee; float: right; margin: 0.786em 2em 0 5em; width: 248px; } #featured figure img {display: block; float: right;} #featured h2 {color: #C74451; font-size: 1.714em; margin-bottom: 0.333em;} #featured h3 {font-size: 1.429em; margin-bottom: .5em;} #featured h3 a:link, #featured h3 a:visited {color: #000305; text-decoration: none;} #featured h3 a:hover, #featured h3 a:active {color: #fff;} /* Body *****************/ #content { background: #fff; margin-bottom: 2em; overflow: hidden; padding: 20px 20px; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } /* Extras *****************/ #extras {margin: 0 auto 3em auto; overflow: hidden;} #extras ul {list-style: none; margin: 0;} #extras li {border-bottom: 1px solid #fff;} #extras h2 { color: #C74350; font-size: 1.429em; margin-bottom: .25em; padding: 0 3px; } #extras a:link, #extras a:visited { color: #444; display: block; border-bottom: 1px solid #F4E3E3; text-decoration: none; padding: .3em .25em; } #extras a:hover, #extras a:active {color: #fff;} /* Blogroll */ #extras .blogroll { float: left; width: 615px; } #extras .blogroll li {float: left; margin: 0 20px 0 0; width: 185px;} /* Social */ #extras .social { float: right; width: 175px; } #extras div[class='social'] a { background-repeat: no-repeat; background-position: 3px 6px; padding-left: 25px; } /* Icons */ .social a[href*='about.me'] {background-image: url('../images/icons/aboutme.png');} .social a[href*='bitbucket.org'] {background-image: url('../images/icons/bitbucket.png');} .social a[href*='delicious.com'] {background-image: url('../images/icons/delicious.png');} .social a[href*='digg.com'] {background-image: url('../images/icons/digg.png');} .social a[href*='facebook.com'] {background-image: url('../images/icons/facebook.png');} .social a[href*='gitorious.org'] {background-image: url('../images/icons/gitorious.png');} .social a[href*='github.com'], .social a[href*='git.io'] {background-image: url('../images/icons/github.png');} .social a[href*='gittip.com'] {background-image: url('../images/icons/gittip.png');} .social a[href*='plus.google.com'] {background-image: url('../images/icons/google-plus.png');} .social a[href*='groups.google.com'] {background-image: url('../images/icons/google-groups.png');} .social a[href*='news.ycombinator.com'], .social a[href*='hackernewsers.com'] {background-image: url('../images/icons/hackernews.png');} .social a[href*='last.fm'], .social a[href*='lastfm.'] {background-image: url('../images/icons/lastfm.png');} .social a[href*='linkedin.com'] {background-image: url('../images/icons/linkedin.png');} .social a[href*='reddit.com'] {background-image: url('../images/icons/reddit.png');} .social a[type$='atom+xml'], .social a[type$='rss+xml'] {background-image: url('../images/icons/rss.png');} .social a[href*='slideshare.net'] {background-image: url('../images/icons/slideshare.png');} .social a[href*='speakerdeck.com'] {background-image: url('../images/icons/speakerdeck.png');} .social a[href*='stackoverflow.com'] {background-image: url('../images/icons/stackoverflow.png');} .social a[href*='twitter.com'] {background-image: url('../images/icons/twitter.png');} .social a[href*='vimeo.com'] {background-image: url('../images/icons/vimeo.png');} .social a[href*='youtube.com'] {background-image: url('../images/icons/youtube.png');} /* About *****************/ #about { background: #fff; font-style: normal; margin-bottom: 2em; overflow: hidden; padding: 20px; text-align: left; width: 760px; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #about .primary {float: left; width: 165px;} #about .primary strong {color: #C64350; display: block; font-size: 1.286em;} #about .photo {float: left; margin: 5px 20px;} #about .url:link, #about .url:visited {text-decoration: none;} #about .bio {float: right; width: 500px;} /* Footer *****************/ #contentinfo {padding-bottom: 2em; text-align: right;} /***** Sections *****/ /* Blog */ .hentry { display: block; clear: both; border-bottom: 1px solid #eee; padding: 1.5em 0; } li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} #content > .hentry {padding: 1em 0;} .hentry img{display : none ;} .entry-title {font-size: 3em; margin-bottom: 10px; margin-top: 0;} .entry-title a:link, .entry-title a:visited {text-decoration: none; color: #333;} .entry-title a:visited {background-color: #fff;} .hentry .post-info * {font-style: normal;} /* Content */ .hentry footer {margin-bottom: 2em;} .hentry footer address {display: inline;} #posts-list footer address {display: block;} /* Blog Index */ #posts-list {list-style: none; margin: 0;} #posts-list .hentry {padding-left: 10px; position: relative;} #posts-list footer { left: 10px; position: relative; float: left; top: 0.5em; width: 190px; } /* About the Author */ #about-author { background: #f9f9f9; clear: both; font-style: normal; margin: 2em 0; padding: 10px 20px 15px 20px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #about-author strong { color: #C64350; clear: both; display: block; font-size: 1.429em; } #about-author .photo {border: 1px solid #ddd; float: left; margin: 5px 1em 0 0;} /* Comments */ #comments-list {list-style: none; margin: 0 1em;} #comments-list blockquote { background: #f8f8f8; clear: both; font-style: normal; margin: 0; padding: 15px 20px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #comments-list footer {color: #888; padding: .5em 1em 0 0; text-align: right;} #comments-list li:nth-child(2n) blockquote {background: #F5f5f5;} /* Add a Comment */ #add-comment label {clear: left; float: left; text-align: left; width: 150px;} #add-comment input[type='text'], #add-comment input[type='email'], #add-comment input[type='url'] {float: left; width: 200px;} #add-comment textarea {float: left; height: 150px; width: 495px;} #add-comment p.req {clear: both; margin: 0 .5em 1em 0; text-align: right;} #add-comment input[type='submit'] {float: right; margin: 0 .5em;} #add-comment * {margin-bottom: .5em;} pelican-3.3/pelican/themes/notmyidea/static/css/pygment.css0000644000076500000240000000345212057161060023672 0ustar jmstaff00000000000000.hll { background-color:#eee; } .c { color:#408090; font-style:italic; } .err { border:1px solid #FF0000; } .k { color:#007020; font-weight:bold; } .o { color:#666666; } .cm { color:#408090; font-style:italic; } .cp { color:#007020; } .c1 { color:#408090; font-style:italic; } .cs { background-color:#FFF0F0; color:#408090; } .gd { color:#A00000; } .ge { font-style:italic; } .gr { color:#FF0000; } .gh { color:#000080; font-weight:bold; } .gi { color:#00A000; } .go { color:#303030; } .gp { color:#C65D09; font-weight:bold; } .gs { font-weight:bold; } .gu { color:#800080; font-weight:bold; } .gt { color:#0040D0; } .kc { color:#007020; font-weight:bold; } .kd { color:#007020; font-weight:bold; } .kn { color:#007020; font-weight:bold; } .kp { color:#007020; } .kr { color:#007020; font-weight:bold; } .kt { color:#902000; } .m { color:#208050; } .s { color:#4070A0; } .na { color:#4070A0; } .nb { color:#007020; } .nc { color:#0E84B5; font-weight:bold; } .no { color:#60ADD5; } .nd { color:#555555; font-weight:bold; } .ni { color:#D55537; font-weight:bold; } .ne { color:#007020; } .nf { color:#06287E; } .nl { color:#002070; font-weight:bold; } .nn { color:#0E84B5; font-weight:bold; } .nt { color:#062873; font-weight:bold; } .nv { color:#BB60D5; } .ow { color:#007020; font-weight:bold; } .w { color:#BBBBBB; } .mf { color:#208050; } .mh { color:#208050; } .mi { color:#208050; } .mo { color:#208050; } .sb { color:#4070A0; } .sc { color:#4070A0; } .sd { color:#4070A0; font-style:italic; } .s2 { color:#4070A0; } .se { color:#4070A0; font-weight:bold; } .sh { color:#4070A0; } .si { color:#70A0D0; font-style:italic; } .sx { color:#C65D09; } .sr { color:#235388; } .s1 { color:#4070A0; } .ss { color:#517918; } .bp { color:#007020; } .vc { color:#BB60D5; } .vg { color:#BB60D5; } .vi { color:#BB60D5; } .il { color:#208050; } pelican-3.3/pelican/themes/notmyidea/static/css/reset.css0000644000076500000240000000211712036016606023330 0ustar jmstaff00000000000000/* Name: Reset Stylesheet Description: Resets browser's default CSS Author: Eric Meyer Author URI: http://meyerweb.com/eric/tools/css/reset/ */ /* v1.0 | 20080212 */ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { background: transparent; border: 0; font-size: 100%; margin: 0; outline: 0; padding: 0; vertical-align: baseline; } body {line-height: 1;} ol, ul {list-style: none;} blockquote, q {quotes: none;} blockquote:before, blockquote:after, q:before, q:after { content: ''; content: none; } /* remember to define focus styles! */ :focus { outline: 0; } /* remember to highlight inserts somehow! */ ins {text-decoration: none;} del {text-decoration: line-through;} /* tables still need 'cellspacing="0"' in the markup */ table { border-collapse: collapse; border-spacing: 0; }pelican-3.3/pelican/themes/notmyidea/static/css/typogrify.css0000644000076500000240000000027612036016606024246 0ustar jmstaff00000000000000.caps {font-size:.92em;} .amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;} .dquo {margin-left:-.38em;} pelican-3.3/pelican/themes/notmyidea/static/css/wide.css0000644000076500000240000000115012036016606023132 0ustar jmstaff00000000000000@import url("main.css"); body { font:1.3em/1.3 "Hoefler Text","Georgia",Georgia,serif,sans-serif; } .post-info{ display: none; } #banner nav { display: none; -moz-border-radius: 0px; margin-bottom: 20px; overflow: hidden; font-size: 1em; background: #F5F4EF; } #banner nav ul{ padding-right: 50px; } #banner nav li{ float: right; color: #000; } #banner nav li a { color: #000; } #banner h1 { margin-bottom: -18px; } #featured, #extras { padding: 50px; } #featured { padding-top: 20px; } #extras { padding-top: 0px; padding-bottom: 0px; } pelican-3.3/pelican/themes/notmyidea/static/images/0000755000076500000240000000000012220367225022151 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/notmyidea/static/images/icons/0000755000076500000240000000000012220367225023264 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/notmyidea/static/images/icons/aboutme.png0000666000076500000240000000135712132103620025425 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ< PLTE >b :\a``__^][XNz 8Y]\\ZZXVS Js Ch 6UXXWVUTRQ~N{ Lw El @d4S P} O| Nz Mx Lw Ku Js Hq Fn Ek @e >a2O Mw3 Ip Dj Bg >a <]0L Hp Ho Gn Bg Cg;]9Y ;[.I Dk :ZAf 7U=_0K,F@e(>=_%:6U"4*D2O'@/K &=-G#:*D!7(@4%=1k/tRNS@f pHYsHHFk>IDATURPEcJP t(P)RcB]7p $YpܪHWUU?9'g^DXz&[|y6:dd#'r7_4L˚7L?`ZW|;h%tEXtdate:create2013-03-15T18:16:20-07:00#6%tEXtdate:modify2013-03-15T18:16:16-07:00SIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/bitbucket.png0000666000076500000240000000720212132103620025740 0ustar jmstaff00000000000000PNG  IHDRh6 AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ pHYs  niTXtXML:com.adobe.xmp ? AmIDAT(ERkAtIݐۤ?jִPЖRD {$xP"1FlҺ>t GTЂ}FD%BdD,>[ēPR@+*ȌFՍJpL +x~,*p*K$ћBJ{iqne6;Ĉv}vpn`k KӲW7ͅ'tՅ |ZWotL,(w,}+WҩP8d״ˍJsP\ C$IAk筕sGt*JB\׆\08Sֿ#/9bSs\&_t@z8vIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/delicious.png0000644000076500000240000000167612132103620025751 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zcIDAT8ou}Kn6IKb*K D(B1/ 1Ll,t@JtCDڦIIS׉o{}yX,Vq#jKZxwv~}z;mgӃ`ڮfOk̙{~5޻~~n4i3/}{׃g½cW=>֚./}p B:m&tkJFLi_ ?ԓIrR "&bi?3$bZ)Hէڲ @8L !:(NDm2yqrK)I%dCesG J) ?ϧJ>2pF> 6`CAsJﳽG7qG52/}Cca@\Ş.M[9rʲ W*YR=*;{"""H$""_}47u6wD*x~8Q3̱P!L4֖j$FH|q  ƾJg0.q!`x@0^5"1"`E^'81ZB`0Kׯh'a.W Ox^8G,b89.~/T+^`c`j )efЩ2},W${{b1}x'mmnko}w㰻u`}?=}yf;wZ?W.72 䭘fIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/facebook.png0000644000076500000240000000031212132103620025524 0ustar jmstaff00000000000000PNG  IHDRRPLTE;Y;Y`xEbmgtRNSACbKGDH pHYsHHFk>=IDATc`F%0``0 e C%P RBeBT\Cp0K 0ef>IENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/github.png0000644000076500000240000000053212132103620025241 0ustar jmstaff00000000000000PNG  IHDRa pHYs  ~ IDAT8˕ӱJa VVB*A>m [[_*  MTl&.Og!hhr7"nq\r &0E,]3m+xLQ>嶝9y`C_ N]kEN!7 g-.@iF6XN_0J > 2#z okm|<˲U,,pt*+X4NO7m9KIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/gitorious.png0000644000076500000240000000034312132103620026003 0ustar jmstaff00000000000000PNG  IHDR(-SLbIDAT}1 % h#"#M 홴z)} .?_"{B4!>}HVU8T% )mu CbD, F IIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/gittip.png0000644000076500000240000000074712132103620025267 0ustar jmstaff00000000000000PNG  IHDRasRGBbKGD pHYs  tIME  mgIDAT8c`o0cm=H_P| *0CF`1d=6_LԄj.d*LsHg#MM@v7S!0lÕs' m`=-oqEv 4plٰl$.4g4ܴb)f ā@,`.&@yjB P q7!UA?~p11?FhhDd"EDm j4'$MOH(I%^V8ǟ)LfgoǑXIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/google-groups.png0000666000076500000240000000144312132103620026556 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<5PLTE,r#bFEB@>=:875}3{1zDB@<7~4|CA>=986~?>6~4|2{1x>2z0x=98;9/w1y0w2{.v3|.uʡ-ṭ,s+qtRNS}abKGD-IDAT5y[QW-q̄13p}(B/繞j;.{`(E( )-O$9dAL#B /$Jryu]Bpp2OiR.;7EBpNb>cã}%bP}fC}(,ggxE)_Oz70Yn`-:9@ 3$%ts%tEXtdate:create2013-01-13T02:11:01-08:00̕%tEXtdate:modify2013-01-13T02:10:36-08:00&zIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/google-plus.png0000644000076500000240000000101712132103620026213 0ustar jmstaff00000000000000PNG  IHDRh6IDAT(cmIbeq&nt9@ A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ pHYs  niTXtXML:com.adobe.xmp ? AIDAT8cD^V4?PAuLU?7g0arp m3Fpu06L.d s`]8bw3lfd ьP#<= Is aLd6\<(A_&#Ft6ab/$eqoIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/lastfm.png0000644000076500000240000000171712132103620025253 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zc(IDAT8OlU{v6*U(D Qc@#'ăO=sp1 ϩD--4Pv{??=~.KxNyfƤTH'*"1֮Br:i$k.>7HXy?؁s(I HrwL.Ig~ Ig9R  (%c5y@F6CH,D ? N6(!cQ6{dPȡpsJ0j0e$pNU.x " 8zZ^5˫3uh`{#at0:Nh`/F1%쑔}#l̮qo2^'#rxqS'ɽshb@c;2I~7;{U,J,yoɾq[ bYBE2'y:fIMw.);#,8vmJK"",7%KRd'""6Q,yJ泓'w>׍j﯒ܹ.P.3_XDz]e?n g_)G_{!bGժԡhvdKAg^䋅kwЕ!dOCPY.cЉ#[{AbXM~bѻD\k-3rUe<$7V%-e?O=k;ʆQFxD0UmTgjzϯ|psO?ϕsݪCIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/linkedin.png0000644000076500000240000000160012132103620025551 0ustar jmstaff00000000000000PNG  IHDR(-S7PLTEhiklklmmoommnnoonopqoqprrpqstsutv vw w v w y yx y yy { {zzzz{|{|~ !"#$%&',-21223E9:9::<=~^|^X۳~#rӯ#"{:(#u;p )*R)j NA^AT kk1HgO\(vo84QImÏY`e)S IENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/reddit.png0000666000076500000240000000126512132103620025242 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<PLTER[eeq}bjsdeg|_ju_lz`][JNSiup|VZ^ߍy)/6w]dknyo~djm{[aflpv><:w{qpoGGG20nprS\eɨFJNˁ~~~U^gjklգxgscmx6 pHYsHHFk>IDATePﵻ;X("6蠎s!/^`4-V-r{>]44"O$S > b\8!Vo4[xj65Bڝ.z6!0'c`4ԢS|j|,sMō6spy /R1$ DBTr\ߤ0^|xfNܸ !bT S<~C# %g;$/)QEuM"I`^~.:%n課~| wV :&15R§w 3OPvmd)$ỵ_%YBڶȦ3_JndW|Ui#5Lf:JS8d$7ԈPwɸ^?3u}ȜmEfS쮉 A*bk;K/T1UcDjVz_3:T80}wNpJɠAke,}:{m;?[/4E5[񮺱馕ny'}^8+` x<IENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/slideshare.png0000666000076500000240000000102712132103620026106 0ustar jmstaff00000000000000PNG  IHDR(-SPLTEâz既d{o˦K>dHk;}unw;97o&wE4fpA,]_z|r]+,$zqfmaHtRNS-)IDATNP^oea01Hc\iGL89qM,n$$LzROQ ]vgchKl#u_וb?oQܔ! . k;GW/ JD44!9ԛIENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/speakerdeck.png0000666000076500000240000000203112132103620026240 0ustar jmstaff00000000000000PNG  IHDR(-SgAMA asRGB cHRMz&u0`:pQ<PLTE9,2tU7]6~\6\7]3uU.qSF~G/qS.vW(qS(pS#kO"jNeKdK_I`I[GXFXETDQCOAMAM@K@I?H?I@A;`VaVB;$!F@F@E??|>{>{@|?{?|;x7u6u6u6t7v;y6u4s3r3q3r4s2r/o0p0q1q,m,l*i*h*g)g)g)f+j,m)j'f\FP>O<VCYGUCN<\F(g%g#bM<K3A7Dd]@d\Ed^A8 =2G:|bv_r\^MXHXHUEUFVGVF_Ns]o\n[p\o\o[n[hXgXgWgXfWfWhYbVaU`T `TcV^U ]U ]T ]S \SǶ(tRNS{{m pHYsHHFk> IDATc``dbfaef&6v M-m]-mN.n=}}C}C#c}nS333s KKKs+3+S^>k[ "[{~G'gWW77wgOA!/o_? /aаȨظ$Դ̬d1¢⒒ҲJqںƦ*Iֶ֎ֶήVi }d&MIDATHT;H+A3;dU (AĀ [(#l"Z GVjaF% PPD$dd;!Oŧ»a̜{a|exc)]^ Cnw4LrtW ݛ&ơ_(r:_6ndkcTRgR@@ W>Ez8>8;0Gi!D)c oԌ󳢌vu qÍeGi|ee.'F_ `l!XE|v TՍ BfgE㹻BHr9!R}Aq==E"T[kO` cR)t] Tt]Υ[JK eYL@J)憳WW$oo׽ssD6{yrUUe##V+!>5c`LmߗM`?ZZLbRJ(eLI4fRBU֦iU.! d2vN3qGg;;!!Ðee]7 !qE'`0dw$ jQ盛 hכl ''PO5(6V\Q(u>~ [e(~@~;IɅT%tEXtdate:create2013-07-03T22:30:09-07:001D%tEXtdate:modify2013-07-01T14:56:54-07:00IENDB`pelican-3.3/pelican/themes/notmyidea/static/images/icons/twitter.png0000644000076500000240000000147612132103620025471 0ustar jmstaff00000000000000PNG  IHDRasBIT|d pHYs  ~tEXtSoftwareAdobe Fireworks CS4ӠtEXtCreation Time20/7/09zcIDAT8Kk]U߻D :;8ळE*"A/ M/i^2n$J) Qe var _gaq = _gaq || []; _gaq.push(['_setAccount', '{{GOOGLE_ANALYTICS}}']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); {% endif %} {% if GAUGES %} {% endif %} pelican-3.3/pelican/themes/notmyidea/templates/archives.html0000644000076500000240000000047312036016606024110 0ustar jmstaff00000000000000{% extends "base.html" %} {% block content %}

    Archives for {{ SITENAME }}

    {% for article in dates %}
    {{ article.locale_date }}
    {{ article.title }}
    {% endfor %}
    {% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/article.html0000666000076500000240000000234612130377623023740 0ustar jmstaff00000000000000{% extends "base.html" %} {% block title %}{{ article.title|striptags }}{% endblock %} {% block content %}

    {{ article.title}}

    {% include 'twitter.html' %}
    {% include 'article_infos.html' %} {{ article.content }}
    {% if DISQUS_SITENAME and SITEURL and article.status != "draft" %}

    Comments !

    {% endif %}
    {% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/article_infos.html0000644000076500000240000000133312057161060025117 0ustar jmstaff00000000000000
    {{ article.locale_date }} {% if article.author %}
    By {{ article.author }}
    {% endif %}

    In {{ article.category }}. {% if PDF_PROCESSOR %}get the pdf{% endif %}

    {% include 'taglist.html' %} {% import 'translations.html' as translations with context %} {{ translations.translations_for(article) }}
    pelican-3.3/pelican/themes/notmyidea/templates/author.html0000644000076500000240000000013012036016606023574 0ustar jmstaff00000000000000{% extends "index.html" %} {% block title %}{{ SITENAME }} - {{ author }}{% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/authors.html0000644000076500000240000000056312200765023023766 0ustar jmstaff00000000000000{% extends "base.html" %} {% block title %}{{ SITENAME }} - Authors{% endblock %} {% block content %}

    Authors on {{ SITENAME }}

    {%- for author, articles in authors|sort %}
  • {{ author }} ({{ articles|count }})
  • {% endfor %}
    {% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/base.html0000644000076500000240000000736012215535610023220 0ustar jmstaff00000000000000 {% block title %}{{ SITENAME }}{%endblock%} {% if FEED_ALL_ATOM %} {% endif %} {% if FEED_ALL_RSS %} {% endif %} {% include 'github.html' %} {% block content %} {% endblock %}
    {% if LINKS %}

    blogroll

      {% for name, link in LINKS %}
    • {{ name }}
    • {% endfor %}
    {% endif %} {% if SOCIAL or FEED_ALL_ATOM or FEED_ALL_RSS %} {% endif %}
    {% include 'analytics.html' %} {% include 'piwik.html' %} {% include 'disqus_script.html' %} pelican-3.3/pelican/themes/notmyidea/templates/category.html0000644000076500000240000000013212036016606024111 0ustar jmstaff00000000000000{% extends "index.html" %} {% block title %}{{ SITENAME }} - {{ category }}{% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/comments.html0000644000076500000240000000017212036016606024125 0ustar jmstaff00000000000000{% if DISQUS_SITENAME %}

    There are comments.

    {% endif %} pelican-3.3/pelican/themes/notmyidea/templates/disqus_script.html0000644000076500000240000000067412036016606025203 0ustar jmstaff00000000000000{% if DISQUS_SITENAME %} {% endif %} pelican-3.3/pelican/themes/notmyidea/templates/github.html0000644000076500000240000000067712036016606023574 0ustar jmstaff00000000000000{% if GITHUB_URL %} {% if GITHUB_POSITION != "left" %} Fork me on GitHub {% else %} Fork me on GitHub {% endif %} {% endif %} pelican-3.3/pelican/themes/notmyidea/templates/index.html0000644000076500000240000000465312177737636023442 0ustar jmstaff00000000000000{% extends "base.html" %} {% block content_title %}{% endblock %} {% block content %} {% if articles %} {% for article in articles_page.object_list %} {# First item #} {% if loop.first and not articles_page.has_previous() %} {% if loop.length > 1 %}

    Other articles


      {% endif %} {# other items #} {% else %} {% if loop.first and articles_page.has_previous %}
        {% endif %}
      1. {% endif %} {% if loop.last %}
      {% if loop.last and (articles_page.has_previous() or not articles_page.has_previous() and loop.length > 1) %} {% include 'pagination.html' %} {% endif %}
      {% endif %} {% endfor %} {% else %}

      Pages

      {% for page in PAGES %}
    1. {{ page.title }}
    2. {% endfor %}
      {% endif %} {% endblock content %} pelican-3.3/pelican/themes/notmyidea/templates/page.html0000644000076500000240000000067612177737636023250 0ustar jmstaff00000000000000{% extends "base.html" %} {% block title %}{{ page.title }}{% endblock %} {% block content %}

      {{ page.title }}

      {% import 'translations.html' as translations with context %} {{ translations.translations_for(page) }} {% if PDF_PROCESSOR %}get the pdf{% endif %} {{ page.content }}
      {% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/piwik.html0000644000076500000240000000131412215535610023422 0ustar jmstaff00000000000000{% if PIWIK_URL and PIWIK_SITE_ID %} {% endif %} pelican-3.3/pelican/themes/notmyidea/templates/tag.html0000644000076500000240000000012512036016606023051 0ustar jmstaff00000000000000{% extends "index.html" %} {% block title %}{{ SITENAME }} - {{ tag }}{% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/taglist.html0000644000076500000240000000036512036016606023753 0ustar jmstaff00000000000000{% if article.tags %}

      tags: {% for tag in article.tags %}{{ tag }}{% endfor %}

      {% endif %} {% if PDF_PROCESSOR %}

      get the pdf

      {% endif %} pelican-3.3/pelican/themes/notmyidea/templates/tags.html0000644000076500000240000000054212200765023023234 0ustar jmstaff00000000000000{% extends "base.html" %} {% block title %}{{ SITENAME }} - Tags{% endblock %} {% block content %}

      Tags for {{ SITENAME }}

      {%- for tag, articles in tags|sort %}
    3. {{ tag }} ({{ articles|count }})
    4. {% endfor %}
      {% endblock %} pelican-3.3/pelican/themes/notmyidea/templates/translations.html0000644000076500000240000000040112177737636025037 0ustar jmstaff00000000000000{% macro translations_for(article) %} {% if article.translations %} Translations: {% for translation in article.translations %} {{ translation.lang }} {% endfor %} {% endif %} {% endmacro %} pelican-3.3/pelican/themes/notmyidea/templates/twitter.html0000644000076500000240000000037412036016606024006 0ustar jmstaff00000000000000{% if TWITTER_USERNAME %} {% endif %}pelican-3.3/pelican/themes/simple/0000755000076500000240000000000012220367225016715 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/simple/templates/0000755000076500000240000000000012220367225020713 5ustar jmstaff00000000000000pelican-3.3/pelican/themes/simple/templates/archives.html0000644000076500000240000000041412036016606023403 0ustar jmstaff00000000000000{% extends "base.html" %} {% block content %}

      Archives for {{ SITENAME }}

      {% for article in dates %}
      {{ article.locale_date }}
      {{ article.title }}
      {% endfor %}
      {% endblock %} pelican-3.3/pelican/themes/simple/templates/article.html0000644000076500000240000000231612215535610023225 0ustar jmstaff00000000000000{% extends "base.html" %} {% block head %} {% for keyword in article.keywords %} {% endfor %} {% for description in article.description %} {% endfor %} {% for tag in article.tags %} {% endfor %} {% endblock %} {% block content %}

      {{ article.title }}

      {% import 'translations.html' as translations with context %} {{ translations.translations_for(article) }}
      {{ article.content }}
      {% endblock %} pelican-3.3/pelican/themes/simple/templates/author.html0000644000076500000240000000026112036016606023101 0ustar jmstaff00000000000000{% extends "index.html" %} {% block title %}{{ SITENAME }} - Articles by {{ author }}{% endblock %} {% block content_title %}

      Articles by {{ author }}

      {% endblock %} pelican-3.3/pelican/themes/simple/templates/authors.html0000644000076500000240000000050112200765023023256 0ustar jmstaff00000000000000{% extends "base.html" %} {% block title %}{{ SITENAME }} - Authors{% endblock %} {% block content %}

      Authors on {{ SITENAME }}

      {%- for author, articles in authors|sort %}
    5. {{ author }} ({{ articles|count }})
    6. {% endfor %} {% endblock %} pelican-3.3/pelican/themes/simple/templates/base.html0000666000076500000240000000623512130377623022530 0ustar jmstaff00000000000000 {% block head %} {% block title %}{{ SITENAME }}{% endblock title %} {% if FEED_ALL_ATOM %} {% endif %} {% if FEED_ALL_RSS %} {% endif %} {% if FEED_ATOM %} {% endif %} {% if FEED_RSS %} {% endif %} {% if CATEGORY_FEED_ATOM and category %} {% endif %} {% if CATEGORY_FEED_RSS and category %} {% endif %} {% if TAG_FEED_ATOM and tag %} {% endif %} {% if TAG_FEED_RSS and tag %} {% endif %} {% endblock head %} {% block content %} {% endblock %}
      Proudly powered by Pelican, which takes great advantage of Python.
      pelican-3.3/pelican/themes/simple/templates/categories.html0000644000076500000240000000031312036016606023722 0ustar jmstaff00000000000000{% extends "base.html" %} {% block content %}
        {% for category, articles in categories %}
      • {{ category }}
      • {% endfor %}
      {% endblock %} pelican-3.3/pelican/themes/simple/templates/category.html0000644000076500000240000000016612036016606023420 0ustar jmstaff00000000000000{% extends "index.html" %} {% block content_title %}

      Articles in the {{ category }} category

      {% endblock %} pelican-3.3/pelican/themes/simple/templates/gosquared.html0000644000076500000240000000112612036016606023572 0ustar jmstaff00000000000000{% if GOSQUARED_SITENAME %} {% endif %} pelican-3.3/pelican/themes/simple/templates/index.html0000644000076500000240000000205712057161060022711 0ustar jmstaff00000000000000{% extends "base.html" %} {% block content %}
      {% block content_title %}

      All articles

      {% endblock %}
        {% for article in articles_page.object_list %}
      1. {% endfor %}
      {% include 'pagination.html' %}
      {% endblock content %} pelican-3.3/pelican/themes/simple/templates/page.html0000644000076500000240000000042112057161060022507 0ustar jmstaff00000000000000{% extends "base.html" %} {% block title %}{{ page.title }}{%endblock%} {% block content %}

      {{ page.title }}

      {% import 'translations.html' as translations with context %} {{ translations.translations_for(page) }} {{ page.content }} {% endblock %} pelican-3.3/pelican/themes/simple/templates/pagination.html0000644000076500000240000000062212177737636023754 0ustar jmstaff00000000000000{% if DEFAULT_PAGINATION %}

      {% if articles_page.has_previous() %} « {% endif %} Page {{ articles_page.number }} / {{ articles_paginator.num_pages }} {% if articles_page.has_next() %} » {% endif %}

      {% endif %} pelican-3.3/pelican/themes/simple/templates/tag.html0000644000076500000240000000000012036016606022341 0ustar jmstaff00000000000000pelican-3.3/pelican/themes/simple/templates/tags.html0000644000076500000240000000046012200765023022533 0ustar jmstaff00000000000000{% extends "base.html" %} {% block title %}{{ SITENAME }} - Tags{% endblock %} {% block content %}

      Tags for {{ SITENAME }}

      {%- for tag, articles in tags|sort %}
    7. {{ tag }} ({{ articles|count }})
    8. {% endfor %} {% endblock %} pelican-3.3/pelican/themes/simple/templates/translations.html0000644000076500000240000000036312057161060024321 0ustar jmstaff00000000000000{% macro translations_for(article) %} {% if article.translations %} Translations: {% for translation in article.translations %} {{ translation.lang }} {% endfor %} {% endif %} {% endmacro %} pelican-3.3/pelican/tools/0000755000076500000240000000000012220367225015277 5ustar jmstaff00000000000000pelican-3.3/pelican/tools/__init__.py0000644000076500000240000000000012036016606017375 0ustar jmstaff00000000000000pelican-3.3/pelican/tools/pelican_import.py0000755000076500000240000006003512177737636020707 0ustar jmstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import argparse try: # py3k import from html.parser import HTMLParser except ImportError: # py2 import from HTMLParser import HTMLParser # NOQA import os import re import subprocess import sys import time import logging from codecs import open from pelican.utils import slugify from pelican.log import init logger = logging.getLogger(__name__) def decode_wp_content(content, br=True): pre_tags = {} if content.strip() == "": return "" content += "\n" if "") last_pre = pre_parts.pop() content = "" pre_index = 0 for pre_part in pre_parts: start = pre_part.find("" content = content + pre_part[0:start] + name pre_index += 1 content = content + last_pre content = re.sub(r'
      \s*
      ', "\n\n", content) allblocks = ('(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|' 'td|th|div|dl|dd|dt|ul|ol|li|pre|select|option|form|' 'map|area|blockquote|address|math|style|p|h[1-6]|hr|' 'fieldset|noscript|samp|legend|section|article|aside|' 'hgroup|header|footer|nav|figure|figcaption|details|' 'menu|summary)') content = re.sub(r'(<' + allblocks + r'[^>]*>)', "\n\\1", content) content = re.sub(r'()', "\\1\n\n", content) # content = content.replace("\r\n", "\n") if " inside object/embed content = re.sub(r'\s*]*)>\s*', "", content) content = re.sub(r'\s*\s*', '', content) # content = re.sub(r'/\n\n+/', '\n\n', content) pgraphs = filter(lambda s: s != "", re.split(r'\n\s*\n', content)) content = "" for p in pgraphs: content = content + "

      " + p.strip() + "

      \n" # under certain strange conditions it could create a P of entirely whitespace content = re.sub(r'

      \s*

      ', '', content) content = re.sub(r'

      ([^<]+)', "

      \\1

      ", content) # don't wrap tags content = re.sub(r'

      \s*(]*>)\s*

      ', "\\1", content) #problem with nested lists content = re.sub(r'

      (', "\\1", content) content = re.sub(r'

      ]*)>', "

      ", content) content = content.replace('

      ', '

      ') content = re.sub(r'

      \s*(]*>)', "\\1", content) content = re.sub(r'(]*>)\s*

      ', "\\1", content) if br: def _preserve_newline(match): return match.group(0).replace("\n", "") content = re.sub(r'/<(script|style).*?<\/\\1>/s', _preserve_newline, content) # optionally make line breaks content = re.sub(r'(?)\s*\n', "
      \n", content) content = content.replace("", "\n") content = re.sub(r'(]*>)\s*
      ', "\\1", content) content = re.sub(r'
      (\s*]*>)', '\\1', content) content = re.sub(r'\n

      ', "

      ", content) if pre_tags: def _multi_replace(dic, string): pattern = r'|'.join(map(re.escape, dic.keys())) return re.sub(pattern, lambda m: dic[m.group()], string) content = _multi_replace(pre_tags, content) return content def wp2fields(xml): """Opens a wordpress XML file, and yield pelican fields""" try: from bs4 import BeautifulSoup except ImportError: error = ('Missing dependency ' '"BeautifulSoup4" and "lxml" required to import Wordpress XML files.') sys.exit(error) with open(xml, encoding='utf-8') as infile: xmlfile = infile.read() soup = BeautifulSoup(xmlfile, "xml") items = soup.rss.channel.findAll('item') for item in items: if item.find('status').string == "publish": try: # Use HTMLParser due to issues with BeautifulSoup 3 title = HTMLParser().unescape(item.title.contents[0]) except IndexError: title = 'No title [%s]' % item.find('post_name').string logger.warn('Post "%s" is lacking a proper title' % title) content = item.find('encoded').string filename = item.find('post_name').string raw_date = item.find('post_date').string date_object = time.strptime(raw_date, "%Y-%m-%d %H:%M:%S") date = time.strftime("%Y-%m-%d %H:%M", date_object) author = item.find('creator').string categories = [cat.string for cat in item.findAll('category', {'domain' : 'category'})] # caturl = [cat['nicename'] for cat in item.find(domain='category')] tags = [tag.string for tag in item.findAll('category', {'domain' : 'post_tag'})] kind = 'article' if item.find('post_type').string == 'page': kind = 'page' yield (title, content, filename, date, author, categories, tags, kind, "wp-html") def dc2fields(file): """Opens a Dotclear export file, and yield pelican fields""" try: from bs4 import BeautifulSoup except ImportError: error = ('Missing dependency ' '"BeautifulSoup4" and "lxml" required to import Dotclear files.') sys.exit(error) in_cat = False in_post = False category_list = {} posts = [] with open(file, 'r', encoding='utf-8') as f: for line in f: # remove final \n line = line[:-1] if line.startswith('[category'): in_cat = True elif line.startswith('[post'): in_post = True elif in_cat: fields = line.split('","') if not line: in_cat = False else: # remove 1st and last "" fields[0] = fields[0][1:] # fields[-1] = fields[-1][:-1] category_list[fields[0]]=fields[2] elif in_post: if not line: in_post = False break else: posts.append(line) print("%i posts read." % len(posts)) for post in posts: fields = post.split('","') # post_id = fields[0][1:] # blog_id = fields[1] # user_id = fields[2] cat_id = fields[3] # post_dt = fields[4] # post_tz = fields[5] post_creadt = fields[6] # post_upddt = fields[7] # post_password = fields[8] # post_type = fields[9] post_format = fields[10] # post_url = fields[11] # post_lang = fields[12] post_title = fields[13] post_excerpt = fields[14] post_excerpt_xhtml = fields[15] post_content = fields[16] post_content_xhtml = fields[17] # post_notes = fields[18] # post_words = fields[19] # post_status = fields[20] # post_selected = fields[21] # post_position = fields[22] # post_open_comment = fields[23] # post_open_tb = fields[24] # nb_comment = fields[25] # nb_trackback = fields[26] post_meta = fields[27] # redirect_url = fields[28][:-1] # remove seconds post_creadt = ':'.join(post_creadt.split(':')[0:2]) author = "" categories = [] tags = [] if cat_id: categories = [category_list[id].strip() for id in cat_id.split(',')] # Get tags related to a post tag = post_meta.replace('{', '').replace('}', '').replace('a:1:s:3:\\"tag\\";a:', '').replace('a:0:', '') if len(tag) > 1: if int(tag[:1]) == 1: newtag = tag.split('"')[1] tags.append( BeautifulSoup( newtag , "xml" ) # bs4 always outputs UTF-8 .decode('utf-8') ) else: i=1 j=1 while(i <= int(tag[:1])): newtag = tag.split('"')[j].replace('\\','') tags.append( BeautifulSoup( newtag , "xml" ) # bs4 always outputs UTF-8 .decode('utf-8') ) i=i+1 if j < int(tag[:1])*2: j=j+2 """ dotclear2 does not use markdown by default unless you use the markdown plugin Ref: http://plugins.dotaddict.org/dc2/details/formatting-markdown """ if post_format == "markdown": content = post_excerpt + post_content else: content = post_excerpt_xhtml + post_content_xhtml content = content.replace('\\n', '') post_format = "html" kind = 'article' # TODO: Recognise pages yield (post_title, content, slugify(post_title), post_creadt, author, categories, tags, kind, post_format) def posterous2fields(api_token, email, password): """Imports posterous posts""" import base64 from datetime import datetime, timedelta try: # py3k import import json except ImportError: # py2 import import simplejson as json try: # py3k import import urllib.request as urllib_request except ImportError: # py2 import import urllib2 as urllib_request def get_posterous_posts(api_token, email, password, page = 1): base64string = base64.encodestring(("%s:%s" % (email, password)).encode('utf-8')).replace(b'\n', b'') url = "http://posterous.com/api/v2/users/me/sites/primary/posts?api_token=%s&page=%d" % (api_token, page) request = urllib_request.Request(url) request.add_header("Authorization", "Basic %s" % base64string.decode()) handle = urllib_request.urlopen(request) posts = json.loads(handle.read().decode('utf-8')) return posts page = 1 posts = get_posterous_posts(api_token, email, password, page) while len(posts) > 0: posts = get_posterous_posts(api_token, email, password, page) page += 1 for post in posts: slug = post.get('slug') if not slug: slug = slugify(post.get('title')) tags = [tag.get('name') for tag in post.get('tags')] raw_date = post.get('display_date') date_object = datetime.strptime(raw_date[:-6], "%Y/%m/%d %H:%M:%S") offset = int(raw_date[-5:]) delta = timedelta(hours = offset / 100) date_object -= delta date = date_object.strftime("%Y-%m-%d %H:%M") kind = 'article' # TODO: Recognise pages yield (post.get('title'), post.get('body_cleaned'), slug, date, post.get('user').get('display_name'), [], tags, kind, "html") def tumblr2fields(api_key, blogname): """ Imports Tumblr posts (API v2)""" from time import strftime, localtime try: # py3k import import json except ImportError: # py2 import import simplejson as json try: # py3k import import urllib.request as urllib_request except ImportError: # py2 import import urllib2 as urllib_request def get_tumblr_posts(api_key, blogname, offset=0): url = "http://api.tumblr.com/v2/blog/%s.tumblr.com/posts?api_key=%s&offset=%d&filter=raw" % (blogname, api_key, offset) request = urllib_request.Request(url) handle = urllib_request.urlopen(request) posts = json.loads(handle.read().decode('utf-8')) return posts.get('response').get('posts') offset = 0 posts = get_tumblr_posts(api_key, blogname, offset) while len(posts) > 0: for post in posts: title = post.get('title') or post.get('source_title') or post.get('type').capitalize() slug = post.get('slug') or slugify(title) tags = post.get('tags') timestamp = post.get('timestamp') date = strftime("%Y-%m-%d %H:%M:%S", localtime(int(timestamp))) slug = strftime("%Y-%m-%d-", localtime(int(timestamp))) + slug format = post.get('format') content = post.get('body') type = post.get('type') if type == 'photo': if format == 'markdown': fmtstr = '![%s](%s)' else: fmtstr = '%s' content = '\n'.join(fmtstr % (photo.get('caption'), photo.get('original_size').get('url')) for photo in post.get('photos')) content += '\n\n' + post.get('caption') elif type == 'quote': if format == 'markdown': fmtstr = '\n\n— %s' else: fmtstr = '

      — %s

      ' content = post.get('text') + fmtstr % post.get('source') elif type == 'link': if format == 'markdown': fmtstr = '[via](%s)\n\n' else: fmtstr = '

      via

      \n' content = fmtstr % post.get('url') + post.get('description') elif type == 'audio': if format == 'markdown': fmtstr = '[via](%s)\n\n' else: fmtstr = '

      via

      \n' content = fmtstr % post.get('source_url') + post.get('caption') + post.get('player') elif type == 'video': if format == 'markdown': fmtstr = '[via](%s)\n\n' else: fmtstr = '

      via

      \n' content = fmtstr % post.get('source_url') + post.get('caption') + '\n'.join(player.get('embed_code') for player in post.get('player')) elif type == 'answer': title = post.get('question') content = '

      %s: %s

      \n%s' % (post.get('asking_name'), post.get('asking_url'), post.get('question'), post.get('answer')) content = content.rstrip() + '\n' kind = 'article' yield (title, content, slug, date, post.get('blog_name'), [type], tags, kind, format) offset += len(posts) posts = get_tumblr_posts(api_key, blogname, offset) def feed2fields(file): """Read a feed and yield pelican fields""" import feedparser d = feedparser.parse(file) for entry in d.entries: date = (time.strftime("%Y-%m-%d %H:%M", entry.updated_parsed) if hasattr(entry, "updated_parsed") else None) author = entry.author if hasattr(entry, "author") else None tags = [e['term'] for e in entry.tags] if hasattr(entry, "tags") else None slug = slugify(entry.title) kind = 'article' yield (entry.title, entry.description, slug, date, author, [], tags, kind, "html") def build_header(title, date, author, categories, tags, slug): """Build a header from a list of fields""" header = '%s\n%s\n' % (title, '#' * len(title)) if date: header += ':date: %s\n' % date if author: header += ':author: %s\n' % author if categories: header += ':category: %s\n' % ', '.join(categories) if tags: header += ':tags: %s\n' % ', '.join(tags) if slug: header += ':slug: %s\n' % slug header += '\n' return header def build_markdown_header(title, date, author, categories, tags, slug): """Build a header from a list of fields""" header = 'Title: %s\n' % title if date: header += 'Date: %s\n' % date if author: header += 'Author: %s\n' % author if categories: header += 'Category: %s\n' % ', '.join(categories) if tags: header += 'Tags: %s\n' % ', '.join(tags) if slug: header += 'Slug: %s\n' % slug header += '\n' return header def fields2pelican(fields, out_markup, output_path, dircat=False, strip_raw=False, disable_slugs=False, dirpage=False, filename_template=None, filter_author=None): for (title, content, filename, date, author, categories, tags, kind, in_markup) in fields: if filter_author and filter_author != author: continue slug = not disable_slugs and filename or None if (in_markup == "markdown") or (out_markup == "markdown") : ext = '.md' header = build_markdown_header(title, date, author, categories, tags, slug) else: out_markup = "rst" ext = '.rst' header = build_header(title, date, author, categories, tags, slug) filename = os.path.basename(filename) # Enforce filename restrictions for various filesystems at once; see # http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words # we do not need to filter words because an extension will be appended filename = re.sub(r'[<>:"/\\|?*^% ]', '-', filename) # invalid chars filename = filename.lstrip('.') # should not start with a dot if not filename: filename = '_' filename = filename[:249] # allow for 5 extra characters # option to put page posts in pages/ subdirectory if dirpage and kind == 'page': pages_dir = os.path.join(output_path, 'pages') if not os.path.isdir(pages_dir): os.mkdir(pages_dir) out_filename = os.path.join(pages_dir, filename+ext) # option to put files in directories with categories names elif dircat and (len(categories) > 0): catname = slugify(categories[0]) out_filename = os.path.join(output_path, catname, filename+ext) if not os.path.isdir(os.path.join(output_path, catname)): os.mkdir(os.path.join(output_path, catname)) else: out_filename = os.path.join(output_path, filename+ext) print(out_filename) if in_markup in ("html", "wp-html"): html_filename = os.path.join(output_path, filename+'.html') with open(html_filename, 'w', encoding='utf-8') as fp: # Replace newlines with paragraphs wrapped with

      so # HTML is valid before conversion if in_markup == "wp-html": new_content = decode_wp_content(content) else: paragraphs = content.splitlines() paragraphs = ['

      {0}

      '.format(p) for p in paragraphs] new_content = ''.join(paragraphs) fp.write(new_content) parse_raw = '--parse-raw' if not strip_raw else '' cmd = ('pandoc --normalize --reference-links {0} --from=html' ' --to={1} -o "{2}" "{3}"').format( parse_raw, out_markup, out_filename, html_filename) try: rc = subprocess.call(cmd, shell=True) if rc < 0: error = "Child was terminated by signal %d" % -rc exit(error) elif rc > 0: error = "Please, check your Pandoc installation." exit(error) except OSError as e: error = "Pandoc execution failed: %s" % e exit(error) os.remove(html_filename) with open(out_filename, 'r', encoding='utf-8') as fs: content = fs.read() if out_markup == "markdown": # In markdown, to insert a
      , end a line with two or more spaces & then a end-of-line content = content.replace("\\\n ", " \n") content = content.replace("\\\n", " \n") with open(out_filename, 'w', encoding='utf-8') as fs: fs.write(header + content) def main(): parser = argparse.ArgumentParser( description="Transform feed, Wordpress or Dotclear files to reST (rst) " "or Markdown (md) files. Be sure to have pandoc installed.", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument(dest='input', help='The input file to read') parser.add_argument('--wpfile', action='store_true', dest='wpfile', help='Wordpress XML export') parser.add_argument('--dotclear', action='store_true', dest='dotclear', help='Dotclear export') parser.add_argument('--posterous', action='store_true', dest='posterous', help='Posterous export') parser.add_argument('--tumblr', action='store_true', dest='tumblr', help='Tumblr export') parser.add_argument('--feed', action='store_true', dest='feed', help='Feed to parse') parser.add_argument('-o', '--output', dest='output', default='output', help='Output path') parser.add_argument('-m', '--markup', dest='markup', default='rst', help='Output markup format (supports rst & markdown)') parser.add_argument('--dir-cat', action='store_true', dest='dircat', help='Put files in directories with categories name') parser.add_argument('--dir-page', action='store_true', dest='dirpage', help=('Put files recognised as pages in "pages/" sub-directory' ' (wordpress import only)')) parser.add_argument('--filter-author', dest='author', help='Import only post from the specified author') parser.add_argument('--strip-raw', action='store_true', dest='strip_raw', help="Strip raw HTML code that can't be converted to " "markup such as flash embeds or iframes (wordpress import only)") parser.add_argument('--disable-slugs', action='store_true', dest='disable_slugs', help='Disable storing slugs from imported posts within output. ' 'With this disabled, your Pelican URLs may not be consistent ' 'with your original posts.') parser.add_argument('-e', '--email', dest='email', help="Email address (posterous import only)") parser.add_argument('-p', '--password', dest='password', help="Password (posterous import only)") parser.add_argument('-b', '--blogname', dest='blogname', help="Blog name (Tumblr import only)") args = parser.parse_args() input_type = None if args.wpfile: input_type = 'wordpress' elif args.dotclear: input_type = 'dotclear' elif args.posterous: input_type = 'posterous' elif args.tumblr: input_type = 'tumblr' elif args.feed: input_type = 'feed' else: error = "You must provide either --wpfile, --dotclear, --posterous, --tumblr or --feed options" exit(error) if not os.path.exists(args.output): try: os.mkdir(args.output) except OSError: error = "Unable to create the output folder: " + args.output exit(error) if input_type == 'wordpress': fields = wp2fields(args.input) elif input_type == 'dotclear': fields = dc2fields(args.input) elif input_type == 'posterous': fields = posterous2fields(args.input, args.email, args.password) elif input_type == 'tumblr': fields = tumblr2fields(args.input, args.blogname) elif input_type == 'feed': fields = feed2fields(args.input) init() # init logging fields2pelican(fields, args.markup, args.output, dircat=args.dircat or False, dirpage=args.dirpage or False, strip_raw=args.strip_raw or False, disable_slugs=args.disable_slugs or False, filter_author=args.author) pelican-3.3/pelican/tools/pelican_quickstart.py0000755000076500000240000002642312207763674021565 0ustar jmstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six import os import string import argparse import sys import codecs from pelican import __version__ _TEMPLATES_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "templates") CONF = { 'pelican': 'pelican', 'pelicanopts': '', 'basedir': os.curdir, 'ftp_host': 'localhost', 'ftp_user': 'anonymous', 'ftp_target_dir': '/', 'ssh_host': 'localhost', 'ssh_port': 22, 'ssh_user': 'root', 'ssh_target_dir': '/var/www', 's3_bucket': 'my_s3_bucket', 'cloudfiles_username': 'my_rackspace_username', 'cloudfiles_api_key': 'my_rackspace_api_key', 'cloudfiles_container': 'my_cloudfiles_container', 'dropbox_dir': '~/Dropbox/Public/', 'default_pagination': 10, 'siteurl': '', 'lang': 'en' } def _input_compat(prompt): if six.PY3: r = input(prompt) else: r = raw_input(prompt) return r if six.PY3: str_compat = str else: str_compat = unicode def decoding_strings(f): def wrapper(*args, **kwargs): out = f(*args, **kwargs) if isinstance(out, six.string_types) and not six.PY3: # todo: make encoding configurable? if six.PY3: return out else: return out.decode(sys.stdin.encoding) return out return wrapper def get_template(name, as_encoding='utf-8'): template = os.path.join(_TEMPLATES_DIR, "{0}.in".format(name)) if not os.path.isfile(template): raise RuntimeError("Cannot open {0}".format(template)) with codecs.open(template, 'r', as_encoding) as fd: line = fd.readline() while line: yield line line = fd.readline() fd.close() @decoding_strings def ask(question, answer=str_compat, default=None, l=None): if answer == str_compat: r = '' while True: if default: r = _input_compat('> {0} [{1}] '.format(question, default)) else: r = _input_compat('> {0} '.format(question, default)) r = r.strip() if len(r) <= 0: if default: r = default break else: print('You must enter something') else: if l and len(r) != l: print('You must enter a {0} letters long string'.format(l)) else: break return r elif answer == bool: r = None while True: if default is True: r = _input_compat('> {0} (Y/n) '.format(question)) elif default is False: r = _input_compat('> {0} (y/N) '.format(question)) else: r = _input_compat('> {0} (y/n) '.format(question)) r = r.strip().lower() if r in ('y', 'yes'): r = True break elif r in ('n', 'no'): r = False break elif not r: r = default break else: print("You must answer 'yes' or 'no'") return r elif answer == int: r = None while True: if default: r = _input_compat('> {0} [{1}] '.format(question, default)) else: r = _input_compat('> {0} '.format(question)) r = r.strip() if not r: r = default break try: r = int(r) break except: print('You must enter an integer') return r else: raise NotImplemented('Argument `answer` must be str_compat, bool, or integer') def main(): parser = argparse.ArgumentParser( description="A kickstarter for Pelican", formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-p', '--path', default=os.curdir, help="The path to generate the blog into") parser.add_argument('-t', '--title', metavar="title", help='Set the title of the website') parser.add_argument('-a', '--author', metavar="author", help='Set the author name of the website') parser.add_argument('-l', '--lang', metavar="lang", help='Set the default web site language') args = parser.parse_args() print('''Welcome to pelican-quickstart v{v}. This script will help you create a new Pelican-based website. Please answer the following questions so this script can generate the files needed by Pelican. '''.format(v=__version__)) project = os.path.join( os.environ.get('VIRTUAL_ENV', os.curdir), '.project') if os.path.isfile(project): CONF['basedir'] = open(project, 'r').read().rstrip("\n") print('Using project associated with current virtual environment.' 'Will save to:\n%s\n' % CONF['basedir']) else: CONF['basedir'] = os.path.abspath(ask('Where do you want to create your new web site?', answer=str_compat, default=args.path)) CONF['sitename'] = ask('What will be the title of this web site?', answer=str_compat, default=args.title) CONF['author'] = ask('Who will be the author of this web site?', answer=str_compat, default=args.author) CONF['lang'] = ask('What will be the default language of this web site?', str_compat, args.lang or CONF['lang'], 2) if ask('Do you want to specify a URL prefix? e.g., http://example.com ', answer=bool, default=True): CONF['siteurl'] = ask('What is your URL prefix? (see above example; no trailing slash)', str_compat, CONF['siteurl']) CONF['with_pagination'] = ask('Do you want to enable article pagination?', bool, bool(CONF['default_pagination'])) if CONF['with_pagination']: CONF['default_pagination'] = ask('How many articles per page do you want?', int, CONF['default_pagination']) else: CONF['default_pagination'] = False automation = ask('Do you want to generate a Fabfile/Makefile to automate generation and publishing?', bool, True) develop = ask('Do you want an auto-reload & simpleHTTP script to assist with theme and site development?', bool, True) if automation: if ask('Do you want to upload your website using FTP?', answer=bool, default=False): CONF['ftp_host'] = ask('What is the hostname of your FTP server?', str_compat, CONF['ftp_host']) CONF['ftp_user'] = ask('What is your username on that server?', str_compat, CONF['ftp_user']) CONF['ftp_target_dir'] = ask('Where do you want to put your web site on that server?', str_compat, CONF['ftp_target_dir']) if ask('Do you want to upload your website using SSH?', answer=bool, default=False): CONF['ssh_host'] = ask('What is the hostname of your SSH server?', str_compat, CONF['ssh_host']) CONF['ssh_port'] = ask('What is the port of your SSH server?', int, CONF['ssh_port']) CONF['ssh_user'] = ask('What is your username on that server?', str_compat, CONF['ssh_user']) CONF['ssh_target_dir'] = ask('Where do you want to put your web site on that server?', str_compat, CONF['ssh_target_dir']) if ask('Do you want to upload your website using Dropbox?', answer=bool, default=False): CONF['dropbox_dir'] = ask('Where is your Dropbox directory?', str_compat, CONF['dropbox_dir']) if ask('Do you want to upload your website using S3?', answer=bool, default=False): CONF['s3_bucket'] = ask('What is the name of your S3 bucket?', str_compat, CONF['s3_bucket']) if ask('Do you want to upload your website using Rackspace Cloud Files?', answer=bool, default=False): CONF['cloudfiles_username'] = ask('What is your Rackspace Cloud username?', str_compat, CONF['cloudfiles_username']) CONF['cloudfiles_api_key'] = ask('What is your Rackspace Cloud API key?', str_compat, CONF['cloudfiles_api_key']) CONF['cloudfiles_container'] = ask('What is the name of your Cloud Files container?', str_compat, CONF['cloudfiles_container']) try: os.makedirs(os.path.join(CONF['basedir'], 'content')) except OSError as e: print('Error: {0}'.format(e)) try: os.makedirs(os.path.join(CONF['basedir'], 'output')) except OSError as e: print('Error: {0}'.format(e)) try: with codecs.open(os.path.join(CONF['basedir'], 'pelicanconf.py'), 'w', 'utf-8') as fd: conf_python = dict() for key, value in CONF.items(): conf_python[key] = repr(value) for line in get_template('pelicanconf.py'): template = string.Template(line) fd.write(template.safe_substitute(conf_python)) fd.close() except OSError as e: print('Error: {0}'.format(e)) try: with codecs.open(os.path.join(CONF['basedir'], 'publishconf.py'), 'w', 'utf-8') as fd: for line in get_template('publishconf.py'): template = string.Template(line) fd.write(template.safe_substitute(CONF)) fd.close() except OSError as e: print('Error: {0}'.format(e)) if automation: try: with codecs.open(os.path.join(CONF['basedir'], 'fabfile.py'), 'w', 'utf-8') as fd: for line in get_template('fabfile.py'): template = string.Template(line) fd.write(template.safe_substitute(CONF)) fd.close() except OSError as e: print('Error: {0}'.format(e)) try: with codecs.open(os.path.join(CONF['basedir'], 'Makefile'), 'w', 'utf-8') as fd: mkfile_template_name = 'Makefile' py_v = 'PY=python' if six.PY3: py_v = 'PY=python3' template = string.Template(py_v) fd.write(template.safe_substitute(CONF)) fd.write('\n') for line in get_template(mkfile_template_name): template = string.Template(line) fd.write(template.safe_substitute(CONF)) fd.close() except OSError as e: print('Error: {0}'.format(e)) if develop: conf_shell = dict() for key, value in CONF.items(): if isinstance(value, six.string_types) and ' ' in value: value = '"' + value.replace('"', '\\"') + '"' conf_shell[key] = value try: with codecs.open(os.path.join(CONF['basedir'], 'develop_server.sh'), 'w', 'utf-8') as fd: lines = list(get_template('develop_server.sh')) py_v = 'PY=python\n' if six.PY3: py_v = 'PY=python3\n' lines = lines[:4] + [py_v] + lines[4:] for line in lines: template = string.Template(line) fd.write(template.safe_substitute(conf_shell)) fd.close() os.chmod((os.path.join(CONF['basedir'], 'develop_server.sh')), 493) # mode 0o755 except OSError as e: print('Error: {0}'.format(e)) print('Done. Your new project is available at %s' % CONF['basedir']) if __name__ == "__main__": main() pelican-3.3/pelican/tools/pelican_themes.py0000777000076500000240000001721712130377623020653 0ustar jmstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six import argparse import os import shutil import sys try: import pelican except: err('Cannot import pelican.\nYou must install Pelican in order to run this script.', -1) global _THEMES_PATH _THEMES_PATH = os.path.join( os.path.dirname( os.path.abspath( pelican.__file__ ) ), 'themes' ) __version__ = '0.2' _BUILTIN_THEMES = ['simple', 'notmyidea'] def err(msg, die=None): """Print an error message and exits if an exit code is given""" sys.stderr.write(msg + '\n') if die: sys.exit((die if type(die) is int else 1)) def main(): """Main function""" parser = argparse.ArgumentParser(description="""Install themes for Pelican""") excl= parser.add_mutually_exclusive_group() excl.add_argument('-l', '--list', dest='action', action="store_const", const='list', help="Show the themes already installed and exit") excl.add_argument('-p', '--path', dest='action', action="store_const", const='path', help="Show the themes path and exit") excl.add_argument('-V', '--version', action='version', version='pelican-themes v{0}'.format(__version__), help='Print the version of this script') parser.add_argument('-i', '--install', dest='to_install', nargs='+', metavar="theme path", help='The themes to install') parser.add_argument('-r', '--remove', dest='to_remove', nargs='+', metavar="theme name", help='The themes to remove') parser.add_argument('-U', '--upgrade', dest='to_upgrade', nargs='+', metavar="theme path", help='The themes to upgrade') parser.add_argument('-s', '--symlink', dest='to_symlink', nargs='+', metavar="theme path", help="Same as `--install', but create a symbolic link instead of copying the theme. Useful for theme development") parser.add_argument('-c', '--clean', dest='clean', action="store_true", help="Remove the broken symbolic links of the theme path") parser.add_argument('-v', '--verbose', dest='verbose', action="store_true", help="Verbose output") args = parser.parse_args() to_install = args.to_install or args.to_upgrade to_sym = args.to_symlink or args.clean if args.action: if args.action is 'list': list_themes(args.verbose) elif args.action is 'path': print(_THEMES_PATH) elif to_install or args.to_remove or to_sym: if args.to_remove: if args.verbose: print('Removing themes...') for i in args.to_remove: remove(i, v=args.verbose) if args.to_install: if args.verbose: print('Installing themes...') for i in args.to_install: install(i, v=args.verbose) if args.to_upgrade: if args.verbose: print('Upgrading themes...') for i in args.to_upgrade: install(i, v=args.verbose, u=True) if args.to_symlink: if args.verbose: print('Linking themes...') for i in args.to_symlink: symlink(i, v=args.verbose) if args.clean: if args.verbose: print('Cleaning the themes directory...') clean(v=args.verbose) else: print('No argument given... exiting.') def themes(): """Returns the list of the themes""" for i in os.listdir(_THEMES_PATH): e = os.path.join(_THEMES_PATH, i) if os.path.isdir(e): if os.path.islink(e): yield (e, os.readlink(e)) else: yield (e, None) def list_themes(v=False): """Display the list of the themes""" for t, l in themes(): if not v: t = os.path.basename(t) if l: if v: print(t + (" (symbolic link to `" + l + "')")) else: print(t + '@') else: print(t) def remove(theme_name, v=False): """Removes a theme""" theme_name = theme_name.replace('/','') target = os.path.join(_THEMES_PATH, theme_name) if theme_name in _BUILTIN_THEMES: err(theme_name + ' is a builtin theme.\nYou cannot remove a builtin theme with this script, remove it by hand if you want.') elif os.path.islink(target): if v: print('Removing link `' + target + "'") os.remove(target) elif os.path.isdir(target): if v: print('Removing directory `' + target + "'") shutil.rmtree(target) elif os.path.exists(target): err(target + ' : not a valid theme') else: err(target + ' : no such file or directory') def install(path, v=False, u=False): """Installs a theme""" if not os.path.exists(path): err(path + ' : no such file or directory') elif not os.path.isdir(path): err(path + ' : not a directory') else: theme_name = os.path.basename(os.path.normpath(path)) theme_path = os.path.join(_THEMES_PATH, theme_name) exists = os.path.exists(theme_path) if exists and not u: err(path + ' : already exists') elif exists and u: remove(theme_name, v) install(path, v) else: if v: print("Copying `{p}' to `{t}' ...".format(p=path, t=theme_path)) try: shutil.copytree(path, theme_path) try: if os.name == 'posix': for root, dirs, files in os.walk(theme_path): for d in dirs: dname = os.path.join(root, d) os.chmod(dname, 493) # 0o755 for f in files: fname = os.path.join(root, f) os.chmod(fname, 420) # 0o644 except OSError as e: err("Cannot change permissions of files or directory in `{r}':\n{e}".format(r=theme_path, e=str(e)), die=False) except Exception as e: err("Cannot copy `{p}' to `{t}':\n{e}".format(p=path, t=theme_path, e=str(e))) def symlink(path, v=False): """Symbolically link a theme""" if not os.path.exists(path): err(path + ' : no such file or directory') elif not os.path.isdir(path): err(path + ' : not a directory') else: theme_name = os.path.basename(os.path.normpath(path)) theme_path = os.path.join(_THEMES_PATH, theme_name) if os.path.exists(theme_path): err(path + ' : already exists') else: if v: print("Linking `{p}' to `{t}' ...".format(p=path, t=theme_path)) try: os.symlink(path, theme_path) except Exception as e: err("Cannot link `{p}' to `{t}':\n{e}".format(p=path, t=theme_path, e=str(e))) def is_broken_link(path): """Returns True if the path given as is a broken symlink""" path = os.readlink(path) return not os.path.exists(path) def clean(v=False): """Removes the broken symbolic links""" c=0 for path in os.listdir(_THEMES_PATH): path = os.path.join(_THEMES_PATH, path) if os.path.islink(path): if is_broken_link(path): if v: print('Removing {0}'.format(path)) try: os.remove(path) except OSError as e: print('Error: cannot remove {0}'.format(path)) else: c+=1 print("\nRemoved {0} broken links".format(c)) pelican-3.3/pelican/tools/templates/0000755000076500000240000000000012220367225017275 5ustar jmstaff00000000000000pelican-3.3/pelican/tools/templates/develop_server.sh.in0000777000076500000240000000426212171064115023272 0ustar jmstaff00000000000000#!/usr/bin/env bash ## # This section should match your Makefile ## PELICAN=$pelican PELICANOPTS=$pelicanopts BASEDIR=$$(pwd) INPUTDIR=$$BASEDIR/content OUTPUTDIR=$$BASEDIR/output CONFFILE=$$BASEDIR/pelicanconf.py ### # Don't change stuff below here unless you are sure ### SRV_PID=$$BASEDIR/srv.pid PELICAN_PID=$$BASEDIR/pelican.pid function usage(){ echo "usage: $$0 (stop) (start) (restart) [port]" echo "This starts pelican in debug and reload mode and then launches" echo "A pelican.server to help site development. It doesn't read" echo "your pelican options so you edit any paths in your Makefile" echo "you will need to edit it as well" exit 3 } function alive() { kill -0 $$1 >/dev/null 2>&1 } function shut_down(){ PID=$$(cat $$SRV_PID) if [[ $$? -eq 0 ]]; then if alive $PID; then echo "Killing pelican.server" kill $$PID else echo "Stale PID, deleting" fi rm $$SRV_PID else echo "pelican.server PIDFile not found" fi PID=$$(cat $$PELICAN_PID) if [[ $$? -eq 0 ]]; then if alive $$PID; then echo "Killing Pelican" kill $$PID else echo "Stale PID, deleting" fi rm $$PELICAN_PID else echo "Pelican PIDFile not found" fi } function start_up(){ local port=$$1 echo "Starting up Pelican and pelican.server" shift $$PELICAN --debug --autoreload -r $$INPUTDIR -o $$OUTPUTDIR -s $$CONFFILE $$PELICANOPTS & pelican_pid=$$! echo $$pelican_pid > $$PELICAN_PID cd $$OUTPUTDIR $PY -m pelican.server $$port & srv_pid=$$! echo $$srv_pid > $$SRV_PID cd $$BASEDIR sleep 1 if ! alive $$pelican_pid ; then echo "Pelican didn't start. Is the pelican package installed?" return 1 elif ! alive $$srv_pid ; then echo "pelican.server didn't start. Is there something else which uses port 8000?" return 1 fi echo 'Pelican and pelican.server processes now running in background.' } ### # MAIN ### [[ ($$# -eq 0) || ($$# -gt 2) ]] && usage port='' [[ $$# -eq 2 ]] && port=$$2 if [[ $$1 == "stop" ]]; then shut_down elif [[ $$1 == "restart" ]]; then shut_down start_up $$port elif [[ $$1 == "start" ]]; then if ! start_up $$port; then shut_down fi else usage fi pelican-3.3/pelican/tools/templates/fabfile.py.in0000644000076500000240000000273012207763674021663 0ustar jmstaff00000000000000from fabric.api import * import fabric.contrib.project as project import os # Local path configuration (can be absolute or relative to fabfile) env.deploy_path = 'output' DEPLOY_PATH = env.deploy_path # Remote server configuration production = '$ssh_user@$ssh_host:$ssh_port' dest_path = '$ssh_target_dir' # Rackspace Cloud Files configuration settings env.cloudfiles_username = '$cloudfiles_username' env.cloudfiles_api_key = '$cloudfiles_api_key' env.cloudfiles_container = '$cloudfiles_container' def clean(): if os.path.isdir(DEPLOY_PATH): local('rm -rf {deploy_path}'.format(**env)) local('mkdir {deploy_path}'.format(**env)) def build(): local('pelican -s pelicanconf.py') def rebuild(): clean() build() def regenerate(): local('pelican -r -s pelicanconf.py') def serve(): local('cd {deploy_path} && python -m SimpleHTTPServer'.format(**env)) def reserve(): build() serve() def preview(): local('pelican -s publishconf.py') def cf_upload(): rebuild() local('cd {deploy_path} && ' 'swift -v -A https://auth.api.rackspacecloud.com/v1.0 ' '-U {cloudfiles_username} ' '-K {cloudfiles_api_key} ' 'upload -c {cloudfiles_container} .'.format(**env)) @hosts(production) def publish(): local('pelican -s publishconf.py') project.rsync_project( remote_dir=dest_path, exclude=".DS_Store", local_dir=DEPLOY_PATH.rstrip('/') + '/', delete=True ) pelican-3.3/pelican/tools/templates/Makefile.in0000644000076500000240000000735712207764021021356 0ustar jmstaff00000000000000PELICAN=$pelican PELICANOPTS=$pelicanopts BASEDIR=$$(CURDIR) INPUTDIR=$$(BASEDIR)/content OUTPUTDIR=$$(BASEDIR)/output CONFFILE=$$(BASEDIR)/pelicanconf.py PUBLISHCONF=$$(BASEDIR)/publishconf.py FTP_HOST=$ftp_host FTP_USER=$ftp_user FTP_TARGET_DIR=$ftp_target_dir SSH_HOST=$ssh_host SSH_PORT=$ssh_port SSH_USER=$ssh_user SSH_TARGET_DIR=$ssh_target_dir S3_BUCKET=$s3_bucket CLOUDFILES_USERNAME=$cloudfiles_username CLOUDFILES_API_KEY=$cloudfiles_api_key CLOUDFILES_CONTAINER=$cloudfiles_container DROPBOX_DIR=$dropbox_dir DEBUG ?= 0 ifeq ($(DEBUG), 1) PELICANOPTS += -D endif help: @echo 'Makefile for a pelican Web site ' @echo ' ' @echo 'Usage: ' @echo ' make html (re)generate the web site ' @echo ' make clean remove the generated files ' @echo ' make regenerate regenerate files upon modification ' @echo ' make publish generate using production settings ' @echo ' make serve [PORT=8000] serve site at http://localhost:8000' @echo ' make devserver [PORT=8000] start/restart develop_server.sh ' @echo ' make stopserver stop local server ' @echo ' make ssh_upload upload the web site via SSH ' @echo ' make rsync_upload upload the web site via rsync+ssh ' @echo ' make dropbox_upload upload the web site via Dropbox ' @echo ' make ftp_upload upload the web site via FTP ' @echo ' make s3_upload upload the web site via S3 ' @echo ' make cf_upload upload the web site via Cloud Files' @echo ' make github upload the web site via gh-pages ' @echo ' ' @echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html' @echo ' ' html: $$(PELICAN) $$(INPUTDIR) -o $$(OUTPUTDIR) -s $$(CONFFILE) $$(PELICANOPTS) clean: [ ! -d $$(OUTPUTDIR) ] || rm -rf $$(OUTPUTDIR) regenerate: $$(PELICAN) -r $$(INPUTDIR) -o $$(OUTPUTDIR) -s $$(CONFFILE) $$(PELICANOPTS) serve: ifdef PORT cd $$(OUTPUTDIR) && $(PY) -m pelican.server $$(PORT) else cd $$(OUTPUTDIR) && $(PY) -m pelican.server endif devserver: ifdef PORT $$(BASEDIR)/develop_server.sh restart $$(PORT) else $$(BASEDIR)/develop_server.sh restart endif stopserver: kill -9 `cat pelican.pid` kill -9 `cat srv.pid` @echo 'Stopped Pelican and SimpleHTTPServer processes running in background.' publish: $$(PELICAN) $$(INPUTDIR) -o $$(OUTPUTDIR) -s $$(PUBLISHCONF) $$(PELICANOPTS) ssh_upload: publish scp -P $$(SSH_PORT) -r $$(OUTPUTDIR)/* $$(SSH_USER)@$$(SSH_HOST):$$(SSH_TARGET_DIR) rsync_upload: publish rsync -e "ssh -p $(SSH_PORT)" -P -rvz --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude dropbox_upload: publish cp -r $$(OUTPUTDIR)/* $$(DROPBOX_DIR) ftp_upload: publish lftp ftp://$$(FTP_USER)@$$(FTP_HOST) -e "mirror -R $$(OUTPUTDIR) $$(FTP_TARGET_DIR) ; quit" s3_upload: publish s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed cf_upload: publish cd $(OUTPUTDIR) && swift -v -A https://auth.api.rackspacecloud.com/v1.0 -U $(CLOUDFILES_USERNAME) -K $(CLOUDFILES_API_KEY) upload -c $(CLOUDFILES_CONTAINER) . github: publish ghp-import $$(OUTPUTDIR) git push origin gh-pages .PHONY: html help clean regenerate serve devserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github pelican-3.3/pelican/tools/templates/pelicanconf.py.in0000666000076500000240000000145012135053604022537 0ustar jmstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # from __future__ import unicode_literals AUTHOR = $author SITENAME = $sitename SITEURL = '' TIMEZONE = 'Europe/Paris' DEFAULT_LANG = $lang # Feed generation is usually not desired when developing FEED_ALL_ATOM = None CATEGORY_FEED_ATOM = None TRANSLATION_FEED_ATOM = None # Blogroll LINKS = (('Pelican', 'http://getpelican.com/'), ('Python.org', 'http://python.org/'), ('Jinja2', 'http://jinja.pocoo.org/'), ('You can modify those links in your config file', '#'),) # Social widget SOCIAL = (('You can add links in your config file', '#'), ('Another social link', '#'),) DEFAULT_PAGINATION = $default_pagination # Uncomment following line if you want document-relative URLs when developing #RELATIVE_URLS = True pelican-3.3/pelican/tools/templates/publishconf.py.in0000777000076500000240000000100412135062627022575 0ustar jmstaff00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # from __future__ import unicode_literals # This file is only used if you use `make publish` or # explicitly specify it as your config file. import os import sys sys.path.append(os.curdir) from pelicanconf import * SITEURL = '$siteurl' RELATIVE_URLS = False FEED_ALL_ATOM = 'feeds/all.atom.xml' CATEGORY_FEED_ATOM = 'feeds/%s.atom.xml' DELETE_OUTPUT_DIRECTORY = True # Following items are often useful when publishing #DISQUS_SITENAME = "" #GOOGLE_ANALYTICS = "" pelican-3.3/pelican/urlwrappers.py0000666000076500000240000000525412171064115017106 0ustar jmstaff00000000000000import os import functools import logging import six from pelican.utils import (slugify, python_2_unicode_compatible) logger = logging.getLogger(__name__) @python_2_unicode_compatible @functools.total_ordering class URLWrapper(object): def __init__(self, name, settings): # next 2 lines are redundant with the setter of the name property # but are here for clarity self.settings = settings self._name = name self.slug = slugify(name, self.settings.get('SLUG_SUBSTITUTIONS', ())) self.name = name @property def name(self): return self._name @name.setter def name(self, name): self._name = name self.slug = slugify(name, self.settings.get('SLUG_SUBSTITUTIONS', ())) def as_dict(self): d = self.__dict__ d['name'] = self.name return d def __hash__(self): return hash(self.slug) def _key(self): return self.slug def _normalize_key(self, key): subs = self.settings.get('SLUG_SUBSTITUTIONS', ()) return six.text_type(slugify(key, subs)) def __eq__(self, other): return self._key() == self._normalize_key(other) def __ne__(self, other): return self._key() != self._normalize_key(other) def __lt__(self, other): return self._key() < self._normalize_key(other) def __str__(self): return self.name def __repr__(self): return '<{} {}>'.format(type(self).__name__, str(self)) def _from_settings(self, key, get_page_name=False): """Returns URL information as defined in settings. When get_page_name=True returns URL without anything after {slug} e.g. if in settings: CATEGORY_URL="cat/{slug}.html" this returns "cat/{slug}" Useful for pagination. """ setting = "%s_%s" % (self.__class__.__name__.upper(), key) value = self.settings[setting] if not isinstance(value, six.string_types): logger.warning('%s is set to %s' % (setting, value)) return value else: if get_page_name: return os.path.splitext(value)[0].format(**self.as_dict()) else: return value.format(**self.as_dict()) page_name = property(functools.partial(_from_settings, key='URL', get_page_name=True)) url = property(functools.partial(_from_settings, key='URL')) save_as = property(functools.partial(_from_settings, key='SAVE_AS')) class Category(URLWrapper): pass class Tag(URLWrapper): def __init__(self, name, *args, **kwargs): super(Tag, self).__init__(name.strip(), *args, **kwargs) class Author(URLWrapper): pass pelican-3.3/pelican/utils.py0000644000076500000240000004437312216354256015671 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals, print_function import six import codecs import errno import fnmatch import locale import logging import os import pytz import re import shutil import traceback from collections import Hashable from contextlib import contextmanager from datetime import datetime from functools import partial from itertools import groupby from jinja2 import Markup from operator import attrgetter logger = logging.getLogger(__name__) def strftime(date, date_format): ''' Replacement for built-in strftime This is necessary because of the way Py2 handles date format strings. Specifically, Py2 strftime takes a bytestring. In the case of text output (e.g. %b, %a, etc), the output is encoded with an encoding defined by locale.LC_TIME. Things get messy if the formatting string has chars that are not valid in LC_TIME defined encoding. This works by 'grabbing' possible format strings (those starting with %), formatting them with the date, (if necessary) decoding the output and replacing formatted output back. ''' # grab candidate format options format_options = '%.' candidates = re.findall(format_options, date_format) # replace candidates with placeholders for later % formatting template = re.sub(format_options, '%s', date_format) # we need to convert formatted dates back to unicode in Py2 # LC_TIME determines the encoding for built-in strftime outputs lang_code, enc = locale.getlocale(locale.LC_TIME) formatted_candidates = [] for candidate in candidates: # test for valid C89 directives only if candidate[1] in 'aAbBcdfHIjmMpSUwWxXyYzZ%': formatted = date.strftime(candidate) # convert Py2 result to unicode if not six.PY3 and enc is not None: formatted = formatted.decode(enc) else: formatted = candidate formatted_candidates.append(formatted) # put formatted candidates back and return return template % tuple(formatted_candidates) class DateFormatter(object): '''A date formatter object used as a jinja filter Uses the `strftime` implementation and makes sure jinja uses the locale defined in LOCALE setting ''' def __init__(self): self.locale = locale.setlocale(locale.LC_TIME) def __call__(self, date, date_format): old_locale = locale.setlocale(locale.LC_TIME) locale.setlocale(locale.LC_TIME, self.locale) formatted = strftime(date, date_format) locale.setlocale(locale.LC_TIME, old_locale) return formatted def python_2_unicode_compatible(klass): """ A decorator that defines __unicode__ and __str__ methods under Python 2. Under Python 3 it does nothing. To support Python 2 and 3 with a single code base, define a __str__ method returning text and apply this decorator to the class. From django.utils.encoding. """ if not six.PY3: klass.__unicode__ = klass.__str__ klass.__str__ = lambda self: self.__unicode__().encode('utf-8') return klass class memoized(object): """Function decorator to cache return values. If called later with the same arguments, the cached value is returned (not reevaluated). """ def __init__(self, func): self.func = func self.cache = {} def __call__(self, *args): if not isinstance(args, Hashable): # uncacheable. a list, for instance. # better to not cache than blow up. return self.func(*args) if args in self.cache: return self.cache[args] else: value = self.func(*args) self.cache[args] = value return value def __repr__(self): return self.func.__doc__ def __get__(self, obj, objtype): '''Support instance methods.''' return partial(self.__call__, obj) def deprecated_attribute(old, new, since=None, remove=None, doc=None): """Attribute deprecation decorator for gentle upgrades For example: class MyClass (object): @deprecated_attribute( old='abc', new='xyz', since=(3, 2, 0), remove=(4, 1, 3)) def abc(): return None def __init__(self): xyz = 5 Note that the decorator needs a dummy method to attach to, but the content of the dummy method is ignored. """ def _warn(): version = '.'.join(six.text_type(x) for x in since) message = ['{} has been deprecated since {}'.format(old, version)] if remove: version = '.'.join(six.text_type(x) for x in remove) message.append( ' and will be removed by version {}'.format(version)) message.append('. Use {} instead.'.format(new)) logger.warning(''.join(message)) logger.debug(''.join( six.text_type(x) for x in traceback.format_stack())) def fget(self): _warn() return getattr(self, new) def fset(self, value): _warn() setattr(self, new, value) def decorator(dummy): return property(fget=fget, fset=fset, doc=doc) return decorator def get_date(string): """Return a datetime object from a string. If no format matches the given date, raise a ValueError. """ string = re.sub(' +', ' ', string) formats = [ # ISO 8601 '%Y', '%Y-%m', '%Y-%m-%d', '%Y-%m-%dT%H:%M%z', '%Y-%m-%dT%H:%MZ', '%Y-%m-%dT%H:%M', '%Y-%m-%dT%H:%M:%S%z', '%Y-%m-%dT%H:%M:%SZ', '%Y-%m-%dT%H:%M:%S', '%Y-%m-%dT%H:%M:%S.%f%z', '%Y-%m-%dT%H:%M:%S.%fZ', '%Y-%m-%dT%H:%M:%S.%f', # end ISO 8601 forms '%Y-%m-%d %H:%M', '%Y-%m-%d %H:%M:%S', '%Y/%m/%d %H:%M', '%Y/%m/%d', '%d-%m-%Y', '%d.%m.%Y %H:%M', '%d.%m.%Y', '%d/%m/%Y', ] for date_format in formats: try: date = datetime.strptime(string, date_format) except ValueError: continue if date_format.endswith('Z'): date = date.replace(tzinfo=pytz.timezone('UTC')) return date raise ValueError('{0!r} is not a valid date'.format(string)) @contextmanager def pelican_open(filename): """Open a file and return its content""" with codecs.open(filename, encoding='utf-8') as infile: content = infile.read() if content[0] == codecs.BOM_UTF8.decode('utf8'): content = content[1:] yield content def slugify(value, substitutions=()): """ Normalizes string, converts to lowercase, removes non-alpha characters, and converts spaces to hyphens. Took from Django sources. """ # TODO Maybe steal again from current Django 1.5dev value = Markup(value).striptags() # value must be unicode per se import unicodedata from unidecode import unidecode # unidecode returns str in Py2 and 3, so in Py2 we have to make # it unicode again value = unidecode(value) if isinstance(value, six.binary_type): value = value.decode('ascii') # still unicode value = unicodedata.normalize('NFKD', value).lower() for src, dst in substitutions: value = value.replace(src.lower(), dst.lower()) value = re.sub('[^\w\s-]', '', value).strip() value = re.sub('[-\s]+', '-', value) # we want only ASCII chars value = value.encode('ascii', 'ignore') # but Pelican should generally use only unicode return value.decode('ascii') def copy(path, source, destination, destination_path=None): """Copy path from origin to destination. The function is able to copy either files or directories. :param path: the path to be copied from the source to the destination :param source: the source dir :param destination: the destination dir :param destination_path: the destination path (optional) """ if not destination_path: destination_path = path source_ = os.path.abspath(os.path.expanduser(os.path.join(source, path))) destination_ = os.path.abspath( os.path.expanduser(os.path.join(destination, destination_path))) if not os.path.exists(destination_): os.makedirs(destination_) def recurse(source, destination): for entry in os.listdir(source): entry_path = os.path.join(source, entry) if os.path.isdir(entry_path): entry_dest = os.path.join(destination, entry) if os.path.exists(entry_dest): if not os.path.isdir(entry_dest): raise IOError('Failed to copy {0} a directory.' .format(entry_dest)) recurse(entry_path, entry_dest) else: shutil.copytree(entry_path, entry_dest) else: shutil.copy(entry_path, destination) if os.path.isdir(source_): recurse(source_, destination_) elif os.path.isfile(source_): dest_dir = os.path.dirname(destination_) if not os.path.exists(dest_dir): os.makedirs(dest_dir) shutil.copy(source_, destination_) logger.info('copying %s to %s' % (source_, destination_)) else: logger.warning('skipped copy %s to %s' % (source_, destination_)) def clean_output_dir(path, retention): """Remove all files from output directory except those in retention list""" if not os.path.exists(path): logger.debug("Directory already removed: %s" % path) return if not os.path.isdir(path): try: os.remove(path) except Exception as e: logger.error("Unable to delete file %s; %s" % (path, str(e))) return # remove existing content from output folder unless in retention list for filename in os.listdir(path): file = os.path.join(path, filename) if any(filename == retain for retain in retention): logger.debug("Skipping deletion; %s is on retention list: %s" \ % (filename, file)) elif os.path.isdir(file): try: shutil.rmtree(file) logger.debug("Deleted directory %s" % file) except Exception as e: logger.error("Unable to delete directory %s; %s" % ( file, str(e))) elif os.path.isfile(file) or os.path.islink(file): try: os.remove(file) logger.debug("Deleted file/link %s" % file) except Exception as e: logger.error("Unable to delete file %s; %s" % (file, str(e))) else: logger.error("Unable to delete %s, file type unknown" % file) def get_relative_path(path): """Return the relative path from the given path to the root path.""" components = split_all(path) if len(components) <= 1: return os.curdir else: parents = [os.pardir] * (len(components) - 1) return os.path.join(*parents) def path_to_url(path): """Return the URL corresponding to a given path.""" if os.sep == '/': return path else: return '/'.join(split_all(path)) def truncate_html_words(s, num, end_text='...'): """Truncates HTML to a certain number of words. (not counting tags and comments). Closes opened tags if they were correctly closed in the given html. Takes an optional argument of what should be used to notify that the string has been truncated, defaulting to ellipsis (...). Newlines in the HTML are preserved. (From the django framework). """ length = int(num) if length <= 0: return '' html4_singlets = ('br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input') # Set up regular expressions re_words = re.compile(r'&.*?;|<.*?>|(\w[\w-]*)', re.U) re_tag = re.compile(r'<(/)?([^ ]+?)(?: (/)| .*?)?>') # Count non-HTML words and keep note of open tags pos = 0 end_text_pos = 0 words = 0 open_tags = [] while words <= length: m = re_words.search(s, pos) if not m: # Checked through whole string break pos = m.end(0) if m.group(1): # It's an actual non-HTML word words += 1 if words == length: end_text_pos = pos continue # Check for tag tag = re_tag.match(m.group(0)) if not tag or end_text_pos: # Don't worry about non tags or tags after our truncate point continue closing_tag, tagname, self_closing = tag.groups() tagname = tagname.lower() # Element names are always case-insensitive if self_closing or tagname in html4_singlets: pass elif closing_tag: # Check for match in open tags list try: i = open_tags.index(tagname) except ValueError: pass else: # SGML: An end tag closes, back to the matching start tag, # all unclosed intervening start tags with omitted end tags open_tags = open_tags[i + 1:] else: # Add it to the start of the open tags list open_tags.insert(0, tagname) if words <= length: # Don't try to close tags if we don't need to truncate return s out = s[:end_text_pos] if end_text: out += ' ' + end_text # Close any tags still open for tag in open_tags: out += '' % tag # Return string return out def process_translations(content_list): """ Finds translation and returns them. Returns a tuple with two lists (index, translations). Index list includes items in default language or items which have no variant in default language. Items with the `translation` metadata set to something else than `False` or `false` will be used as translations, unless all the items with the same slug have that metadata. For each content_list item, sets the 'translations' attribute. """ content_list.sort(key=attrgetter('slug')) grouped_by_slugs = groupby(content_list, attrgetter('slug')) index = [] translations = [] for slug, items in grouped_by_slugs: items = list(items) # items with `translation` metadata will be used as translations… default_lang_items = list(filter( lambda i: i.metadata.get('translation', 'false').lower() == 'false', items)) # …unless all items with that slug are translations if not default_lang_items: default_lang_items = items # display warnings if several items have the same lang for lang, lang_items in groupby(items, attrgetter('lang')): lang_items = list(lang_items) len_ = len(lang_items) if len_ > 1: logger.warning('There are %s variants of "%s" with lang %s' \ % (len_, slug, lang)) for x in lang_items: logger.warning(' %s' % x.source_path) # find items with default language default_lang_items = list(filter(attrgetter('in_default_lang'), default_lang_items)) # if there is no article with default language, take an other one if not default_lang_items: default_lang_items = items[:1] if not slug: logger.warning(( 'empty slug for {!r}. ' 'You can fix this by adding a title or a slug to your ' 'content' ).format(default_lang_items[0].source_path)) index.extend(default_lang_items) translations.extend([x for x in items if x not in default_lang_items]) for a in items: a.translations = [x for x in items if x != a] return index, translations def folder_watcher(path, extensions, ignores=[]): '''Generator for monitoring a folder for modifications. Returns a boolean indicating if files are changed since last check. Returns None if there are no matching files in the folder''' def file_times(path): '''Return `mtime` for each file in path''' for root, dirs, files in os.walk(path): dirs[:] = [x for x in dirs if not x.startswith(os.curdir)] for f in files: if (f.endswith(tuple(extensions)) and not any(fnmatch.fnmatch(f, ignore) for ignore in ignores)): try: yield os.stat(os.path.join(root, f)).st_mtime except OSError as e: logger.warning('Caught Exception: {}'.format(e)) LAST_MTIME = 0 while True: try: mtime = max(file_times(path)) if mtime > LAST_MTIME: LAST_MTIME = mtime yield True except ValueError: yield None else: yield False def file_watcher(path): '''Generator for monitoring a file for modifications''' LAST_MTIME = 0 while True: if path: try: mtime = os.stat(path).st_mtime except OSError as e: logger.warning('Caught Exception: {}'.format(e)) continue if mtime > LAST_MTIME: LAST_MTIME = mtime yield True else: yield False else: yield None def set_date_tzinfo(d, tz_name=None): """Set the timezone for dates that don't have tzinfo""" if tz_name and not d.tzinfo: tz = pytz.timezone(tz_name) return tz.localize(d) return d def mkdir_p(path): try: os.makedirs(path) except OSError as e: if e.errno != errno.EEXIST or not os.path.isdir(path): raise def split_all(path): """Split a path into a list of components While os.path.split() splits a single component off the back of `path`, this function splits all components: >>> split_all(os.path.join('a', 'b', 'c')) ['a', 'b', 'c'] """ components = [] path = path.lstrip('/') while path: head, tail = os.path.split(path) if tail: components.insert(0, tail) elif head == path: components.insert(0, head) break path = head return components pelican-3.3/pelican/writers.py0000644000076500000240000002005112207763674016223 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import with_statement, unicode_literals, print_function import six import os import locale import logging if not six.PY3: from codecs import open from feedgenerator import Atom1Feed, Rss201rev2Feed from jinja2 import Markup from pelican.paginator import Paginator from pelican.utils import get_relative_path, path_to_url, set_date_tzinfo from pelican import signals logger = logging.getLogger(__name__) class Writer(object): def __init__(self, output_path, settings=None): self.output_path = output_path self.reminder = dict() self.settings = settings or {} self._written_files = set() self._overridden_files = set() def _create_new_feed(self, feed_type, context): feed_class = Rss201rev2Feed if feed_type == 'rss' else Atom1Feed sitename = Markup(context['SITENAME']).striptags() feed = feed_class( title=sitename, link=(self.site_url + '/'), feed_url=self.feed_url, description=context.get('SITESUBTITLE', '')) return feed def _add_item_to_the_feed(self, feed, item): title = Markup(item.title).striptags() feed.add_item( title=title, link='%s/%s' % (self.site_url, item.url), unique_id='tag:%s,%s:%s' % (self.site_url.replace('http://', ''), item.date.date(), item.url), description=item.get_content(self.site_url), categories=item.tags if hasattr(item, 'tags') else None, author_name=getattr(item, 'author', ''), pubdate=set_date_tzinfo(item.date, self.settings.get('TIMEZONE', None))) def _open_w(self, filename, encoding, override=False): """Open a file to write some content to it. Exit if we have already written to that file, unless one (and no more than one) of the writes has the override parameter set to True. """ if filename in self._overridden_files: if override: raise StandardError('File %s is set to be overridden twice' % filename) else: logger.info('skipping %s' % filename) filename = os.devnull elif filename in self._written_files: if override: logger.info('overwriting %s' % filename) else: raise StandardError('File %s is to be overwritten' % filename) if override: self._overridden_files.add(filename) self._written_files.add(filename) return open(filename, 'w', encoding=encoding) def write_feed(self, elements, context, path=None, feed_type='atom'): """Generate a feed with the list of articles provided Return the feed. If no path or output_path is specified, just return the feed object. :param elements: the articles to put on the feed. :param context: the context to get the feed metadata. :param path: the path to output. :param feed_type: the feed type to use (atom or rss) """ old_locale = locale.setlocale(locale.LC_ALL) locale.setlocale(locale.LC_ALL, str('C')) try: self.site_url = context.get( 'SITEURL', path_to_url(get_relative_path(path))) self.feed_domain = context.get('FEED_DOMAIN') self.feed_url = '{}/{}'.format(self.feed_domain, path) feed = self._create_new_feed(feed_type, context) max_items = len(elements) if self.settings['FEED_MAX_ITEMS']: max_items = min(self.settings['FEED_MAX_ITEMS'], max_items) for i in range(max_items): self._add_item_to_the_feed(feed, elements[i]) if path: complete_path = os.path.join(self.output_path, path) try: os.makedirs(os.path.dirname(complete_path)) except Exception: pass encoding = 'utf-8' if six.PY3 else None with self._open_w(complete_path, encoding) as fp: feed.write(fp, 'utf-8') logger.info('writing %s' % complete_path) return feed finally: locale.setlocale(locale.LC_ALL, old_locale) def write_file(self, name, template, context, relative_urls=False, paginated=None, override_output=False, **kwargs): """Render the template and write the file. :param name: name of the file to output :param template: template to use to generate the content :param context: dict to pass to the templates. :param relative_urls: use relative urls or absolutes ones :param paginated: dict of article list to paginate - must have the same length (same list in different orders) :param override_output: boolean telling if we can override previous output with the same name (and if next files written with the same name should be skipped to keep that one) :param **kwargs: additional variables to pass to the templates """ if name is False: return elif not name: # other stuff, just return for now return def _write_file(template, localcontext, output_path, name, override): """Render the template write the file.""" old_locale = locale.setlocale(locale.LC_ALL) locale.setlocale(locale.LC_ALL, str('C')) try: output = template.render(localcontext) finally: locale.setlocale(locale.LC_ALL, old_locale) path = os.path.join(output_path, name) try: os.makedirs(os.path.dirname(path)) except Exception: pass with self._open_w(path, 'utf-8', override=override) as f: f.write(output) logger.info('writing {}'.format(path)) # Send a signal to say we're writing a file with some specific # local context. signals.content_written.send(path, context=localcontext) localcontext = context.copy() if relative_urls: relative_url = path_to_url(get_relative_path(name)) context['localsiteurl'] = relative_url localcontext['SITEURL'] = relative_url localcontext['output_file'] = name localcontext.update(kwargs) # check paginated paginated = paginated or {} if paginated: name_root = os.path.splitext(name)[0] # pagination needed, init paginators paginators = {} for key in paginated.keys(): object_list = paginated[key] paginators[key] = Paginator( name_root, object_list, self.settings, ) # generated pages, and write for page_num in range(list(paginators.values())[0].num_pages): paginated_localcontext = localcontext.copy() for key in paginators.keys(): paginator = paginators[key] previous_page = paginator.page(page_num) \ if page_num > 0 else None page = paginator.page(page_num + 1) next_page = paginator.page(page_num + 2) \ if page_num + 1 < paginator.num_pages else None paginated_localcontext.update( {'%s_paginator' % key: paginator, '%s_page' % key: page, '%s_previous_page' % key: previous_page, '%s_next_page' % key: next_page}) _write_file(template, paginated_localcontext, self.output_path, page.save_as, override_output) else: # no pagination _write_file(template, localcontext, self.output_path, name, override_output) pelican-3.3/pelican.egg-info/0000755000076500000240000000000012220367225015631 5ustar jmstaff00000000000000pelican-3.3/pelican.egg-info/dependency_links.txt0000666000076500000240000000000112220367224021702 0ustar jmstaff00000000000000 pelican-3.3/pelican.egg-info/entry_points.txt0000666000076500000240000000031312220367224021127 0ustar jmstaff00000000000000[console_scripts] pelican = pelican:main pelican-import = pelican.tools.pelican_import:main pelican-quickstart = pelican.tools.pelican_quickstart:main pelican-themes = pelican.tools.pelican_themes:main pelican-3.3/pelican.egg-info/PKG-INFO0000644000076500000240000003021412220367224016725 0ustar jmstaff00000000000000Metadata-Version: 1.1 Name: pelican Version: 3.3 Summary: A tool to generate a static blog from reStructuredText or Markdown input files. Home-page: http://getpelican.com/ Author: Alexis Metaireau Author-email: authors@getpelican.com License: UNKNOWN Description: Pelican ======= .. image:: https://secure.travis-ci.org/getpelican/pelican.png?branch=master :target: http://travis-ci.org/getpelican/pelican :alt: Travis-ci: continuous integration status. Pelican is a static site generator, written in Python_. * Write your weblog entries directly with your editor of choice (vim!) in reStructuredText_ or Markdown_ * Includes a simple CLI tool to (re)generate the weblog * Easy to interface with DVCSes and web hooks * Completely static output is easy to host anywhere Features -------- Pelican currently supports: * Blog articles and pages * Comments, via an external service (Disqus). (Please note that while useful, Disqus is an external service, and thus the comment data will be somewhat outside of your control and potentially subject to data loss.) * Theming support (themes are created using Jinja2_ templates) * PDF generation of the articles/pages (optional) * Publication of articles in multiple languages * Atom/RSS feeds * Code syntax highlighting * Import from WordPress, Dotclear, or RSS feeds * Integration with external tools: Twitter, Google Analytics, etc. (optional) Have a look at the `Pelican documentation`_ for more information. Why the name "Pelican"? ----------------------- "Pelican" is an anagram for *calepin*, which means "notebook" in French. ;) Source code ----------- You can access the source code at: https://github.com/getpelican/pelican If you feel hackish, have a look at the explanation of `Pelican's internals`_. Feedback / Contact us --------------------- If you want to see new features in Pelican, don't hesitate to offer suggestions, clone the repository, etc. There are many ways to contribute_. That's open source, dude! Send a message to "authors at getpelican dot com" with any requests/feedback! You can also join the team at `#pelican on Freenode`_ (or if you don't have an IRC client handy, use the webchat_ for quick feedback. .. Links .. _Python: http://www.python.org/ .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Markdown: http://daringfireball.net/projects/markdown/ .. _Jinja2: http://jinja.pocoo.org/ .. _`Pelican documentation`: http://docs.getpelican.com/3.3.0/ .. _`Pelican's internals`: http://docs.getpelican.com/en/latest/internals.html .. _`#pelican on Freenode`: irc://irc.freenode.net/pelican .. _webchat: http://webchat.freenode.net/?channels=pelican&uio=d4 .. _contribute: http://docs.getpelican.com/en/latest/contribute.html Release history ############### 3.3.0 (2013-09-24) ================== * Drop Python 3.2 support in favor of Python 3.3 * Add ``Fabfile`` so Fabric can be used for workflow automation instead of Make * ``OUTPUT_RETENTION`` setting can be used to preserve metadata (e.g., VCS data such as ``.hg`` and ``.git``) from being removed from output directory * Tumblr import * Improve logic and consistency when cleaning output folder * Improve documentation versioning and release automation * Improve pagination flexibility * Rename signals for better consistency (some plugins may need to be updated) * Move metadata extraction from generators to readers; metadata extraction no longer article-specific * Deprecate ``FILES_TO_COPY`` in favor of ``STATIC_PATHS`` and ``EXTRA_PATH_METADATA`` * Summaries in Markdown posts no longer include footnotes * Remove unnecessary whitespace in output via ``lstrip_blocks`` Jinja parameter * Move PDF generation from core to plugin * Replace ``MARKUP`` setting with ``READERS`` * Add warning if img tag is missing ``alt`` attribute * Add support for ``{}`` in relative links syntax, besides ``||`` * Add support for ``{tag}`` and ``{category}`` relative links * Add a ``content_written`` signal 3.2.1 and 3.2.2 =============== * Facilitate inclusion in FreeBSD Ports Collection 3.2 (2013-04-24) ================ * Support for Python 3! * Override page save-to location from meta-data (enables using a static page as the site's home page, for example) * Time period archives (per-year, per-month, and per-day archives of posts) * Posterous blog import * Improve WordPress blog import * Migrate plugins to separate repository * Improve HTML parser * Provide ability to show or hide categories from menu using ``DISPLAY_CATEGORIES_ON_MENU`` option * Auto-regeneration can be told to ignore files via ``IGNORE_FILES`` setting * Improve post-generation feedback to user * For multilingual posts, use meta-data to designate which is the original and which is the translation * Add ``.mdown`` to list of supported Markdown file extensions * Document-relative URL generation (``RELATIVE_URLS``) is now off by default 3.1 (2012-12-04) ================ * Importer now stores slugs within files by default. This can be disabled with the ``--disable-slugs`` option. * Improve handling of links to intra-site resources * Ensure WordPress import adds paragraphs for all types of line endings in post content * Decode HTML entities within WordPress post titles on import * Improve appearance of LinkedIn icon in default theme * Add GitHub and Google+ social icons support in default theme * Optimize social icons * Add ``FEED_ALL_ATOM`` and ``FEED_ALL_RSS`` to generate feeds containing all posts regardless of their language * Split ``TRANSLATION_FEED`` into ``TRANSLATION_FEED_ATOM`` and ``TRANSLATION_FEED_RSS`` * Different feeds can now be enabled/disabled individually * Allow for blank author: if ``AUTHOR`` setting is not set, author won't default to ``${USER}`` anymore, and a post won't contain any author information if the post author is empty * Move LESS and Webassets support from Pelican core to plugin * The ``DEFAULT_DATE`` setting now defaults to ``None``, which means that articles won't be generated unless date metadata is specified * Add ``FILENAME_METADATA`` setting to support metadata extraction from filename * Add ``gzip_cache`` plugin to compress common text files into a ``.gz`` file within the same directory as the original file, preventing the server (e.g. Nginx) from having to compress files during an HTTP call * Add support for AsciiDoc-formatted content * Add ``USE_FOLDER_AS_CATEGORY`` setting so that feature can be toggled on/off * Support arbitrary Jinja template files * Restore basic functional tests * New signals: ``generator_init``, ``get_generators``, and ``article_generate_preread`` 3.0 (2012-08-08) ================ * Refactored the way URLs are handled * Improved the English documentation * Fixed packaging using ``setuptools`` entrypoints * Added ``typogrify`` support * Added a way to disable feed generation * Added support for ``DIRECT_TEMPLATES`` * Allow multiple extensions for content files * Added LESS support * Improved the import script * Added functional tests * Rsync support in the generated Makefile * Improved feed support (easily pluggable with Feedburner for instance) * Added support for ``abbr`` in reST * Fixed a bunch of bugs :-) 2.8 (2012-02-28) ================== * Dotclear importer * Allow the usage of Markdown extensions * Themes are now easily extensible * Don't output pagination information if there is only one page * Add a page per author, with all their articles * Improved the test suite * Made the themes easier to extend * Removed Skribit support * Added a ``pelican-quickstart`` script * Fixed timezone-related issues * Added some scripts for Windows support * Date can be specified in seconds * Never fail when generating posts (skip and continue) * Allow the use of future dates * Support having different timezones per language * Enhanced the documentation 2.7 (2011-06-11) ================== * Use ``logging`` rather than echoing to stdout * Support custom Jinja filters * Compatibility with Python 2.5 * Added a theme manager * Packaged for Debian * Added draft support 2.6 (2011-03-08) ================== * Changes in the output directory structure * Makes templates easier to work with / create * Added RSS support (was Atom-only) * Added tag support for the feeds * Enhance the documentation * Added another theme (brownstone) * Added translations * Added a way to use cleaner URLs with a rewrite url module (or equivalent) * Added a tag cloud * Added an autoreloading feature: the blog is automatically regenerated each time a modification is detected * Translate the documentation into French * Import a blog from an RSS feed * Pagination support * Added Skribit support 2.5 (2010-11-20) ================== * Import from Wordpress * Added some new themes (martyalchin / wide-notmyidea) * First bug report! * Linkedin support * Added a FAQ * Google Analytics support * Twitter support * Use relative URLs, not static ones 2.4 (2010-11-06) ================ * Minor themes changes * Add Disqus support (so we have comments) * Another code refactoring * Added config settings about pages * Blog entries can also be generated in PDF 2.3 (2010-10-31) ================ * Markdown support 2.2 (2010-10-30) ================ * Prettify output * Manages static pages as well 2.1 (2010-10-30) ================ * Make notmyidea the default theme 2.0 (2010-10-30) ================ * Refactoring to be more extensible * Change into the setting variables 1.2 (2010-09-28) ================ * Added a debug option * Added per-category feeds * Use filesystem to get dates if no metadata is provided * Add Pygments support 1.1 (2010-08-19) ================ * First working version Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: License :: OSI Approved :: GNU Affero General Public License v3 Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Software Development :: Libraries :: Python Modules pelican-3.3/pelican.egg-info/requires.txt0000666000076500000240000000012512220367224020232 0ustar jmstaff00000000000000feedgenerator >= 1.6 jinja2 >= 2.7 pygments docutils pytz >= 0a blinker unidecode sixpelican-3.3/pelican.egg-info/SOURCES.txt0000666000076500000240000003040212220367224017517 0ustar jmstaff00000000000000CONTRIBUTING.rst LICENSE MANIFEST.in README.rst THANKS setup.py docs/changelog.rst docs/conf.py pelican/__init__.py pelican/contents.py pelican/generators.py pelican/log.py pelican/paginator.py pelican/readers.py pelican/rstdirectives.py pelican/server.py pelican/settings.py pelican/signals.py pelican/urlwrappers.py pelican/utils.py pelican/writers.py pelican.egg-info/PKG-INFO pelican.egg-info/SOURCES.txt pelican.egg-info/dependency_links.txt pelican.egg-info/entry_points.txt pelican.egg-info/requires.txt pelican.egg-info/top_level.txt pelican/tests/__init__.py pelican/tests/default_conf.py pelican/tests/support.py pelican/tests/test_contents.py pelican/tests/test_generators.py pelican/tests/test_importer.py pelican/tests/test_pelican.py pelican/tests/test_readers.py pelican/tests/test_settings.py pelican/tests/test_utils.py pelican/tests/TestPages/bad_page.rst pelican/tests/TestPages/hidden_page.rst pelican/tests/TestPages/hidden_page_markdown.md pelican/tests/TestPages/hidden_page_with_template.rst pelican/tests/TestPages/page.rst pelican/tests/TestPages/page_markdown.md pelican/tests/TestPages/page_with_template.rst pelican/tests/content/2012-11-29_rst_w_filename_meta#foo-bar.rst pelican/tests/content/2012-11-30_md_w_filename_meta#foo-bar.md pelican/tests/content/article.rst pelican/tests/content/article_with_comments.html pelican/tests/content/article_with_keywords.html pelican/tests/content/article_with_markdown_and_footnote.md pelican/tests/content/article_with_markdown_and_nonascii_summary.md pelican/tests/content/article_with_markdown_and_summary_metadata_multi.md pelican/tests/content/article_with_markdown_and_summary_metadata_single.md pelican/tests/content/article_with_markdown_markup_extensions.md pelican/tests/content/article_with_md_extension.md pelican/tests/content/article_with_metadata.html pelican/tests/content/article_with_metadata.rst pelican/tests/content/article_with_metadata_and_contents.html pelican/tests/content/article_with_mkd_extension.mkd pelican/tests/content/article_with_null_attributes.html pelican/tests/content/article_with_template.rst pelican/tests/content/article_with_uppercase_metadata.html pelican/tests/content/article_with_uppercase_metadata.rst pelican/tests/content/article_without_category.rst pelican/tests/content/wordpressexport.xml pelican/tests/content/TestCategory/article_with_category.rst pelican/tests/content/TestCategory/article_without_category.rst pelican/tests/output/basic/a-markdown-powered-article.html pelican/tests/output/basic/archives.html pelican/tests/output/basic/article-1.html pelican/tests/output/basic/article-2.html pelican/tests/output/basic/article-3.html pelican/tests/output/basic/authors.html pelican/tests/output/basic/categories.html pelican/tests/output/basic/filename_metadata-example.html pelican/tests/output/basic/index.html pelican/tests/output/basic/oh-yeah.html pelican/tests/output/basic/second-article-fr.html pelican/tests/output/basic/second-article.html pelican/tests/output/basic/tags.html pelican/tests/output/basic/this-is-a-super-article.html pelican/tests/output/basic/unbelievable.html pelican/tests/output/basic/author/alexis-metaireau.html pelican/tests/output/basic/category/bar.html pelican/tests/output/basic/category/cat1.html pelican/tests/output/basic/category/misc.html pelican/tests/output/basic/category/yeah.html pelican/tests/output/basic/feeds/all-en.atom.xml pelican/tests/output/basic/feeds/all-fr.atom.xml pelican/tests/output/basic/feeds/all.atom.xml pelican/tests/output/basic/feeds/bar.atom.xml pelican/tests/output/basic/feeds/cat1.atom.xml pelican/tests/output/basic/feeds/misc.atom.xml pelican/tests/output/basic/feeds/yeah.atom.xml pelican/tests/output/basic/override/index.html pelican/tests/output/basic/pages/this-is-a-test-hidden-page.html pelican/tests/output/basic/pages/this-is-a-test-page.html pelican/tests/output/basic/tag/bar.html pelican/tests/output/basic/tag/baz.html pelican/tests/output/basic/tag/foo.html pelican/tests/output/basic/tag/foobar.html pelican/tests/output/basic/tag/oh.html pelican/tests/output/basic/tag/yeah.html pelican/tests/output/basic/theme/css/main.css pelican/tests/output/basic/theme/css/pygment.css pelican/tests/output/basic/theme/css/reset.css pelican/tests/output/basic/theme/css/typogrify.css pelican/tests/output/basic/theme/css/wide.css pelican/tests/output/basic/theme/images/icons/aboutme.png pelican/tests/output/basic/theme/images/icons/bitbucket.png pelican/tests/output/basic/theme/images/icons/delicious.png pelican/tests/output/basic/theme/images/icons/facebook.png pelican/tests/output/basic/theme/images/icons/github.png pelican/tests/output/basic/theme/images/icons/gitorious.png pelican/tests/output/basic/theme/images/icons/gittip.png pelican/tests/output/basic/theme/images/icons/google-groups.png pelican/tests/output/basic/theme/images/icons/google-plus.png pelican/tests/output/basic/theme/images/icons/hackernews.png pelican/tests/output/basic/theme/images/icons/lastfm.png pelican/tests/output/basic/theme/images/icons/linkedin.png pelican/tests/output/basic/theme/images/icons/reddit.png pelican/tests/output/basic/theme/images/icons/rss.png pelican/tests/output/basic/theme/images/icons/slideshare.png pelican/tests/output/basic/theme/images/icons/speakerdeck.png pelican/tests/output/basic/theme/images/icons/stackoverflow.png pelican/tests/output/basic/theme/images/icons/twitter.png pelican/tests/output/basic/theme/images/icons/vimeo.png pelican/tests/output/basic/theme/images/icons/youtube.png pelican/tests/output/custom/a-markdown-powered-article.html pelican/tests/output/custom/archives.html pelican/tests/output/custom/article-1.html pelican/tests/output/custom/article-2.html pelican/tests/output/custom/article-3.html pelican/tests/output/custom/authors.html pelican/tests/output/custom/categories.html pelican/tests/output/custom/filename_metadata-example.html pelican/tests/output/custom/index.html pelican/tests/output/custom/index2.html pelican/tests/output/custom/index3.html pelican/tests/output/custom/jinja2_template.html pelican/tests/output/custom/oh-yeah-fr.html pelican/tests/output/custom/oh-yeah.html pelican/tests/output/custom/second-article-fr.html pelican/tests/output/custom/second-article.html pelican/tests/output/custom/tags.html pelican/tests/output/custom/this-is-a-super-article.html pelican/tests/output/custom/unbelievable.html pelican/tests/output/custom/author/alexis-metaireau.html pelican/tests/output/custom/author/alexis-metaireau2.html pelican/tests/output/custom/author/alexis-metaireau3.html pelican/tests/output/custom/category/bar.html pelican/tests/output/custom/category/cat1.html pelican/tests/output/custom/category/misc.html pelican/tests/output/custom/category/yeah.html pelican/tests/output/custom/drafts/a-draft-article.html pelican/tests/output/custom/feeds/all-en.atom.xml pelican/tests/output/custom/feeds/all-fr.atom.xml pelican/tests/output/custom/feeds/all.atom.xml pelican/tests/output/custom/feeds/all.rss.xml pelican/tests/output/custom/feeds/bar.atom.xml pelican/tests/output/custom/feeds/bar.rss.xml pelican/tests/output/custom/feeds/cat1.atom.xml pelican/tests/output/custom/feeds/cat1.rss.xml pelican/tests/output/custom/feeds/misc.atom.xml pelican/tests/output/custom/feeds/misc.rss.xml pelican/tests/output/custom/feeds/yeah.atom.xml pelican/tests/output/custom/feeds/yeah.rss.xml pelican/tests/output/custom/override/index.html pelican/tests/output/custom/pages/this-is-a-test-hidden-page.html pelican/tests/output/custom/pages/this-is-a-test-page.html pelican/tests/output/custom/tag/bar.html pelican/tests/output/custom/tag/baz.html pelican/tests/output/custom/tag/foo.html pelican/tests/output/custom/tag/foobar.html pelican/tests/output/custom/tag/oh.html pelican/tests/output/custom/tag/yeah.html pelican/tests/output/custom/theme/css/main.css pelican/tests/output/custom/theme/css/pygment.css pelican/tests/output/custom/theme/css/reset.css pelican/tests/output/custom/theme/css/typogrify.css pelican/tests/output/custom/theme/css/wide.css pelican/tests/output/custom/theme/images/icons/aboutme.png pelican/tests/output/custom/theme/images/icons/bitbucket.png pelican/tests/output/custom/theme/images/icons/delicious.png pelican/tests/output/custom/theme/images/icons/facebook.png pelican/tests/output/custom/theme/images/icons/github.png pelican/tests/output/custom/theme/images/icons/gitorious.png pelican/tests/output/custom/theme/images/icons/gittip.png pelican/tests/output/custom/theme/images/icons/google-groups.png pelican/tests/output/custom/theme/images/icons/google-plus.png pelican/tests/output/custom/theme/images/icons/hackernews.png pelican/tests/output/custom/theme/images/icons/lastfm.png pelican/tests/output/custom/theme/images/icons/linkedin.png pelican/tests/output/custom/theme/images/icons/reddit.png pelican/tests/output/custom/theme/images/icons/rss.png pelican/tests/output/custom/theme/images/icons/slideshare.png pelican/tests/output/custom/theme/images/icons/speakerdeck.png pelican/tests/output/custom/theme/images/icons/stackoverflow.png pelican/tests/output/custom/theme/images/icons/twitter.png pelican/tests/output/custom/theme/images/icons/vimeo.png pelican/tests/output/custom/theme/images/icons/youtube.png pelican/themes/notmyidea/static/css/main.css pelican/themes/notmyidea/static/css/pygment.css pelican/themes/notmyidea/static/css/reset.css pelican/themes/notmyidea/static/css/typogrify.css pelican/themes/notmyidea/static/css/wide.css pelican/themes/notmyidea/static/images/icons/aboutme.png pelican/themes/notmyidea/static/images/icons/bitbucket.png pelican/themes/notmyidea/static/images/icons/delicious.png pelican/themes/notmyidea/static/images/icons/facebook.png pelican/themes/notmyidea/static/images/icons/github.png pelican/themes/notmyidea/static/images/icons/gitorious.png pelican/themes/notmyidea/static/images/icons/gittip.png pelican/themes/notmyidea/static/images/icons/google-groups.png pelican/themes/notmyidea/static/images/icons/google-plus.png pelican/themes/notmyidea/static/images/icons/hackernews.png pelican/themes/notmyidea/static/images/icons/lastfm.png pelican/themes/notmyidea/static/images/icons/linkedin.png pelican/themes/notmyidea/static/images/icons/reddit.png pelican/themes/notmyidea/static/images/icons/rss.png pelican/themes/notmyidea/static/images/icons/slideshare.png pelican/themes/notmyidea/static/images/icons/speakerdeck.png pelican/themes/notmyidea/static/images/icons/stackoverflow.png pelican/themes/notmyidea/static/images/icons/twitter.png pelican/themes/notmyidea/static/images/icons/vimeo.png pelican/themes/notmyidea/static/images/icons/youtube.png pelican/themes/notmyidea/templates/analytics.html pelican/themes/notmyidea/templates/archives.html pelican/themes/notmyidea/templates/article.html pelican/themes/notmyidea/templates/article_infos.html pelican/themes/notmyidea/templates/author.html pelican/themes/notmyidea/templates/authors.html pelican/themes/notmyidea/templates/base.html pelican/themes/notmyidea/templates/category.html pelican/themes/notmyidea/templates/comments.html pelican/themes/notmyidea/templates/disqus_script.html pelican/themes/notmyidea/templates/github.html pelican/themes/notmyidea/templates/index.html pelican/themes/notmyidea/templates/page.html pelican/themes/notmyidea/templates/piwik.html pelican/themes/notmyidea/templates/tag.html pelican/themes/notmyidea/templates/taglist.html pelican/themes/notmyidea/templates/tags.html pelican/themes/notmyidea/templates/translations.html pelican/themes/notmyidea/templates/twitter.html pelican/themes/simple/templates/archives.html pelican/themes/simple/templates/article.html pelican/themes/simple/templates/author.html pelican/themes/simple/templates/authors.html pelican/themes/simple/templates/base.html pelican/themes/simple/templates/categories.html pelican/themes/simple/templates/category.html pelican/themes/simple/templates/gosquared.html pelican/themes/simple/templates/index.html pelican/themes/simple/templates/page.html pelican/themes/simple/templates/pagination.html pelican/themes/simple/templates/tag.html pelican/themes/simple/templates/tags.html pelican/themes/simple/templates/translations.html pelican/tools/__init__.py pelican/tools/pelican_import.py pelican/tools/pelican_quickstart.py pelican/tools/pelican_themes.py pelican/tools/templates/Makefile.in pelican/tools/templates/develop_server.sh.in pelican/tools/templates/fabfile.py.in pelican/tools/templates/pelicanconf.py.in pelican/tools/templates/publishconf.py.in samples/pelican.conf.pypelican-3.3/pelican.egg-info/top_level.txt0000666000076500000240000000001012220367224020355 0ustar jmstaff00000000000000pelican pelican-3.3/PKG-INFO0000644000076500000240000003021412220367225013621 0ustar jmstaff00000000000000Metadata-Version: 1.1 Name: pelican Version: 3.3 Summary: A tool to generate a static blog from reStructuredText or Markdown input files. Home-page: http://getpelican.com/ Author: Alexis Metaireau Author-email: authors@getpelican.com License: UNKNOWN Description: Pelican ======= .. image:: https://secure.travis-ci.org/getpelican/pelican.png?branch=master :target: http://travis-ci.org/getpelican/pelican :alt: Travis-ci: continuous integration status. Pelican is a static site generator, written in Python_. * Write your weblog entries directly with your editor of choice (vim!) in reStructuredText_ or Markdown_ * Includes a simple CLI tool to (re)generate the weblog * Easy to interface with DVCSes and web hooks * Completely static output is easy to host anywhere Features -------- Pelican currently supports: * Blog articles and pages * Comments, via an external service (Disqus). (Please note that while useful, Disqus is an external service, and thus the comment data will be somewhat outside of your control and potentially subject to data loss.) * Theming support (themes are created using Jinja2_ templates) * PDF generation of the articles/pages (optional) * Publication of articles in multiple languages * Atom/RSS feeds * Code syntax highlighting * Import from WordPress, Dotclear, or RSS feeds * Integration with external tools: Twitter, Google Analytics, etc. (optional) Have a look at the `Pelican documentation`_ for more information. Why the name "Pelican"? ----------------------- "Pelican" is an anagram for *calepin*, which means "notebook" in French. ;) Source code ----------- You can access the source code at: https://github.com/getpelican/pelican If you feel hackish, have a look at the explanation of `Pelican's internals`_. Feedback / Contact us --------------------- If you want to see new features in Pelican, don't hesitate to offer suggestions, clone the repository, etc. There are many ways to contribute_. That's open source, dude! Send a message to "authors at getpelican dot com" with any requests/feedback! You can also join the team at `#pelican on Freenode`_ (or if you don't have an IRC client handy, use the webchat_ for quick feedback. .. Links .. _Python: http://www.python.org/ .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Markdown: http://daringfireball.net/projects/markdown/ .. _Jinja2: http://jinja.pocoo.org/ .. _`Pelican documentation`: http://docs.getpelican.com/3.3.0/ .. _`Pelican's internals`: http://docs.getpelican.com/en/latest/internals.html .. _`#pelican on Freenode`: irc://irc.freenode.net/pelican .. _webchat: http://webchat.freenode.net/?channels=pelican&uio=d4 .. _contribute: http://docs.getpelican.com/en/latest/contribute.html Release history ############### 3.3.0 (2013-09-24) ================== * Drop Python 3.2 support in favor of Python 3.3 * Add ``Fabfile`` so Fabric can be used for workflow automation instead of Make * ``OUTPUT_RETENTION`` setting can be used to preserve metadata (e.g., VCS data such as ``.hg`` and ``.git``) from being removed from output directory * Tumblr import * Improve logic and consistency when cleaning output folder * Improve documentation versioning and release automation * Improve pagination flexibility * Rename signals for better consistency (some plugins may need to be updated) * Move metadata extraction from generators to readers; metadata extraction no longer article-specific * Deprecate ``FILES_TO_COPY`` in favor of ``STATIC_PATHS`` and ``EXTRA_PATH_METADATA`` * Summaries in Markdown posts no longer include footnotes * Remove unnecessary whitespace in output via ``lstrip_blocks`` Jinja parameter * Move PDF generation from core to plugin * Replace ``MARKUP`` setting with ``READERS`` * Add warning if img tag is missing ``alt`` attribute * Add support for ``{}`` in relative links syntax, besides ``||`` * Add support for ``{tag}`` and ``{category}`` relative links * Add a ``content_written`` signal 3.2.1 and 3.2.2 =============== * Facilitate inclusion in FreeBSD Ports Collection 3.2 (2013-04-24) ================ * Support for Python 3! * Override page save-to location from meta-data (enables using a static page as the site's home page, for example) * Time period archives (per-year, per-month, and per-day archives of posts) * Posterous blog import * Improve WordPress blog import * Migrate plugins to separate repository * Improve HTML parser * Provide ability to show or hide categories from menu using ``DISPLAY_CATEGORIES_ON_MENU`` option * Auto-regeneration can be told to ignore files via ``IGNORE_FILES`` setting * Improve post-generation feedback to user * For multilingual posts, use meta-data to designate which is the original and which is the translation * Add ``.mdown`` to list of supported Markdown file extensions * Document-relative URL generation (``RELATIVE_URLS``) is now off by default 3.1 (2012-12-04) ================ * Importer now stores slugs within files by default. This can be disabled with the ``--disable-slugs`` option. * Improve handling of links to intra-site resources * Ensure WordPress import adds paragraphs for all types of line endings in post content * Decode HTML entities within WordPress post titles on import * Improve appearance of LinkedIn icon in default theme * Add GitHub and Google+ social icons support in default theme * Optimize social icons * Add ``FEED_ALL_ATOM`` and ``FEED_ALL_RSS`` to generate feeds containing all posts regardless of their language * Split ``TRANSLATION_FEED`` into ``TRANSLATION_FEED_ATOM`` and ``TRANSLATION_FEED_RSS`` * Different feeds can now be enabled/disabled individually * Allow for blank author: if ``AUTHOR`` setting is not set, author won't default to ``${USER}`` anymore, and a post won't contain any author information if the post author is empty * Move LESS and Webassets support from Pelican core to plugin * The ``DEFAULT_DATE`` setting now defaults to ``None``, which means that articles won't be generated unless date metadata is specified * Add ``FILENAME_METADATA`` setting to support metadata extraction from filename * Add ``gzip_cache`` plugin to compress common text files into a ``.gz`` file within the same directory as the original file, preventing the server (e.g. Nginx) from having to compress files during an HTTP call * Add support for AsciiDoc-formatted content * Add ``USE_FOLDER_AS_CATEGORY`` setting so that feature can be toggled on/off * Support arbitrary Jinja template files * Restore basic functional tests * New signals: ``generator_init``, ``get_generators``, and ``article_generate_preread`` 3.0 (2012-08-08) ================ * Refactored the way URLs are handled * Improved the English documentation * Fixed packaging using ``setuptools`` entrypoints * Added ``typogrify`` support * Added a way to disable feed generation * Added support for ``DIRECT_TEMPLATES`` * Allow multiple extensions for content files * Added LESS support * Improved the import script * Added functional tests * Rsync support in the generated Makefile * Improved feed support (easily pluggable with Feedburner for instance) * Added support for ``abbr`` in reST * Fixed a bunch of bugs :-) 2.8 (2012-02-28) ================== * Dotclear importer * Allow the usage of Markdown extensions * Themes are now easily extensible * Don't output pagination information if there is only one page * Add a page per author, with all their articles * Improved the test suite * Made the themes easier to extend * Removed Skribit support * Added a ``pelican-quickstart`` script * Fixed timezone-related issues * Added some scripts for Windows support * Date can be specified in seconds * Never fail when generating posts (skip and continue) * Allow the use of future dates * Support having different timezones per language * Enhanced the documentation 2.7 (2011-06-11) ================== * Use ``logging`` rather than echoing to stdout * Support custom Jinja filters * Compatibility with Python 2.5 * Added a theme manager * Packaged for Debian * Added draft support 2.6 (2011-03-08) ================== * Changes in the output directory structure * Makes templates easier to work with / create * Added RSS support (was Atom-only) * Added tag support for the feeds * Enhance the documentation * Added another theme (brownstone) * Added translations * Added a way to use cleaner URLs with a rewrite url module (or equivalent) * Added a tag cloud * Added an autoreloading feature: the blog is automatically regenerated each time a modification is detected * Translate the documentation into French * Import a blog from an RSS feed * Pagination support * Added Skribit support 2.5 (2010-11-20) ================== * Import from Wordpress * Added some new themes (martyalchin / wide-notmyidea) * First bug report! * Linkedin support * Added a FAQ * Google Analytics support * Twitter support * Use relative URLs, not static ones 2.4 (2010-11-06) ================ * Minor themes changes * Add Disqus support (so we have comments) * Another code refactoring * Added config settings about pages * Blog entries can also be generated in PDF 2.3 (2010-10-31) ================ * Markdown support 2.2 (2010-10-30) ================ * Prettify output * Manages static pages as well 2.1 (2010-10-30) ================ * Make notmyidea the default theme 2.0 (2010-10-30) ================ * Refactoring to be more extensible * Change into the setting variables 1.2 (2010-09-28) ================ * Added a debug option * Added per-category feeds * Use filesystem to get dates if no metadata is provided * Add Pygments support 1.1 (2010-08-19) ================ * First working version Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Console Classifier: License :: OSI Approved :: GNU Affero General Public License v3 Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Software Development :: Libraries :: Python Modules pelican-3.3/README.rst0000644000076500000240000000466212220367223014221 0ustar jmstaff00000000000000Pelican ======= .. image:: https://secure.travis-ci.org/getpelican/pelican.png?branch=master :target: http://travis-ci.org/getpelican/pelican :alt: Travis-ci: continuous integration status. Pelican is a static site generator, written in Python_. * Write your weblog entries directly with your editor of choice (vim!) in reStructuredText_ or Markdown_ * Includes a simple CLI tool to (re)generate the weblog * Easy to interface with DVCSes and web hooks * Completely static output is easy to host anywhere Features -------- Pelican currently supports: * Blog articles and pages * Comments, via an external service (Disqus). (Please note that while useful, Disqus is an external service, and thus the comment data will be somewhat outside of your control and potentially subject to data loss.) * Theming support (themes are created using Jinja2_ templates) * PDF generation of the articles/pages (optional) * Publication of articles in multiple languages * Atom/RSS feeds * Code syntax highlighting * Import from WordPress, Dotclear, or RSS feeds * Integration with external tools: Twitter, Google Analytics, etc. (optional) Have a look at the `Pelican documentation`_ for more information. Why the name "Pelican"? ----------------------- "Pelican" is an anagram for *calepin*, which means "notebook" in French. ;) Source code ----------- You can access the source code at: https://github.com/getpelican/pelican If you feel hackish, have a look at the explanation of `Pelican's internals`_. Feedback / Contact us --------------------- If you want to see new features in Pelican, don't hesitate to offer suggestions, clone the repository, etc. There are many ways to contribute_. That's open source, dude! Send a message to "authors at getpelican dot com" with any requests/feedback! You can also join the team at `#pelican on Freenode`_ (or if you don't have an IRC client handy, use the webchat_ for quick feedback. .. Links .. _Python: http://www.python.org/ .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Markdown: http://daringfireball.net/projects/markdown/ .. _Jinja2: http://jinja.pocoo.org/ .. _`Pelican documentation`: http://docs.getpelican.com/3.3.0/ .. _`Pelican's internals`: http://docs.getpelican.com/en/latest/internals.html .. _`#pelican on Freenode`: irc://irc.freenode.net/pelican .. _webchat: http://webchat.freenode.net/?channels=pelican&uio=d4 .. _contribute: http://docs.getpelican.com/en/latest/contribute.html pelican-3.3/samples/0000755000076500000240000000000012220367225014170 5ustar jmstaff00000000000000pelican-3.3/samples/pelican.conf.py0000755000076500000240000000317712216354256017121 0ustar jmstaff00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals AUTHOR = 'Alexis Métaireau' SITENAME = "Alexis' log" SITEURL = 'http://blog.notmyidea.org' TIMEZONE = "Europe/Paris" # can be useful in development, but set to False when you're ready to publish RELATIVE_URLS = True GITHUB_URL = 'http://github.com/ametaireau/' DISQUS_SITENAME = "blog-notmyidea" PDF_GENERATOR = False REVERSE_CATEGORY_ORDER = True LOCALE = "C" DEFAULT_PAGINATION = 4 DEFAULT_DATE = (2012, 3, 2, 14, 1, 1) FEED_ALL_RSS = 'feeds/all.rss.xml' CATEGORY_FEED_RSS = 'feeds/%s.rss.xml' LINKS = (('Biologeek', 'http://biologeek.org'), ('Filyb', "http://filyb.info/"), ('Libert-fr', "http://www.libert-fr.com"), ('N1k0', "http://prendreuncafe.com/blog/"), ('Tarek Ziadé', "http://ziade.org/blog"), ('Zubin Mithra', "http://zubin71.wordpress.com/"),) SOCIAL = (('twitter', 'http://twitter.com/ametaireau'), ('lastfm', 'http://lastfm.com/user/akounet'), ('github', 'http://github.com/ametaireau'),) # global metadata to all the contents DEFAULT_METADATA = (('yeah', 'it is'),) # path-specific metadata EXTRA_PATH_METADATA = { 'extra/robots.txt': {'path': 'robots.txt'}, } # static paths will be copied without parsing their contents STATIC_PATHS = [ 'pictures', 'extra/robots.txt', ] # custom page generated with a jinja2 template TEMPLATE_PAGES = {'pages/jinja2_template.html': 'jinja2_template.html'} # code blocks with line numbers PYGMENTS_RST_OPTIONS = {'linenos': 'table'} # foobar will not be used, because it's not in caps. All configuration keys # have to be in caps foobar = "barbaz" pelican-3.3/setup.cfg0000644000076500000240000000007312220367225014345 0ustar jmstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 pelican-3.3/setup.py0000755000076500000240000000306412200765047014246 0ustar jmstaff00000000000000#!/usr/bin/env python from setuptools import setup requires = ['feedgenerator >= 1.6', 'jinja2 >= 2.7', 'pygments', 'docutils', 'pytz >= 0a', 'blinker', 'unidecode', 'six'] entry_points = { 'console_scripts': [ 'pelican = pelican:main', 'pelican-import = pelican.tools.pelican_import:main', 'pelican-quickstart = pelican.tools.pelican_quickstart:main', 'pelican-themes = pelican.tools.pelican_themes:main' ] } README = open('README.rst').read() CHANGELOG = open('docs/changelog.rst').read() setup( name="pelican", version="3.3", url='http://getpelican.com/', author='Alexis Metaireau', author_email='authors@getpelican.com', description="A tool to generate a static blog from reStructuredText or " "Markdown input files.", long_description=README + '\n' + CHANGELOG, packages=['pelican', 'pelican.tools'], include_package_data=True, install_requires=requires, entry_points=entry_points, classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', 'License :: OSI Approved :: GNU Affero General Public License v3', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.3', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Software Development :: Libraries :: Python Modules', ], test_suite='pelican.tests', ) pelican-3.3/THANKS0000666000076500000240000000506212135521746013453 0ustar jmstaff00000000000000Pelican is a project originally created by Alexis Métaireau , but there are a large number of people that have contributed or implemented key features over time. We do our best to keep this list up-to-date, but you can also have a look at the nice contributor graphs produced by GitHub: https://github.com/getpelican/pelican/graphs/contributors If you want to contibute, check the documentation section about how to do so: Aaron Kavlie Abhishek L Albrecht Mühlenschulte Aldiantoro Nugroho Alen Mujezinovic Alessandro Martin Alexander Artemenko Alexandre RODIERE Alexis Daboville Alexis Métaireau Allan Whatmough Andrea Crotti Andrew Laski Andrew Spiers Arnaud BOS asselinpaul Axel Haustant Benoît HERVIER Borgar Brandon W Maister Brendan Wholihan Brian C. Lane Brian Hsu Brian St. Pierre Bruno Binet BunnyMan Chenguang Wang Chris Elston Chris McDonald (Wraithan) Chris Streeter Christophe Chauvet Clint Howarth Colin Dunklau Dafydd Crosby Dana Woodman Dave King Dave Mankoff David Beitey David Marble Deniz Turgut (Avaris) derdon Dirkjan Ochtman Dirk Makowski draftcode Edward Delaporte Emily Strickland epatters Eric Case Erik Hetzner FELD Boris Feth Arezki Florian Jacob Florian Preinstorfer Félix Delval Freeculture George V. Reilly Guillaume Guillaume B Guillermo López guillermooo Ian Cordasco Igor Kalnitsky Irfan Ahmad Iuri de Silvio Ivan Dyedov James King James Rowe jawher Jered Boxman Jerome Jiachen Yang Jochen Breuer joe di castro John Kristensen John Mastro Jökull Sólberg Auðunsson Jomel Imperio Joseph Reagle Joshua Adelman Julian Berman Justin Mayer Kyle Fuller Laureline Guerin Leonard Huang Leroy Jiang Marcel Hellkamp Marco Milanesi Marcus Fredriksson Mario Rodas Mark Caudill Martin Brochhaus Massimo Santini Matt Bowcock Matt Layman Meir Kriheli Michael Guntsche Michael Reneer Michael Yanovich Mike Yumatov Mikhail Korobov m-r-r mviera Nico Di Rocco Nicolas Duhamel Nicolas Perriault Nicolas Steinmetz Paul Asselin Pavel Puchkin Perry Roper Peter Desmet Philippe Pepiot Rachid Belaid Randall Degges Ranjhith Kalisamy Remi Rampin Rémy HUBSCHER renhbo Richard Duivenvoorde Rogdham Roman Skvazh Ronny Pfannschmidt Rory McCann Rıdvan Örsvuran saghul sam Samrat Man Singh Simon Conseil Simon Liedtke Skami18 solsTiCe d'Hiver Steve Schwarz Stéphane Bunel Stéphane Raimbault Stuart Colville Talha Mansoor Tarek Ziade Thanos Lefteris Thomas Thurman Tobias Tomi Pieviläinen Trae Blain Tshepang Lekhonkhobe Valentin-Costel Hăloiu Vlad Niculae William Light Wladislaw Merezhko W. Trevor King Zoresvit