From b409e340abf55a1e667a92304acf00bac0abc2a3 Mon Sep 17 00:00:00 2001 From: Martin Ortbauer Date: Tue, 13 Aug 2013 23:02:58 +0200 Subject: [PATCH 1/6] added a setup script --- htmltruncate.py | 11 +++++------ setup.py | 13 +++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 setup.py diff --git a/htmltruncate.py b/htmltruncate.py index 6fe3ef8..2518a53 100755 --- a/htmltruncate.py +++ b/htmltruncate.py @@ -1,6 +1,5 @@ #!/usr/bin/env python -from __future__ import print_function import sys @@ -16,14 +15,14 @@ def __init__(self, tag, rest=''): def as_string(self): return '<' + self.tag + self.rest + '>' - + class CloseTag(OpenTag): def as_string(self): return '' class SelfClosingTag(OpenTag): pass - + class Tokenizer: def __init__(self, input): self.input = input @@ -32,7 +31,7 @@ def __init__(self, input): def __next_char(self): self.counter += 1 return self.input[self.counter] - + def next_token(self): try: char = self.input[self.counter] @@ -62,7 +61,7 @@ def __entity(self): entity.append(';') self.counter += 1 return ''.join(entity) - + def __open_tag(self): """Return an open/close tag token. Precondition: self.counter points at the first character of the tag name @@ -130,7 +129,7 @@ def truncate(str, target_len, ellipsis = ''): if length == target_len: return ''.join(retval) + ellipsis else: - return ''.join(retval) + return ''.join(retval) if __name__ == "__main__": try: diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..96eec88 --- /dev/null +++ b/setup.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +# -*- coding: UTF-8 -*- + +from setuptools import setup + +setup(name='htmltruncate', + version='1.0', + description='To truncate html content meaningfull', + author='Martin Ortbauer', + author_email='mortbauer@gmail.com', + url='https://mortbauer.com', + py_modules = ['htmltruncate'] + ) From 44f6de13a5780fcb9f1e0a33e29ba7879ee0d4e7 Mon Sep 17 00:00:00 2001 From: Martin Ortbauer Date: Thu, 15 Aug 2013 13:58:11 +0200 Subject: [PATCH 2/6] updated metadata --- setup.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 96eec88..01eaca0 100644 --- a/setup.py +++ b/setup.py @@ -6,8 +6,7 @@ setup(name='htmltruncate', version='1.0', description='To truncate html content meaningfull', - author='Martin Ortbauer', - author_email='mortbauer@gmail.com', - url='https://mortbauer.com', + author='Eric Entzel', + url='https://github.com/eentzel/htmltruncate.py', py_modules = ['htmltruncate'] ) From 4adc4b22cc87a4fe93512ad4c345b04ff6383365 Mon Sep 17 00:00:00 2001 From: Chad Paulson Date: Thu, 12 Sep 2013 19:25:11 +0000 Subject: [PATCH 3/6] Adds ability to truncate to the nearest full word. --- htmltruncate.py | 11 ++++++++--- tests.py | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/htmltruncate.py b/htmltruncate.py index 2518a53..a85282d 100755 --- a/htmltruncate.py +++ b/htmltruncate.py @@ -96,7 +96,7 @@ def __close_tag(self): self.counter += 1 return CloseTag( ''.join(tag) ) -def truncate(str, target_len, ellipsis = ''): +def truncate(str, target_len, full_word=False, ellipsis = ''): """Returns a copy of str truncated to target_len characters, preserving HTML markup (which does not count towards the length). Any tags that would be left open by truncation will be closed at @@ -107,7 +107,7 @@ def truncate(str, target_len, ellipsis = ''): length = 0 # number of characters (not counting markup) placed in retval so far tokens = Tokenizer(str) tok = tokens.next_token() - while tok != END and length < target_len: + while tok != END: if tok.__class__.__name__ == 'OpenTag': stack.append(tok) retval.append( tok.as_string() ) @@ -123,10 +123,15 @@ def truncate(str, target_len, ellipsis = ''): retval.append(tok) length += 1 tok = tokens.next_token() + if length == target_len and not full_word: + break + elif length >= target_len and full_word and tok == " ": + break + while len(stack) > 0: tok = CloseTag( stack.pop().tag ) retval.append( tok.as_string() ) - if length == target_len: + if len(str) > length: return ''.join(retval) + ellipsis else: return ''.join(retval) diff --git a/tests.py b/tests.py index 575cd6a..0531b49 100755 --- a/tests.py +++ b/tests.py @@ -40,7 +40,7 @@ def testSelfClosing(self): self.assertEqual( htmltruncate.truncate( "I need
a break", 11 ), "I need
a br" ) def testEllipsis(self): - self.assertEqual( htmltruncate.truncate('this word is bolded', 10, '...' ), "this word ...") + self.assertEqual( htmltruncate.truncate('this word is bolded', 10, ellipsis='...' ), "this word ...") if __name__ == "__main__": unittest.main() From d5f017e46ca08031a69191efca26f81e9655bb4c Mon Sep 17 00:00:00 2001 From: Chad Paulson Date: Thu, 12 Sep 2013 19:32:11 +0000 Subject: [PATCH 4/6] Adds full word test case. --- tests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests.py b/tests.py index 0531b49..c1d4dc2 100755 --- a/tests.py +++ b/tests.py @@ -42,5 +42,8 @@ def testSelfClosing(self): def testEllipsis(self): self.assertEqual( htmltruncate.truncate('this word is bolded', 10, ellipsis='...' ), "this word ...") + def testFullWord(self): + self.assertEqual( htmltruncate.truncate( "I need
a break", 11, full_word=True ), "I need
a break" ) + if __name__ == "__main__": unittest.main() From 098a5dec08c8e71d5f01a36bc1cbe174ff5a3558 Mon Sep 17 00:00:00 2001 From: chadpaulson Date: Fri, 13 Sep 2013 00:10:53 -0500 Subject: [PATCH 5/6] Adds Travis service hook. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 01657a8..b5afc7d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/eentzel/htmltruncate.py.png)](https://travis-ci.org/eentzel/htmltruncate.py) +[![Build Status](https://travis-ci.org/chadpaulson/htmltruncate.py.png)](https://travis-ci.org/chadpaulson/htmltruncate.py) A module to truncate strings containing HTML. From 2595c7c445a9b836a322ee16dbe0828f9f2bf374 Mon Sep 17 00:00:00 2001 From: chadpaulson Date: Fri, 13 Sep 2013 00:42:20 -0500 Subject: [PATCH 6/6] Adds examples. --- README.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b5afc7d..6bc8d12 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,21 @@ -[![Build Status](https://travis-ci.org/chadpaulson/htmltruncate.py.png)](https://travis-ci.org/chadpaulson/htmltruncate.py) +## htmltruncate -A module to truncate strings containing HTML. +[![Build Status](https://travis-ci.org/chadpaulson/htmltruncate.png)](https://travis-ci.org/chadpaulson/htmltruncate.py) + +Returns a truncated string while preserving HTML markup (which does not count towards length). All tags left open by truncation are closed. + +**Example**: + +```python +>>> import htmltruncate +>>> str = "

You're not gonna lose the house, everybody has three mortgages nowadays.

" +>>> htmltruncate.truncate(str, 33) +"

You're not gonna lose the house,

" +``` + +**Options**: ```python -htmltruncate.truncate(str, target_len, ellipsis='') +>>> htmltruncate.truncate(str, 33, full_word=True, ellipsis="...") +"

You're not gonna lose the house, everybody

..." ``` - Returns a copy of str truncated to target_len characters, - preserving HTML markup (which does not count towards the length). - Any tags that would be left open by truncation will be closed at - the end of the returned string. Optionally append ellipsis if - the string was truncated.