Ticket #12200: truncate.py

File truncate.py, 3.4 KB (added by paulschreiber, 5 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