chiark / gitweb /
m.htmlsanity: initial test.
authorVladimír Vondruš <mosra@centrum.cz>
Mon, 11 Dec 2017 00:32:41 +0000 (01:32 +0100)
committerVladimír Vondruš <mosra@centrum.cz>
Mon, 11 Dec 2017 02:03:32 +0000 (03:03 +0100)
16 files changed:
.gitignore
doc/plugins/htmlsanity-test.rst [deleted file]
doxygen/.gitignore
pelican-plugins/m/test/.gitignore [new file with mode: 0644]
pelican-plugins/m/test/__init__.py [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_content/page.html [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_content/page.rst [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography/article-lang.html [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography/articles/lang.rst [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography/page-lang.html [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography/page-lang.rst [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography/page.html [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography/page.rst [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography_global_lang/page.html [new file with mode: 0644]
pelican-plugins/m/test/htmlsanity_typography_global_lang/page.rst [new file with mode: 0644]
pelican-plugins/m/test/test_htmlsanity.py [new file with mode: 0644]

index 1e0752e841f7fa0e76bb2311db48bbfd45e5efc0..c156db4d3390679107608f558538046700669276 100644 (file)
@@ -1,2 +1,4 @@
 __pycache__
+htmlcov
+.coverage
 *.kdev4
diff --git a/doc/plugins/htmlsanity-test.rst b/doc/plugins/htmlsanity-test.rst
deleted file mode 100644 (file)
index 9acb94e..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-..
-    This file is part of m.css.
-
-    Copyright © 2017 Vladimír Vondruš <mosra@centrum.cz>
-
-    Permission is hereby granted, free of charge, to any person obtaining a
-    copy of this software and associated documentation files (the "Software"),
-    to deal in the Software without restriction, including without limitation
-    the rights to use, copy, modify, merge, publish, distribute, sublicense,
-    and/or sell copies of the Software, and to permit persons to whom the
-    Software is furnished to do so, subject to the following conditions:
-
-    The above copyright notice and this permission notice shall be included
-    in all copies or substantial portions of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-    DEALINGS IN THE SOFTWARE.
-..
-
-Test
-####
-
-:save_as: plugins/htmlsanity/test/index.html
-:breadcrumb: {filename}/plugins.rst Pelican plugins
-             {filename}/plugins/htmlsanity.rst HTML sanity
-
-Inline preformatted blocks should be escaped: ``<hr>``
-
-Inline preformatted blocks should have whitespace preserved: ``two  spaces  between  words``
-
-Preformatted blocks should have sane rendering::
-
-    helllo
-
-      world
-
-Inline code shouldn't be hyphenated or with smart quotes applied: ``"hello" --- isn't this working?"``.
index 02d74deab9ad7ac1a42067b35472cdef9fa0bfd9..68f1973952c28001c923793892dafc3b9e7147c5 100644 (file)
@@ -1,5 +1,2 @@
-__pycache__
-htmlcov
 test/*/html/
 test/*/xml/
-.coverage
diff --git a/pelican-plugins/m/test/.gitignore b/pelican-plugins/m/test/.gitignore
new file mode 100644 (file)
index 0000000..beeea24
--- /dev/null
@@ -0,0 +1 @@
+*/output/
diff --git a/pelican-plugins/m/test/__init__.py b/pelican-plugins/m/test/__init__.py
new file mode 100644 (file)
index 0000000..3cfe1bd
--- /dev/null
@@ -0,0 +1,55 @@
+import os
+import shutil
+import unittest
+
+from pelican import read_settings, Pelican
+
+class PluginTestCase(unittest.TestCase):
+    def __init__(self, path, dir, *args, **kwargs):
+        unittest.TestCase.__init__(self, *args, **kwargs)
+        # Source files for test_something.py are in something_{dir}/ subdirectory
+        self.path = os.path.join(os.path.dirname(os.path.realpath(path)), os.path.splitext(os.path.basename(path))[0][5:] + ('_' + dir if dir else ''))
+
+        # Display ALL THE DIFFS
+        self.maxDiff = None
+
+    def setUp(self):
+        if os.path.exists(os.path.join(self.path, 'output')): shutil.rmtree(os.path.join(self.path, 'output'))
+
+    def run_pelican(self, settings):
+        implicit_settings = {
+            # Contains just stuff that isn't required by the m.css theme itself,
+            # but is needed to have the test setup working correctly
+            'RELATIVE_URLS': True,
+            'TIMEZONE': 'UTC',
+            'READERS': {'html': None},
+            'SITEURL': '.',
+            'PATH': os.path.join(self.path),
+            'OUTPUT_PATH': os.path.join(self.path, 'output'),
+            'PAGE_PATHS': [''],
+            'PAGE_SAVE_AS': '{slug}.html',
+            'PAGE_URL': '{slug}.html',
+            'PAGE_EXCLUDES': ['output'],
+            'ARTICLE_PATHS': ['articles'], # does not exist
+            'FEED_ALL_ATOM': None, # Don't render feeds, we're not testing them *ever*
+            'THEME': '../pelican-theme',
+            'PLUGIN_PATHS': ['.'],
+            'THEME_STATIC_DIR': 'static',
+            'M_CSS_FILES': ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i',
+               'static/m-dark.css'],
+            'M_FINE_PRINT': None,
+            'DIRECT_TEMPLATES': [],
+            'SLUGIFY_SOURCE': 'basename'
+        }
+        settings = read_settings(path=None, override={**implicit_settings, **settings})
+        pelican = Pelican(settings=settings)
+        pelican.run()
+
+    def actual_expected_contents(self, actual, expected = None):
+        if not expected: expected = actual
+
+        with open(os.path.join(self.path, expected)) as f:
+            expected_contents = f.read().strip()
+        with open(os.path.join(self.path, 'output', actual)) as f:
+            actual_contents = f.read().strip()
+        return actual_contents, expected_contents
diff --git a/pelican-plugins/m/test/htmlsanity_content/page.html b/pelican-plugins/m/test/htmlsanity_content/page.html
new file mode 100644 (file)
index 0000000..7ca916a
--- /dev/null
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>A page | A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta property="og:title" content="A page" />
+  <meta name="twitter:title" content="A page" />
+  <meta property="og:url" content="page.html" />
+  <meta name="twitter:url" content="page.html" />
+  <meta property="og:description" content="no." />
+  <meta name="twitter:description" content="no." />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>A page</h1>
+<!-- content -->
+<aside class="contents m-block m-default" id="contents">
+<h3>Contents</h3>
+<ul>
+<li><a href="#section-title" id="id3">Section title</a><ul>
+<li><a href="#section-title-with-link" id="id4">Section title with link</a></li>
+</ul>
+</li>
+</ul>
+</aside>
+<p>A paragraph.</p>
+<blockquote>
+A block quote.</blockquote>
+<p>
+Hand<br />
+wrapped<br />
+content<br />
+</p>
+<pre>Code with &lt;all&gt; the &amp; &quot;things&quot; escaped and
+                                       weird whitespace
+                                       preserved</pre>
+<ul>
+<li>An unordered list</li>
+<li>Another item<ol>
+<li>Sub-list, ordered</li>
+<li>Another item</li>
+</ol>
+</li>
+<li>Third item of the top-level list</li>
+</ul>
+<table class="m-table">
+<thead>
+<tr><th>Heading 1</th>
+<th>Heading 2</th>
+</tr>
+</thead>
+<tbody>
+<tr><td>Cell 1</td>
+<td>Table cell 2</td>
+</tr>
+<tr><td>Row 2</td>
+<td>Row 2 cell 2</td>
+</tr>
+</tbody>
+</table>
+<dl>
+<dt>Term 1</dt>
+<dd>Description</dd>
+<dt>Term 2</dt>
+<dd>Description of term 2</dd>
+</dl>
+<section id="section-title">
+<h2><a class="toc-backref" href="#id3">Section title</a></h2>
+<p>An <em>emphasised text</em>, <strong>strong text</strong> and a <code>literal</code>. Link to
+<a href="https://google.com">Google</a>, <a href="#a-heading">the heading below</a> or just an
+URL as-is: <a href="https://mcss.mosra.cz/">https://mcss.mosra.cz/</a>. <a href="mailto:mosra&#64;centrum.cz">E-mail</a>. A footnote
+reference: <a class="footnote-reference brackets" href="#id2" id="id1">1</a></p>
+<dl class="footnote brackets">
+<dt class="label" id="id2"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
+<dd>A footnote description</dd>
+</dl>
+<section id="section-title-with-link">
+<h3><a href="#section-title-with-link">Section title with link</a></h3>
+<p>A line:</p>
+<hr />
+<p>And a paragraph after.</p>
+</section>
+</section>
+<!-- /content -->
+      </div>
+    </div>
+  </div>
+</article>
+</main>
+</body>
+</html>
diff --git a/pelican-plugins/m/test/htmlsanity_content/page.rst b/pelican-plugins/m/test/htmlsanity_content/page.rst
new file mode 100644 (file)
index 0000000..e0fd5b2
--- /dev/null
@@ -0,0 +1,62 @@
+A page
+######
+
+:summary: no.
+
+.. contents::
+    :class: m-block m-default
+
+A paragraph.
+
+    A block quote.
+
+| Hand
+| wrapped
+| content
+
+::
+
+    Code with <all> the & "things" escaped and
+                                           weird whitespace
+                                           preserved
+
+-   An unordered list
+-   Another item
+
+    1.  Sub-list, ordered
+    2.  Another item
+
+-   Third item of the top-level list
+
+.. class:: m-table
+
+========= ============
+Heading 1 Heading 2
+========= ============
+Cell 1    Table cell 2
+Row 2     Row 2 cell 2
+========= ============
+
+Term 1
+    Description
+Term 2
+    Description of term 2
+
+Section title
+=============
+
+An *emphasised text*, **strong text** and a ``literal``. Link to
+`Google <https://google.com>`_, `the heading below <#a-heading>`_ or just an
+URL as-is: https://mcss.mosra.cz/. `E-mail <mosra@centrum.cz>`_. A footnote
+reference: [1]_
+
+.. [1] A footnote description
+
+`Section title with link`_
+--------------------------
+
+A line:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+And a paragraph after.
diff --git a/pelican-plugins/m/test/htmlsanity_typography/article-lang.html b/pelican-plugins/m/test/htmlsanity_typography/article-lang.html
new file mode 100644 (file)
index 0000000..5d385fc
--- /dev/null
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html lang="cs">
+<head>
+  <meta charset="UTF-8" />
+  <title>Article in different language | A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&amp;subset=latin-ext" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta name="keywords" content="" />
+  <meta property="og:title" content="Article in different language" />
+  <meta name="twitter:title" content="Article in different language" />
+  <meta property="og:url" content="lang-cs.html" />
+  <meta name="twitter:url" content="lang-cs.html" />
+  <meta property="og:description" content="Text tohoto článku je česky (přičemž DEFAULT_LANG je &#39;en&#39;) a měl by tedy mít české dělení slov. „A také české uvozovky.“" />
+  <meta name="twitter:description" content="Text tohoto článku je česky (přičemž DEFAULT_LANG je &#39;en&#39;) a měl by tedy mít české dělení slov. „A také české uvozovky.“" />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="article" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container">
+  <div class="m-row">
+    <article class="m-col-m-10 m-nopadb">
+      <header>
+        <h1><a href="lang-cs.html" rel="bookmark" title="Permalink to Article in different language">
+          <time class="m-date" datetime="2017-12-10T00:00:00+00:00">
+            Dec <span class="m-date-day">10</span> 2017
+          </time>
+          Article in different language
+        </a></h1>
+        <p>Text to&shy;ho&shy;to člán&shy;ku je čes&shy;ky (při&shy;čemž <code>DEFAULT_LANG</code> je <code>'en'</code>) a měl by
+        te&shy;dy mít čes&shy;ké dě&shy;le&shy;ní slov. „A ta&shy;ké čes&shy;ké uvo&shy;zov&shy;ky.“</p>
+      </header>
+      <div class="m-clearfix-l"></div>
+<!-- content -->
+<p>Text to&shy;ho&shy;to člán&shy;ku je čes&shy;ky (při&shy;čemž <code>DEFAULT_LANG</code> je <code>'en'</code>) a měl by
+te&shy;dy mít čes&shy;ké dě&shy;le&shy;ní slov. „A ta&shy;ké čes&shy;ké uvo&shy;zov&shy;ky.“</p>
+<!-- /content -->
+      <footer>
+        <p>Posted on <time datetime="2017-12-10T00:00:00+00:00">Dec 10, 2017</time> in <a href="category/articles.html">articles</a>.</p>
+      </footer>
+    </article>
+    <nav class="m-navpanel m-col-m-2">
+      <h3>Cat&shy;e&shy;gories</h3>
+      <ol class="m-block-bar-m">
+        <li><a href="category/articles.html">ar&amp;shy;ti&amp;shy;cles</a></li>
+      </ol>
+    </nav>
+  </div>
+</div>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>The foot&shy;er should be hy&shy;phen&shy;at&shy;ed as well. “And with smart quotes.”</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-plugins/m/test/htmlsanity_typography/articles/lang.rst b/pelican-plugins/m/test/htmlsanity_typography/articles/lang.rst
new file mode 100644 (file)
index 0000000..4e22a81
--- /dev/null
@@ -0,0 +1,8 @@
+Article in different language
+#############################
+
+:date: 2017-12-10
+:lang: cs
+
+Text tohoto článku je česky (přičemž ``DEFAULT_LANG`` je ``'en'``) a měl by
+tedy mít české dělení slov. "A také české uvozovky."
diff --git a/pelican-plugins/m/test/htmlsanity_typography/page-lang.html b/pelican-plugins/m/test/htmlsanity_typography/page-lang.html
new file mode 100644 (file)
index 0000000..9b576d1
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="cs">
+<head>
+  <meta charset="UTF-8" />
+  <title>Page in different language | A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&amp;subset=latin-ext" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta property="og:title" content="Page in different language" />
+  <meta name="twitter:title" content="Page in different language" />
+  <meta property="og:url" content="pages/page-lang-cs.html" />
+  <meta name="twitter:url" content="pages/page-lang-cs.html" />
+  <meta property="og:description" content="Text této stránky je česky (přičemž DEFAULT_LANG je &#39;en&#39;) a měl by tedy mít české dělení slov. „A také české uvozovky.“" />
+  <meta name="twitter:description" content="Text této stránky je česky (přičemž DEFAULT_LANG je &#39;en&#39;) a měl by tedy mít české dělení slov. „A také české uvozovky.“" />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>Page in different language</h1>
+<!-- content -->
+<p>Text té&shy;to strán&shy;ky je čes&shy;ky (při&shy;čemž <code>DEFAULT_LANG</code> je <code>'en'</code>) a měl by te&shy;dy
+mít čes&shy;ké dě&shy;le&shy;ní slov. „A ta&shy;ké čes&shy;ké uvo&shy;zov&shy;ky.“</p>
+<!-- /content -->
+      </div>
+    </div>
+  </div>
+</article>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>The foot&shy;er should be hy&shy;phen&shy;at&shy;ed as well. “And with smart quotes.”</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-plugins/m/test/htmlsanity_typography/page-lang.rst b/pelican-plugins/m/test/htmlsanity_typography/page-lang.rst
new file mode 100644 (file)
index 0000000..2610d11
--- /dev/null
@@ -0,0 +1,7 @@
+Page in different language
+##########################
+
+:lang: cs
+
+Text této stránky je česky (přičemž ``DEFAULT_LANG`` je ``'en'``) a měl by tedy
+mít české dělení slov. "A také české uvozovky."
diff --git a/pelican-plugins/m/test/htmlsanity_typography/page.html b/pelican-plugins/m/test/htmlsanity_typography/page.html
new file mode 100644 (file)
index 0000000..1dbcf19
--- /dev/null
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8" />
+  <title>Page title should not be hyphenated. “But quotes yes.” | A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&amp;subset=latin-ext" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <link rel="stylesheet" href="and-definitely-not-css-links.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta name="description" content="Neither the description. “But quotes yes.”" />
+  <meta property="og:title" content="Page title should not be hyphenated. “But quotes yes.”" />
+  <meta name="twitter:title" content="Page title should not be hyphenated. “But quotes yes.”" />
+  <meta property="og:url" content="page.html" />
+  <meta name="twitter:url" content="page.html" />
+  <meta property="og:description" content="Page summary in the meta tag should not be hyphenated. “But quotes yes.”" />
+  <meta name="twitter:description" content="Page summary in the meta tag should not be hyphenated. “But quotes yes.”" />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<div class="m-container m-container-inflatable">
+  <div class="m-row">
+    <div class="m-col-l-10 m-push-l-1 m-nopadb">
+<!-- header -->
+<p>A head&shy;er that <em>should be</em> hy&shy;phen&shy;at&shy;ed. “Quotes.”</p>
+<!-- /header -->
+    </div>
+  </div>
+</div>
+<article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>Page title should not be hyphenated. “But quotes yes.”</h1>
+<!-- content -->
+<p>Page con&shy;tent should be hy&shy;phen&shy;at&shy;ed. <code>But &quot;code&quot; should not be hyphenated.</code></p>
+<pre>Neither preformatted text. &quot;No quotes for you.&quot;</pre>
+<div class="m-note m-info">
+Nest&shy;ed con&shy;tent should be hy&shy;phen&shy;at&shy;ed al&shy;so! And al&shy;so <strong>bold sec&shy;tions</strong> or
+<em>ital&shy;ics text</em>. Oh and “quotes should be smart” — with prop&shy;er em-dash,
+8–22 (en-dash) and el&shy;lip&shy;sis…</div>
+<p><a href="http://blog.mosra.cz/">Link ti&shy;tles can be hy&shy;phen&shy;at&shy;ed as well.</a> But in&shy;line
+ver&shy;ba&shy;tim stuff shouldn’t: <span class="raw-html">hello "this" is not hyphenated</span>. Nei&shy;ther
+ver&shy;ba&shy;tim blocks:</p>
+"quote" hyphenation<p lang="cs">Od&shy;sta&shy;vec v češ&shy;ti&shy;ně. „Uvo&shy;zov&shy;ky“ fun&shy;gu&shy;jí ji&shy;nak a dě&shy;le&shy;ní slov jakbys&shy;met.</p>
+<!-- /content -->
+      </div>
+    </div>
+  </div>
+</article>
+<div class="m-container m-container-inflatable">
+  <div class="m-row">
+    <div class="m-col-l-10 m-push-l-1 m-nopadt">
+<!-- footer -->
+<p>The foot&shy;er <em>should be</em> hy&shy;phen&shy;at&shy;ed as well. “Quotes.”</p>
+<!-- /footer -->
+    </div>
+  </div>
+</div>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>The foot&shy;er should be hy&shy;phen&shy;at&shy;ed as well. “And with smart quotes.”</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-plugins/m/test/htmlsanity_typography/page.rst b/pelican-plugins/m/test/htmlsanity_typography/page.rst
new file mode 100644 (file)
index 0000000..f429181
--- /dev/null
@@ -0,0 +1,35 @@
+Page title should not be hyphenated. "But quotes yes."
+######################################################
+
+:header: A header that *should be* hyphenated. "Quotes."
+:footer: The footer *should be* hyphenated as well. "Quotes."
+:summary: Page summary in the meta tag should not be hyphenated. "But quotes yes."
+:description: Neither the description. "But quotes yes."
+:css: and-definitely-not-css-links.css
+
+.. role:: raw-html(raw)
+    :format: html
+
+Page content should be hyphenated. ``But "code" should not be hyphenated.``
+
+::
+
+    Neither preformatted text. "No quotes for you."
+
+.. container:: m-note m-info
+
+    Nested content should be hyphenated also! And also **bold sections** or
+    *italics text*. Oh and "quotes should be smart" --- with proper em-dash,
+    8--22 (en-dash) and ellipsis...
+
+`Link titles can be hyphenated as well. <http://blog.mosra.cz/>`_ But inline
+verbatim stuff shouldn't: :raw-html:`hello "this" is not hyphenated`. Neither
+verbatim blocks:
+
+.. raw:: html
+
+    "quote" hyphenation
+
+.. class:: language-cs
+
+    Odstavec v češtině. "Uvozovky" fungují jinak a dělení slov jakbysmet.
diff --git a/pelican-plugins/m/test/htmlsanity_typography_global_lang/page.html b/pelican-plugins/m/test/htmlsanity_typography_global_lang/page.html
new file mode 100644 (file)
index 0000000..49cdfba
--- /dev/null
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html lang="cs">
+<head>
+  <meta charset="UTF-8" />
+  <title>Hyphenation in other languages | A Pelican Blog</title>
+  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&amp;subset=latin-ext" />
+  <link rel="stylesheet" href="static/m-dark.css" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+  <meta property="og:title" content="Hyphenation in other languages" />
+  <meta name="twitter:title" content="Hyphenation in other languages" />
+  <meta property="og:url" content="page.html" />
+  <meta name="twitter:url" content="page.html" />
+  <meta property="og:description" content="Text všech stránek je česky (DEFAULT_LANG je &#39;cs&#39;) a měl by mít tedy české dělení slov. „A také české uvozovky.“" />
+  <meta name="twitter:description" content="Text všech stránek je česky (DEFAULT_LANG je &#39;cs&#39;) a měl by mít tedy české dělení slov. „A také české uvozovky.“" />
+  <meta name="twitter:card" content="summary" />
+  <meta property="og:type" content="website" />
+</head>
+<body>
+<header><nav id="navigation">
+  <div class="m-container">
+    <div class="m-row">
+      <a href="./" id="m-navbar-brand" class="m-col-t-9 m-col-m-none m-left-m">A Pelican Blog</a>
+    </div>
+  </div>
+</nav></header>
+<main>
+<article>
+  <div class="m-container m-container-inflatable">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <h1>Hyphenation in other languages</h1>
+<!-- content -->
+<p>Text všech strá&shy;nek je čes&shy;ky (<code>DEFAULT_LANG</code> je <code>'cs'</code>) a měl by mít te&shy;dy
+čes&shy;ké dě&shy;le&shy;ní slov. „A ta&shy;ké čes&shy;ké uvo&shy;zov&shy;ky.“</p>
+<!-- /content -->
+      </div>
+    </div>
+  </div>
+</article>
+</main>
+<footer><nav>
+  <div class="m-container">
+    <div class="m-row">
+      <div class="m-col-l-10 m-push-l-1">
+        <p>Pa&shy;tič&shy;ka má dě&shy;le&shy;ní slov ta&shy;ké. „A chyt&shy;ré uvo&shy;zov&shy;ky.“</p>
+      </div>
+    </div>
+  </div>
+</nav></footer>
+</body>
+</html>
diff --git a/pelican-plugins/m/test/htmlsanity_typography_global_lang/page.rst b/pelican-plugins/m/test/htmlsanity_typography_global_lang/page.rst
new file mode 100644 (file)
index 0000000..fd9814e
--- /dev/null
@@ -0,0 +1,5 @@
+Hyphenation in other languages
+##############################
+
+Text všech stránek je česky (``DEFAULT_LANG`` je ``'cs'``) a měl by mít tedy
+české dělení slov. "A také české uvozovky."
diff --git a/pelican-plugins/m/test/test_htmlsanity.py b/pelican-plugins/m/test/test_htmlsanity.py
new file mode 100644 (file)
index 0000000..b9fff16
--- /dev/null
@@ -0,0 +1,65 @@
+from m.test import PluginTestCase
+
+class Content(PluginTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'content', *args, **kwargs)
+
+    def test(self):
+        self.run_pelican({
+            'PLUGINS': ['m.htmlsanity']
+        })
+
+        # Verify there's no superfluous markup or useless classes
+        self.assertEqual(*self.actual_expected_contents('page.html'))
+
+class Typography(PluginTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'typography', *args, **kwargs)
+
+    def test(self):
+        self.run_pelican({
+            # Need extended Latin characters for Czech text
+            'M_CSS_FILES': ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&subset=latin-ext',
+                            'static/m-dark.css'],
+            'PLUGINS': ['m.htmlsanity'],
+            'M_HTMLSANITY_HYPHENATION': True,
+            'M_HTMLSANITY_SMART_QUOTES': True,
+            'M_FINE_PRINT': "The footer should be hyphenated as well. \"And with smart quotes.\"",
+            'DATE_FORMATS': {'cs': ('en_US.UTF-8', '%b %d, %Y')},
+            'PAGE_LANG_SAVE_AS': '{slug}.html',
+            'ARTICLE_SAVE_AS': 'article-{slug}.html',
+            'ARTICLE_LANG_SAVE_AS': 'article-{slug}.html',
+            'FORMATTED_FIELDS': ['summary', 'description', 'header', 'footer'],
+
+            # Disable unneeded stuff
+            'TRANSLATION_FEED_ATOM': None,
+            'CATEGORY_FEED_ATOM': None,
+            'CATEGORY_SAVE_AS': '',
+        })
+
+        # The &shy; should be at proper places and not where it shouldn't be.
+        self.assertEqual(*self.actual_expected_contents('page.html'))
+
+        # The <html> lang element should be set correctly as well.
+        self.assertEqual(*self.actual_expected_contents('page-lang.html'))
+        self.assertEqual(*self.actual_expected_contents('article-lang.html'))
+
+class TypographyGlobalLang(PluginTestCase):
+    def __init__(self, *args, **kwargs):
+        super().__init__(__file__, 'typography_global_lang', *args, **kwargs)
+
+    def test(self):
+        self.run_pelican({
+            # Need extended Latin characters for Czech text
+            'M_CSS_FILES': ['https://fonts.googleapis.com/css?family=Source+Code+Pro:400,400i,600%7CSource+Sans+Pro:400,400i,600,600i&subset=latin-ext',
+                            'static/m-dark.css'],
+            'PLUGINS': ['m.htmlsanity'],
+            'DEFAULT_LANG': 'cs',
+            'M_HTMLSANITY_HYPHENATION': True,
+            'M_HTMLSANITY_SMART_QUOTES': True,
+            'M_FINE_PRINT': "Patička má dělení slov také. \"A chytré uvozovky.\""
+        })
+
+        # The <html> lang element should be set correctly and the &shy; should
+        # be at proper places and not where it shouldn't be.
+        self.assertEqual(*self.actual_expected_contents('page.html'))