Ticket #12200: truncate.py

File truncate.py, 3.4 KB (added by Paul Schreiber, 14 years ago)
Line 
1# -*- coding: utf-8 -*-
2
3# truncate.py
4# Copyright © 2009 Paul Schreiber
5# paulschreiber at gmail dot com
6# http://paulschreiber.com/
7# Released under a Creative Commons Attribution-Share Alike 3.0 United States License
8# http://creativecommons.org/licenses/by-sa/3.0/us/
9#
10
11from django import template
12from django.template.defaultfilters import stringfilter
13
14register = template.Library()
15
16@register.filter(name='truncate_head')
17def truncate_head(value, character_count, ellipsis=True):
18 if value == None:
19 return ""
20
21 try:
22 length = int(character_count)
23 except ValueError: # Invalid literal for int().
24 return value # Fail silently.
25
26 if len(value) < length:
27 return value
28
29 # if we're already on a word boundary, done
30 if value[-(length+1)] == " ":
31 result = value[-length:].strip()
32 else:
33 original_length = len(value)
34 delta = (original_length-length)
35 first_space = value.find(" ", delta, original_length)
36
37 if first_space == -1:
38 length = delta
39 elif first_space > length:
40 length = first_space
41
42 result = value[length:].strip()
43
44 if ellipsis:
45 return u"…" + result
46 else:
47 return result
48
49@register.filter(name='truncate_tail')
50def truncate_tail(value, character_count, ellipsis=True):
51 if value == None:
52 return ""
53
54 try:
55 length = int(character_count)
56 except ValueError: # Invalid literal for int().
57 return value # Fail silently.
58
59 if len(value) < length:
60 return value
61
62 # if we're already on a word boundary, done
63 if value[length] == " ":
64 result = value[:length].strip()
65 else:
66 last_space = value.rfind(" ", 0, length)
67 if last_space != -1 and last_space <= length:
68 length = last_space
69
70 result = value[:length].strip()
71
72 if ellipsis:
73 return result + u"…"
74 else:
75 return result
76
77
78@register.filter(name='truncate_middle')
79def truncate_middle(value, character_count):
80 if value == None:
81 return ""
82
83 try:
84 length = int(character_count)
85 except ValueError: # Invalid literal for int().
86 return value # Fail silently.
87
88 if len(value) < length:
89 return value
90
91 half_size = length / 2
92 first_half = truncate_tail(value, half_size, False)
93 last_half = truncate_head(value, half_size, False)
94
95 return u"%s%s" % (first_half, last_half)
96
97@register.filter(name='truncatechars')
98def truncatechars(value, character_count, truncate_type='tail'):
99 """
100 truncatechars(value, character_count, truncate_type='tail')
101
102 Returns a copy of the string containg only character_counr characters. Try to break on word boundaries.
103
104 Arguments: Number of characters to truncate after, truncation type (tail/head/middle).
105 """
106
107 if truncate_type not in ["head", "tail", "middle"]:
108 raise ValueError
109
110 if value == None:
111 return ""
112
113 try:
114 length = int(character_count)
115 except ValueError: # Invalid literal for int().
116 return value # Fail silently.
117
118 if len(value) < length:
119 return value
120
121 if truncate_type == "tail":
122 return truncate_tail(value, character_count)
123
124 elif truncate_type == "head":
125 return truncate_head(value, character_count)
126
127 elif truncate_type == "middle":
128 return truncate_middle(value, character_count)
129
130
131truncatechars.is_safe = True
132truncate_head.is_safe = True
133truncate_tail.is_safe = True
134truncate_middle.is_safe = True
135
Back to Top