Skip to content

Commit

Permalink
better prettify implementation + new tests + docs
Browse files Browse the repository at this point in the history
  • Loading branch information
daveoncode committed Aug 18, 2015
1 parent 6d6cab1 commit e7d3927
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 12 deletions.
Binary file modified docs/_build/doctrees/environment.pickle
Binary file not shown.
Binary file modified docs/_build/doctrees/index.doctree
Binary file not shown.
11 changes: 11 additions & 0 deletions docs/_build/html/genindex.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ <h1 id="index">Index</h1>
<div class="genindex-jumpbox">
<a href="#C"><strong>C</strong></a>
| <a href="#I"><strong>I</strong></a>
| <a href="#P"><strong>P</strong></a>
| <a href="#R"><strong>R</strong></a>
| <a href="#S"><strong>S</strong></a>
| <a href="#U"><strong>U</strong></a>
Expand Down Expand Up @@ -178,6 +179,16 @@ <h2 id="I">I</h2>
</dl></td>
</tr></table>

<h2 id="P">P</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>

<dt><a href="index.html#string_utils.prettify">prettify() (in module string_utils)</a>
</dt>

</dl></td>
</tr></table>

<h2 id="R">R</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%" valign="top"><dl>
Expand Down
29 changes: 29 additions & 0 deletions docs/_build/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,35 @@ <h1>Welcome to Python String Utils&#8217;s documentation!<a class="headerlink" h
</table>
</dd></dl>

<dl class="function">
<dt id="string_utils.prettify">
<code class="descclassname">string_utils.</code><code class="descname">prettify</code><span class="sig-paren">(</span><em>string</em><span class="sig-paren">)</span><a class="headerlink" href="#string_utils.prettify" title="Permalink to this definition"></a></dt>
<dd><p>Turns an ugly text string into a beautiful one by applying a regex pipeline which ensures the following:</p>
<ul class="simple">
<li>String cannot start or end with spaces</li>
<li>String cannot have multiple sequential spaces, empty lines or punctuation (except for &#8221;?&#8221;, &#8221;!&#8221; and &#8221;.&#8221;)</li>
<li>Arithmetic operators (&#8220;+&#8221;, &#8220;-&#8221;, &#8220;/&#8221;, &#8220;*&#8221;, &#8220;=&#8221;) must have one, and only one space before and after themselves</li>
<li>The first letter after a dot, an exclamation or a question mark must be uppercase</li>
<li>One, and only one space should follow a dot, an exclamation or a question mark</li>
<li>Text inside double quotes cannot start or end with spaces, but one, and only one space must come first and after quotes (foo&#8221; bar&#8221;baz -&gt; foo &#8220;bar&#8221; baz)</li>
<li>Text inside round brackets cannot start or end with spaces, but one, and only one space must come first and after brackets (&#8220;foo(bar )baz&#8221; -&gt; &#8220;foo (bar) baz&#8221;)</li>
<li>Percentage sign (&#8220;%&#8221;) cannot be preceded by a space if there is a number before (&#8220;100 %&#8221; -&gt; &#8220;100%&#8221;)</li>
<li>Saxon genitive is correct (&#8220;Dave&#8217; s dog&#8221; -&gt; &#8220;Dave&#8217;s dog&#8221;)</li>
</ul>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body"><strong>string</strong> &#8211; String to manipulate</td>
</tr>
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body">Prettified string.</td>
</tr>
<tr class="field-odd field"><th class="field-name">Return type:</th><td class="field-body">str</td>
</tr>
</tbody>
</table>
</dd></dl>

</div>
<div class="section" id="indices-and-tables">
<h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline"></a></h1>
Expand Down
Binary file modified docs/_build/html/objects.inv
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/_build/html/searchindex.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='python-string-utils',
version='0.2.0',
version='0.3.0',
description='Utility functions for strings checking and manipulation.',
long_description=long_description,
author='Davide Zanotti',
Expand Down
29 changes: 25 additions & 4 deletions string_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import random

# module settings
__version__ = '0.2.0'
__version__ = '0.3.0'
__all__ = [
'is_string',
'is_url',
Expand Down Expand Up @@ -81,11 +81,11 @@
'RIGHT_SPACE': re.compile(
r'('
r'(?<=[^\s\d]),(?=[^\s\d])|\s,\s|\s,(?=[^\s\d])|\s,(?!.)|' # comma (,)
r'(?<=[^\s\d])\.(?=[^\s\d])|\s\.\s|\s\.(?=[^\s\d])|\s\.(?!.)|' # dot (.)
r'(?<=[^\s\d\.])\.+(?=[^\s\d\.])|\s\.+\s|\s\.+(?=[^\s\d])|\s\.+(?!\.)|' # dot (.)
r'(?<=\S);(?=\S)|\s;\s|\s;(?=\S)|\s;(?!.)|' # semicolon (;)
r'(?<=\S):(?=\S)|\s:\s|\s:(?=\S)|\s:(?!.)|' # colon (:)
r'(?<=\S)!(?=\S)|\s!\s|\s!(?=\S)|\s!(?!.)|' # exclamation (!)
r'(?<=\S)\?(?=\S)|\s\?\s|\s\?(?=\S)|\s\?(?!.)|' # question (?)
r'(?<=[^\s!])!+(?=[^\s!])|\s!+\s|\s!+(?=[^\s!])|\s!+(?!!)|' # exclamation (!)
r'(?<=[^\s\?])\?+(?=[^\s\?])|\s\?+\s|\s\?+(?=[^\s\?])|\s\?+(?!\?)|' # question (?)
r'\d%(?=\S)|(?<=\d)\s%\s|(?<=\d)\s%(?=\S)|(?<=\d)\s%(?!.)' # percentage (%)
r')',
re.MULTILINE | re.DOTALL
Expand Down Expand Up @@ -471,6 +471,27 @@ def strip_html(string, keep_tag_content=False):


def prettify(string):
"""
Turns an ugly text string into a beautiful one by applying a regex pipeline which ensures the following:
- String cannot start or end with spaces
- String cannot have multiple sequential spaces, empty lines or punctuation (except for "?", "!" and ".")
- Arithmetic operators ("+", "-", "/", "*", "=") must have one, and only one space before and after themselves
- The first letter after a dot, an exclamation or a question mark must be uppercase
- One, and only one space should follow a dot, an exclamation or a question mark
- Text inside double quotes cannot start or end with spaces, but one, and only one space must come first and \
after quotes (foo" bar"baz -> foo "bar" baz)
- Text inside round brackets cannot start or end with spaces, but one, and only one space must come first and \
after brackets ("foo(bar )baz" -> "foo (bar) baz")
- Percentage sign ("%") cannot be preceded by a space if there is a number before ("100 %" -> "100%")
- Saxon genitive is correct ("Dave' s dog" -> "Dave's dog")
:param string: String to manipulate
:return: Prettified string.
:rtype: str
"""

def remove_duplicates(regex_match):
return regex_match.group(1)[0]

Expand Down
30 changes: 24 additions & 6 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1080,29 +1080,35 @@ def test_should_replace_multiple_percentage_with_single_ones(self):
self.assertEqual('%', prettify('%%%'))
self.assertEqual('A % b % c', prettify('a %% b %%%%%% c'))

def test_should_put_space_after_comma_if_missing(self):
def test_should_add_space_after_comma_if_missing(self):
self.assertEqual('One, two, three', prettify('one,two,three'))

def test_should_not_add_right_space_after_dot_for_numbers(self):
self.assertEqual('12,55', prettify('12,55'))

def test_should_remove_space_before_comma(self):
self.assertEqual('One, two, three', prettify('one , two , three'))

def test_should_uppercase_first_letter_after_period(self):
self.assertEqual('Foo. Bar', prettify('Foo. bar'))

def test_should_put_space_after_period_if_missing(self):
def test_should_add_space_after_period_if_missing(self):
self.assertEqual('One. Two. Three', prettify('one.two.three'))

def test_should_not_add_right_space_after_comma_for_numbers(self):
self.assertEqual('12.55', prettify('12.55'))

def test_should_remove_space_before_period(self):
self.assertEqual('One. Two. Three', prettify('one . two . three'))

def test_should_put_space_after_colon_if_missing(self):
def test_should_add_space_after_colon_if_missing(self):
self.assertEqual('Test: this', prettify('Test:this'))

def test_should_remove_space_before_colon(self):
self.assertEqual('Test: this', prettify('Test :this'))
self.assertEqual('Test:', prettify('Test :'))

def test_should_put_space_after_semicolon_if_missing(self):
def test_should_add_space_after_semicolon_if_missing(self):
self.assertEqual('Test; this', prettify('Test;this'))

def test_should_remove_space_before_semicolon(self):
Expand All @@ -1112,7 +1118,7 @@ def test_should_remove_space_before_semicolon(self):
def test_should_uppercase_first_letter_after_exclamation(self):
self.assertEqual('Foo! Bar', prettify('Foo! bar'))

def test_should_put_space_after_exclamation_if_missing(self):
def test_should_add_space_after_exclamation_if_missing(self):
self.assertEqual('Test! This', prettify('Test!this'))

def test_should_remove_space_before_exclamation(self):
Expand All @@ -1122,7 +1128,7 @@ def test_should_remove_space_before_exclamation(self):
def test_should_uppercase_first_letter_after_question(self):
self.assertEqual('Foo? Bar', prettify('Foo? bar'))

def test_should_put_space_after_question_if_missing(self):
def test_should_add_space_after_question_if_missing(self):
self.assertEqual('Test? This', prettify('Test?this'))

def test_should_remove_space_before_question(self):
Expand Down Expand Up @@ -1165,6 +1171,18 @@ def test_should_add_spaces_around_multiplication_if_missing(self):
self.assertEqual('5 * 2 = 10', prettify('5 *2 = 10'))
self.assertEqual('5 * 2 = 10', prettify('5*2 = 10'))

def test_triple_dot_preserved(self):
self.assertEqual('Test...', prettify('Test...'))
self.assertEqual('Test... This', prettify('Test...This'))

def test_triple_exclamation_preserved(self):
self.assertEqual('Test!!!', prettify('Test!!!'))
self.assertEqual('Test!!! This', prettify('Test!!!This'))

def test_triple_question_preserved(self):
self.assertEqual('Test???', prettify('Test???'))
self.assertEqual('Test??? This', prettify('Test???This'))

def test_should_prettify_string_as_expected(self):
original = ' unprettified string ,, like this one,will be"prettified" .it\' s awesome!( like python)) '
pretty = 'Unprettified string, like this one, will be "prettified". It\'s awesome! (like python)'
Expand Down

0 comments on commit e7d3927

Please sign in to comment.