summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYu-Jie Lin <livibetter@gmail.com>2013-08-12 16:41:56 +0800
committerYu-Jie Lin <livibetter@gmail.com>2013-08-12 16:41:56 +0800
commited1d8e03b553dfb4ea641a5dd86b09efba5db2cd (patch)
treec4140731821409c873ab2005e0ed3fea988c2be9
parent3ccc710d62d154cbb75782487cf533b5f4ddf3ae (diff)
downloadsmartypants-ed1d8e03b553dfb4ea641a5dd86b09efba5db2cd.tar.gz
add CLI script
-rw-r--r--CHANGES.rst1
-rw-r--r--README.rst56
-rwxr-xr-xsetup.py21
-rwxr-xr-xsmartypants30
-rw-r--r--tests/test_cli.py64
5 files changed, 160 insertions, 12 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 16a5966..aa48351 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -10,6 +10,7 @@ Versions without timestamps mean they are future releases.
- deprecate Pyblosxom support
- add Python 3 support
- add unittest and checks
+ - add CLI script
----
diff --git a/README.rst b/README.rst
index eacc396..cc858c1 100644
--- a/README.rst
+++ b/README.rst
@@ -2,10 +2,13 @@
smartypants.py
==============
+.. contents:: **Contents**
+
+
Synopsis
========
-The priginal "SmartyPants" is a free web publishing plug-in for Movable Type,
+The original "SmartyPants" is a free web publishing plug-in for Movable Type,
Blosxom, and BBEdit that easily translates plain ASCII punctuation characters
into "smart" typographic punctuation HTML entities.
@@ -34,6 +37,41 @@ display text where smart quotes and other "smart punctuation" would not be
appropriate, such as source code or example markup.
+Installation
+============
+
+smartypants.py can be installed vi pip::
+
+ $ pip install smartypants
+
+
+Usage
+=====
+
+As module
+---------
+
+.. code:: python
+
+ import smartypants
+
+ text = '"SmartyPants" is smart, so is <code>smartypants.py</code> -- a Python port'
+ print(smartypants.smartyPants(text))
+
+It outputs::
+
+ &#8220;SmartyPants&#8221; is smart, so is <code>smartypants.py</code> &#8212; a Python port
+
+
+Via CLI
+-------
+
+.. code:: sh
+
+ $ echo '"SmartyPants" is smart, so is <code>smartypants.py</code> -- a Python port' | smartypants
+ &#8220;SmartyPants&#8221; is smart, so is <code>smartypants.py</code> &#8212; a Python port
+
+
Backslash Escapes
=================
@@ -92,11 +130,19 @@ Numeric values are the easiest way to configure SmartyPants' behavior:
The following single-character attribute values can be combined to toggle
-individual transformations from within the smarty_pants attribute. For
+individual transformations from within the SmartyPants attributes. For
example, to educate normal quotes and em-dashes, but not ellipses or
\`\`backticks'' -style quotes:
-``py['smartypants_attributes'] = "1"``
+.. code:: python
+
+ smartypants.smartyPants(text, '1')
+
+In CLI:
+
+.. code:: sh
+
+ echo "$text" | smartypants -a '1'
"q"
Educates normal quote characters: (") and (').
@@ -179,9 +225,9 @@ Algorithmic Shortcomings
------------------------
One situation in which quotes will get curled the wrong way is when
-apostrophes are used at the start of leading contractions. For example:
+apostrophes are used at the start of leading contractions. For example::
-``'Twas the night before Christmas.``
+ 'Twas the night before Christmas.
In the case above, SmartyPants will turn the apostrophe into an opening
single-quote, when in fact it should be a closing one. I don't think
diff --git a/setup.py b/setup.py
index 6ccb5ad..9fc0e44 100755
--- a/setup.py
+++ b/setup.py
@@ -7,10 +7,15 @@ from distutils.core import Command, setup
from unittest import TestLoader, TextTestRunner
import sys
+CLI_script = 'smartypants'
+module_name = 'smartypants'
+module_file = 'smartypants.py'
+
+CHECK_FILES = ('.', CLI_script)
+
# scripts to be exculded from checking
EXCLUDE_SCRIPTS = ()
-script_name = 'smartypants.py'
# ============================================================================
@@ -76,7 +81,7 @@ class cmd_pep8(Command):
print('Results')
print('=======')
print()
- report = p8.check_files('.')
+ report = p8.check_files(CHECK_FILES)
print()
print('Statistics')
@@ -132,7 +137,7 @@ class cmd_pyflakes(Command):
print('Results')
print('=======')
print()
- warnings = api.checkRecursive('.', reporter)
+ warnings = api.checkRecursive(CHECK_FILES, reporter)
print()
print('Total warnings: %d' % warnings)
@@ -166,7 +171,7 @@ class cmd_pylint(Command):
print()
print('Exclude:', EXCLUDE_SCRIPTS)
- files = ['setup.py', script_name] + glob('tests/*.py')
+ files = ['setup.py', CLI_script, module_file] + glob('tests/*.py')
args = [
'--ignore=%s' % ','.join(EXCLUDE_SCRIPTS),
'--output-format=colorized',
@@ -178,7 +183,7 @@ class cmd_pylint(Command):
# ============================================================================
-with open(script_name) as f:
+with open(module_file) as f:
meta = dict(
(k.strip(' _'), eval(v)) for k, v in
# There will be a '\n', with eval(), it's safe to ignore
@@ -203,6 +208,7 @@ with open(script_name) as f:
classifiers = [
'Development Status :: 5 - Production/Stable',
'Intended Audience :: Developers',
+ 'Intended Audience :: End Users/Desktop',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2',
@@ -211,7 +217,7 @@ classifiers = [
]
setup_d = dict(
- name='smartypants',
+ name=module_name,
cmdclass={
'pep8': cmd_pep8,
'pyflakes': cmd_pyflakes,
@@ -219,7 +225,8 @@ setup_d = dict(
'test': cmd_test,
},
classifiers=classifiers,
- py_modules=['smartypants'],
+ py_modules=[module_name],
+ scripts=[CLI_script],
**meta
)
diff --git a/smartypants b/smartypants
new file mode 100755
index 0000000..67adfdc
--- /dev/null
+++ b/smartypants
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# Copyright (c) 2013 Yu-Jie Lin
+# Licensed under the BSD License, for detailed license information, see COPYING
+
+from __future__ import print_function
+import argparse
+import sys
+
+import smartypants
+
+
+def main():
+
+ parser = argparse.ArgumentParser(description='SmartyPants in Python')
+ parser.add_argument('-a', '--attr',
+ default=smartypants.default_smartypants_attr,
+ help='processing attributes (Default: %(default)s)')
+ parser.add_argument('files', metavar='FILE', type=argparse.FileType('r'),
+ nargs='*', help='files to be processed ')
+ args = parser.parse_args()
+
+ if args.files:
+ for f in args.files:
+ print(smartypants.smartyPants(f.read(), args.attr), end='')
+ else:
+ print(smartypants.smartyPants(sys.stdin.read(), args.attr), end='')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/test_cli.py b/tests/test_cli.py
new file mode 100644
index 0000000..0cf29dc
--- /dev/null
+++ b/tests/test_cli.py
@@ -0,0 +1,64 @@
+# Copyright (c) 2013 Yu-Jie Lin
+# Licensed under the BSD License, for detailed license information, see COPYING
+
+from __future__ import unicode_literals
+import os
+from subprocess import Popen, PIPE
+import tempfile
+import unittest
+
+
+CLI_SCRIPT = './smartypants'
+
+
+class TestCLI(unittest.TestCase):
+
+ @staticmethod
+ def _p(args, T=None):
+
+ if T:
+ T = T.encode()
+
+ stdin = PIPE if T else None
+ p = Popen(args, stdin=stdin, stdout=PIPE)
+ output = p.communicate(input=T)[0]
+
+ if isinstance(output, bytes):
+ output = output.decode() # Python 3
+
+ return output
+
+ def test_pipe(self):
+
+ T = '"foobar"'
+ E = '&#8220;foobar&#8221;'
+
+ output = self._p([CLI_SCRIPT], T)
+ self.assertEquals(output, E)
+
+ def test_pipe_attr(self):
+
+ T = """"foo" ``bar''"""
+
+ E = T
+ output = self._p([CLI_SCRIPT, '--attr', '0'], T)
+ self.assertEquals(output, E)
+
+ E = """"foo" &#8220;bar&#8221;"""
+ output = self._p([CLI_SCRIPT, '--attr', 'b'], T)
+ self.assertEquals(output, E)
+
+ def test_file(self):
+
+ T = '"foobar"'
+ E = '&#8220;foobar&#8221;'
+
+ F = tempfile.mkstemp()[1]
+ try:
+ with open(F, 'w') as f:
+ f.write(T)
+
+ output = self._p([CLI_SCRIPT, F])
+ finally:
+ os.remove(F)
+ self.assertEquals(output, E)