Skip to content

textfilters

Class info

🛈 DocStrings

dirname_to_title

dirname_to_title(dirname: str | PathLike[str]) -> str

Return a page tile obtained from a directory name.

Replaces dashes and underscores with spaces and capitalizes the first letter in case all letters are lowercase

Parameters:

Name Type Description Default
dirname str | PathLike[str]

directory to get a title for

required
Source code in src/jinjarope/textfilters.py
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
def dirname_to_title(dirname: str | os.PathLike[str]) -> str:
    """Return a page tile obtained from a directory name.

    Replaces dashes and underscores with spaces and capitalizes the first letter
    in case all letters are lowercase

    Args:
        dirname: directory to get a title for
    """
    title = str(dirname)
    title = title.replace("-", " ").replace("_", " ")
    if title.lower() == title:
        title = title.capitalize()

    return title

escape

escape(text: str) -> str

Escape text using Markupsafe library.

Parameters:

Name Type Description Default
text str

text to escape

required
Source code in src/jinjarope/textfilters.py
213
214
215
216
217
218
219
220
221
def escape(text: str) -> str:
    """Escape text using Markupsafe library.

    Args:
        text: text to escape
    """
    import markupsafe

    return markupsafe.escape(text)

extract_body cached

extract_body(src: str) -> str

Get body of source code of given function / class.

Strips off the signature / decorators.

Parameters:

Name Type Description Default
src str

Source code to extract the body from

required
Source code in src/jinjarope/textfilters.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
@functools.cache
def extract_body(src: str) -> str:
    """Get body of source code of given function / class.

    Strips off the signature / decorators.

    Args:
        src: Source code to extract the body from
    """
    # see https://stackoverflow.com/questions/38050649
    lines = src.split("\n")
    src_lines = itertools.dropwhile(lambda x: x.strip().startswith("@"), lines)
    line = next(src_lines).strip()  # type: ignore
    if not line.startswith(("def ", "class ")):
        return line.rsplit(":")[-1].strip()
    if not line.endswith(":"):
        for line in src_lines:
            line = line.strip()
            if line.endswith(":"):
                break
    return "".join(src_lines)

format_code cached

format_code(code: str, line_length: int = 100)

Format code to given line length using black.

Parameters:

Name Type Description Default
code str

The code to format

required
line_length int

Line length limit for formatted code

100
Source code in src/jinjarope/textfilters.py
86
87
88
89
90
91
92
93
94
95
96
97
98
@functools.cache
def format_code(code: str, line_length: int = 100):
    """Format code to given line length using `black`.

    Args:
        code: The code to format
        line_length: Line length limit for formatted code
    """
    code = code.strip()
    if len(code) < line_length:
        return code
    formatter = utils._get_black_formatter()
    return formatter(code, line_length)

format_filter_signature

format_filter_signature(
    fn: Callable, filter_name: str, follow_wrapped: bool = True, eval_str: bool = False
) -> str

Create a signature for a jinja filter based on filter name and callable.

Outputs text in shape of "code: 'str' | test(line_length: 'int' = 100)"

Parameters:

Name Type Description Default
fn Callable

The callable to format the signature from

required
filter_name str

Name of the jinja filter

required
follow_wrapped bool

Whether to unwrap the callable

True
eval_str bool

Un-stringize annotations using eval

False
Source code in src/jinjarope/textfilters.py
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
def format_filter_signature(
    fn: Callable,
    filter_name: str,
    follow_wrapped: bool = True,
    eval_str: bool = False,
) -> str:
    """Create a signature for a jinja filter based on filter name and callable.

    Outputs text in shape of
    "code: 'str' | test(line_length: 'int' = 100)"

    Args:
        fn: The callable to format the signature from
        filter_name: Name of the jinja filter
        follow_wrapped: Whether to unwrap the callable
        eval_str: Un-stringize annotations using eval
    """
    sig = inspect.signature(fn, follow_wrapped=follow_wrapped, eval_str=eval_str)
    params = dict(sig._parameters)  # type: ignore[attr-defined]
    if hasattr(fn, "jinja_pass_arg"):
        # for @pass_xyz decorated functions
        params.pop(next(iter(params)))
    first_val = params.pop(next(iter(params)))
    sig._parameters = params  # type: ignore[attr-defined]
    return f"{first_val} | {filter_name}{sig}"

format_signature cached

format_signature(
    fn: Callable,
    follow_wrapped: bool = True,
    eval_str: bool = True,
    remove_jinja_arg: bool = False,
) -> str

Format signature of a callable.

Parameters:

Name Type Description Default
fn Callable

The callable to format the signature from

required
follow_wrapped bool

Whether to unwrap the callable

True
eval_str bool

Un-stringize annotations using eval

True
remove_jinja_arg bool

If true, remove the first argument for pass_xyz decorated fns.

False
Source code in src/jinjarope/textfilters.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
@functools.cache
def format_signature(
    fn: Callable,
    follow_wrapped: bool = True,
    eval_str: bool = True,
    remove_jinja_arg: bool = False,
) -> str:
    """Format signature of a callable.

    Args:
        fn: The callable to format the signature from
        follow_wrapped: Whether to unwrap the callable
        eval_str: Un-stringize annotations using eval
        remove_jinja_arg: If true, remove the first argument for pass_xyz decorated fns.
    """
    if eval_str:
        try:
            sig = inspect.signature(fn, follow_wrapped=follow_wrapped, eval_str=True)
        except (TypeError, NameError):
            sig = inspect.signature(fn, follow_wrapped=follow_wrapped, eval_str=False)
    else:
        sig = inspect.signature(fn, follow_wrapped=follow_wrapped, eval_str=False)
    if remove_jinja_arg and hasattr(fn, "jinja_pass_arg"):
        # for @pass_xyz decorated functions
        params = dict(sig._parameters)  # type: ignore[attr-defined]
        params.pop(next(iter(params)))
        sig._parameters = params  # type: ignore[attr-defined]
    return str(sig)

format_timestamp

format_timestamp(timestamp: float, fmt: str) -> str

Format Unix timestamp to date string.

Parameters:

Name Type Description Default
timestamp float

Unix timestamp to format

required
fmt str

Format string according to strftime() format codes

required

Returns:

Type Description
str

Formatted date string

Source code in src/jinjarope/textfilters.py
224
225
226
227
228
229
230
231
232
233
234
def format_timestamp(timestamp: float, fmt: str) -> str:
    """Format Unix timestamp to date string.

    Args:
        timestamp: Unix timestamp to format
        fmt: Format string according to strftime() format codes

    Returns:
        Formatted date string
    """
    return datetime.datetime.fromtimestamp(timestamp).strftime(fmt)

lower_camel_case

lower_camel_case(text: str) -> str

Convert given text to lower-camel-case.

Parameters:

Name Type Description Default
text str

The string to convert

required
Source code in src/jinjarope/textfilters.py
61
62
63
64
65
66
67
68
69
70
71
def lower_camel_case(text: str) -> str:
    """Convert given text to lower-camel-case.

    Args:
        text: The string to convert
    """
    # do nothing if nothing to camel
    if "_" not in text:
        return text
    first, *others = text.split("_")
    return "".join([first.lower(), *map(str.title, others)])

lstrip

lstrip(text: str, chars: str | None = None) -> str

Strip given chars from beginning of string.

Parameters:

Name Type Description Default
text str

The text to strip the chars from

required
chars str | None

The chars to remove

None
Source code in src/jinjarope/textfilters.py
41
42
43
44
45
46
47
48
def lstrip(text: str, chars: str | None = None) -> str:
    """Strip given chars from beginning of string.

    Args:
        text: The text to strip the chars from
        chars: The chars to remove
    """
    return text.lstrip(chars)

removeprefix

removeprefix(text: str, prefix: str) -> str

Return given prefix from text.

Parameters:

Name Type Description Default
text str

The text to strip the prefix from

required
prefix str

The prefix to remove

required
Source code in src/jinjarope/textfilters.py
31
32
33
34
35
36
37
38
def removeprefix(text: str, prefix: str) -> str:
    """Return given prefix from text.

    Args:
        text: The text to strip the prefix from
        prefix: The prefix to remove
    """
    return text.removeprefix(prefix)

removesuffix

removesuffix(text: str, suffix: str) -> str

Return given suffix from text.

Parameters:

Name Type Description Default
text str

The text to strip the suffix from

required
suffix str

The suffix to remove

required
Source code in src/jinjarope/textfilters.py
21
22
23
24
25
26
27
28
def removesuffix(text: str, suffix: str) -> str:
    """Return given suffix from text.

    Args:
        text: The text to strip the suffix from
        suffix: The suffix to remove
    """
    return text.removesuffix(suffix)

rstrip

rstrip(text: str, chars: str | None = None) -> str

Strip given chars from end of string.

Parameters:

Name Type Description Default
text str

The text to strip the chars from

required
chars str | None

The chars to remove

None
Source code in src/jinjarope/textfilters.py
51
52
53
54
55
56
57
58
def rstrip(text: str, chars: str | None = None) -> str:
    """Strip given chars from end of string.

    Args:
        text: The text to strip the chars from
        chars: The chars to remove
    """
    return text.rstrip(chars)

slugify

slugify(text: str | PathLike[str]) -> str

Create a slug for given text.

Returned text only contains alphanumerical and underscore.

Parameters:

Name Type Description Default
text str | PathLike[str]

text to get a slug for

required
Source code in src/jinjarope/textfilters.py
181
182
183
184
185
186
187
188
189
190
191
192
193
def slugify(text: str | os.PathLike[str]) -> str:
    """Create a slug for given text.

    Returned text only contains alphanumerical and underscore.

    Args:
        text: text to get a slug for
    """
    import re

    text = str(text).lower()
    text = re.sub("[^0-9a-zA-Z_.]", "_", text)
    return re.sub("^[^0-9a-zA-Z_#]+", "", text)

snake_case

snake_case(text: str) -> str

Convert given text to snake-case.

Parameters:

Name Type Description Default
text str

The string to convert

required
Source code in src/jinjarope/textfilters.py
74
75
76
77
78
79
80
81
82
83
def snake_case(text: str) -> str:
    """Convert given text to snake-case.

    Args:
        text: The string to convert
    """
    #  don't snake-case snakes.
    if "_" in text:
        return text
    return CASE_PATTERN.sub("_", text).lower()