# ansi-string
ANSI String Formatter in Python for CLI Color and Style Formatting
## Introduction
This code was originally written for [greplica](https://pypi.org/project/greplica/), but I felt it deserved its own, separate library.
The main goals for this project are:
- To provide a simple way to construct a string-like object with embedded ANSI formatting without requiring the developer to know how ANSI formatting works
- Provide a way to further format the object using format string
- Allow for concatenation of the object
## Contribution
Feel free to open a bug report or make a merge request on [github](https://github.com/Tails86/ansi-string/issues).
## Installation
This project is uploaded to PyPI at https://pypi.org/project/ansi-string
To install, ensure you are connected to the internet and execute: `python3 -m pip install ansi-string --upgrade`
## Examples
### AnsiString
#### Example 1
Code:
```py
from ansi_string import AnsiString
s = AnsiString('This string is red and bold', AnsiFormat.BOLD, AnsiFormat.RED)
print(s)
```
Output:
![Example 1 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out1.png)
#### Example 2
Code:
```py
from ansi_string import AnsiString, AnsiFormat
s = AnsiString.join('This ', AnsiString('string', AnsiFormat.BOLD))
s += AnsiString(' contains ') + AnsiString('multiple', AnsiFormat.BG_BLUE)
s += ' color settings across different ranges'
s.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)
# Blue and orange will conflict - blue applied on bottom, so orange will show for [21:35]
s.apply_formatting(AnsiFormat.FG_BLUE, 21, 44, topmost=False)
print(s)
```
Output:
![Example 2 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out2.png)
#### Example 3
Code:
```py
from ansi_string import AnsiString
s = AnsiString('This string will be formatted bold and red, right justify')
# An AnsiString format string uses the format: [string_format[:ansi_format]]
# For ansi_format, use any name within AnsiFormat and separate directives with semicolons
print('{:>90:bold;red}'.format(s))
```
Output:
![Example 3 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out3.png)
#### Example 4
Code:
```py
from ansi_string import AnsiString
s = AnsiString('This string will be formatted bold and red')
# Use double colon to skip specification of string_format
print('{::bold;red}'.format(s))
```
Output:
![Example 4 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out4.png)
#### Example 5
Code:
```py
from ansi_string import AnsiString
s1 = 'This is a normal string'
s2 = AnsiString('This is an ANSI string')
# AnsiString may also be used in an F-String
print(f'String 1: "{s1}" String 2: "{s2::bold;purple}"')
```
Output:
![Example 5 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out5.png)
#### Example 6
Code:
```py
from ansi_string import AnsiString
s = AnsiString('Manually adjust colors of foreground, background, and underline')
print(f'{s::rgb(0x8A2BE2);bg_rgb(100, 232, 170);ul_rgb(0xFF, 0x63, 0x47)}')
```
Output:
![Example 6 Output](https://raw.githubusercontent.com/Tails86/ansi-string/76fd7fe127ab65c2b0ff5215f1b1ce9e253d50e9/docs/out6.png)
#### Example 7
Code:
```py
from ansi_string import AnsiString, AnsiFormat
s = AnsiString(
'This example shows how to format and unformat matching',
AnsiFormat.dul_rgb(0xFF, 0x80, 0x00),
AnsiFormat.ITALIC
)
s.format_matching('[a-z]*mat', AnsiFormat.RED, match_case=True, regex=True)
s.unformat_matching('unformat') # don't specify any format to remove all formatting in matching range
print(s)
```
Output:
![Example 7 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out7.png)
#### More Examples
Refer to the [AnsiString test file](https://github.com/Tails86/ansi-string/blob/main/tests/test_ansi_string.py) for more examples on how to use the AnsiString class.
### AnsiStr
AnsiStr is an immutable version of AnsiString. The advantage of this object is that isinstance(AnsiStr(), str) returns True. The disadvantages are that all formatting functionality return a new object rather than formatting in-place, and the output is always automatically simplified, so using escape codes outside of the internally-known ones may result in undesired behavior.
#### Example 1
Code:
```py
from ansi_string import AnsiStr
s = AnsiStr('This string is red and bold', AnsiFormat.BOLD, AnsiFormat.RED)
print(s)
```
Output:
![Example 1 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out1.png)
#### Example 2
Code:
```py
from ansi_string import AnsiStr, AnsiFormat
s = AnsiStr.join('This ', AnsiStr('string', AnsiFormat.BOLD))
s += AnsiStr(' contains ') + AnsiStr('multiple', AnsiFormat.BG_BLUE)
s += ' color settings across different ranges'
# Since AnsiStr is immutable, apply_formatting() returns a new object rather than formatting in-place
s = s.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)
# Blue and orange will conflict - blue applied on bottom, so orange will show for [21:35]
s = s.apply_formatting(AnsiFormat.FG_BLUE, 21, 44, topmost=False)
print(s)
```
Output:
![Example 2 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out2.png)
#### Example 3
Code:
```py
from ansi_string import AnsiStr
s = AnsiStr('This string will be formatted bold and red, right justify')
# An AnsiStr format string uses the format: [string_format[:ansi_format]]
# For ansi_format, use any name within AnsiFormat and separate directives with semicolons
print('{:>90:bold;red}'.format(s))
```
Output:
![Example 3 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out3.png)
#### Example 4
Code:
```py
from ansi_string import AnsiStr
s = AnsiStr('This string will be formatted bold and red')
# Use double colon to skip specification of string_format
print('{::bold;red}'.format(s))
```
Output:
![Example 4 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out4.png)
#### Example 5
Code:
```py
from ansi_string import AnsiStr
s1 = 'This is a normal string'
s2 = AnsiStr('This is an ANSI string')
# AnsiStr may also be used in an F-String
print(f'String 1: "{s1}" String 2: "{s2::bold;purple}"')
```
Output:
![Example 5 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out5.png)
#### Example 6
Code:
```py
from ansi_string import AnsiStr
s = AnsiStr('Manually adjust colors of foreground, background, and underline')
print(f'{s::rgb(0x8A2BE2);bg_rgb(100, 232, 170);ul_rgb(0xFF, 0x63, 0x47)}')
```
Output:
![Example 6 Output](https://raw.githubusercontent.com/Tails86/ansi-string/76fd7fe127ab65c2b0ff5215f1b1ce9e253d50e9/docs/out6.png)
#### Example 7
Code:
```py
from ansi_string import AnsiStr, AnsiFormat
s = AnsiStr(
'This example shows how to format and unformat matching',
AnsiFormat.dul_rgb(0xFF, 0x80, 0x00),
AnsiFormat.ITALIC
)
# Since AnsiStr is immutable, these calls return a new object rather than formatting in-place
s = s.format_matching('[a-z]*mat', AnsiFormat.RED, match_case=True, regex=True)
s = s.unformat_matching('unformat') # don't specify any format to remove all formatting in matching range
print(s)
```
Output:
![Example 7 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out7.png)
#### More Examples
Refer to the [AnsiStr test file](https://github.com/Tails86/ansi-string/blob/main/tests/test_ansi_str.py) for examples on how to use AnsiStr.
## Usage
To begin, import AnsiString from the ansi_string module.
```py
from ansi_string import en_tty_ansi, AnsiFormat, AnsiString
```
### Enabling ANSI Formatting
Windows requires ANSI formatting to be enabled before it can be used. This can either be set in the environment or by simply calling the following before printing so that ANSI is enabled locally.
```py
en_tty_ansi()
```
If this also needs to be enabled for stderr, stderr may also be passed to this method.
```py
import sys
en_tty_ansi(sys.stderr)
```
For Windows, this returns True if the given IO is a TTY (i.e. not piped to a file) and enabling ANSI was successful. For all other operating systems, this will return True if and only if the given IO is a TTY (i.e. isatty()); no other action is taken.
### Construction
The AnsiString and AnsiStr classes contains the following `__init__` method.
```py
def __init__(self, s:str='', *setting_or_settings:Union[List[str], str, List[int], int, List[AnsiFormat], AnsiFormat]): ...
```
The first argument, `s`, is a string to be formatted. The next 0 to N arguments are formatting setting directives that can be applied to the entire string. These arguments can be in the form of any of the following.
- An AnsiFormat enum (ex: `AnsiFormat.BOLD`)
- The result of calling `AnsiFormat.rgb()`, `AnsiFormat.fg_rgb()`, `AnsiFormat.bg_rgb()`, `AnsiFormat.ul_rgb()`, or `AnsiFormat.dul_rgb()`
- A string color or formatting name (i.e. any name of the AnsiFormat enum in lower or upper case)
- An `rgb(...)` function directive as a string (ex: `"rgb(255, 255, 255)"`)
- `rgb(...)` or `fg_rgb(...)` to adjust text color
- `bg_rgb(...)` to adjust background color
- `ul_rgb(...)` to enable underline and set the underline color
- `dul_rgb(...)` to enable double underline and set the underline color
- Value given may be either a 24-bit integer or 3 x 8-bit integers, separated by commas
- Each given value within the parenthesis is treated as hexadecimal if the value starts with "0x", otherwise it is treated as a decimal value
A formatting setting may also be any of the following, but it's not advised to specify settings in any of these ways unless there is a specific reason to do so.
- An AnsiSetting object
- A string containing known ANSI directives (ex: `"01;31"` for BOLD and FG_RED)
- The string will normally be parsed into separate settings unless the character "[" is the first character of the string (ex: `"[38;5;214"`)
- Never specify the reset directive (0) because this is implicitly handled internally
- A single ANSI directive as an integer
Examples:
```py
# Set foreground to light_sea_green using string directive
# Set background to chocolate using AnsiFormat directive
# Underline in gray using ul_rgb() directive
# Enable italics using explicit string directive ("3")
# Enable bold using explicit integer directive (1)
s = AnsiString("This is an ANSI string", "light_sea_green", AnsiFormat.BG_CHOCOLATE, "ul_rgb(0x808080)", "3", 1)
print(s)
```
### Concatenation
- The static methods `AnsiString.join()` and `AnsiStr.join()` are provided to join together 0 to many `AnsiStr`, `AnsiString`, and `str` values into a single `AnsiString` or `AnsiStr`.
- The `+` operator may be used to join an `AnsiString` or `AnsiStr` with another `AnsiStr`, `AnsiString`, or `str` into a new object
- The `+` operator may not be used if the left-hand-side value is a `str` and the right-hand-side values is an `AnsiString` or `AnsiStr`
- The `+=` operator may be used to append an `AnsiStr`, `AnsiString`, or `str` to an `AnsiString` or `AnsiStr`
Examples:
```py
s = AnsiString.join("This ", AnsiStr("string", AnsiFormat.BOLD))
s += AnsiStr(" contains ") + AnsiStr("multiple", AnsiFormat.BG_BLUE)
s += AnsiString(" color ", AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC) + "settings accross different ranges"
print(s)
```
### Formatting
#### apply_formatting
The method `AnsiString.apply_formatting()` is provided to append formatting to a previously constructed `AnsiString`. The method `AnsiStr.apply_formatting()` works similarly except it returns a new object since `AnsiStr` is immutable.
Example:
```py
s = AnsiString("This string contains multiple color settings across different ranges")
s.apply_formatting(AnsiFormat.BOLD, 5, 11)
s.apply_formatting(AnsiFormat.BG_BLUE, 21, 29)
s.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)
print(s)
# This will result in the same printout using AnsiStr instead of AnsiString
s = AnsiStr("This string contains multiple color settings across different ranges")
s = s.apply_formatting(AnsiFormat.BOLD, 5, 11)
s = s.apply_formatting(AnsiFormat.BG_BLUE, 21, 29)
s = s.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)
print(s)
```
#### Format String
A format string may be used to format an AnsiString before printing. The format specification string must be in the format `"[string_format][:ansi_format]"` where `string_format` is the standard string format specifier and `ansi_format` contains 0 or more ANSI directives separated by semicolons (;). The ANSI directives may be any of the same string values that can be passed to the `AnsiString` constructor. If no `string_format` is desired, then it can be set to an empty string. This same functionality is available in `AnsiStr`.
Examples:
```py
ansi_str = AnsiString("This is an ANSI string")
# Right justify with width of 100, formatted bold and red
print("{:>100:bold;red}".format(ansi_str))
# No justification settings, formatted bold and red
print("{::bold;red}".format(ansi_str))
# No justification settings, formatted bold and red
print("{::bold;rgb(255, 0, 0)}".format(ansi_str))
# No justification settings, formatted bold and red
print(f"{ansi_str::bold;red}")
# Format text, background, and underline with custom colors
fg_color = 0x8A2BE2
bg_colors = [100, 232, 170]
ul_colors = [0xFF, 0x63, 0x47]
print(f"{ansi_str::rgb({fg_color});bg_rgb({bg_colors});ul_rgb({ul_colors})}")
```
#### format_matching and unformat_matching
The methods `AnsiString.format_matching()` and `AnsiString.unformat_matching()` are provided to apply or remove formatting of an `AnsiString` based on a match specification. The methods `AnsiStr.format_matching()` and `AnsiStr.unformat_matching()` work similarly except they return a new object since `AnsiStr` is immutable.
Example:
```py
s = AnsiString("Here is a strING that I will match formatting", AnsiFormat.BOLD)
# This will make the word "formatting" cyan with a pink background
s.format_matching("[A-Za-z]+ing", "cyan", AnsiFormat.BG_PINK, regex=True, match_case=True)
# This will remove BOLD from "strING" and "formatting"
s.unformat_matching("[A-Za-z]+ing", AnsiFormat.BOLD, regex=True)
print(s)
# This will result in the same printout using AnsiStr instead of AnsiString
s = AnsiStr("Here is a strING that I will match formatting", AnsiFormat.BOLD)
# This will make the word "formatting" cyan with a pink background
s = s.format_matching("[A-Za-z]+ing", "cyan", AnsiFormat.BG_PINK, regex=True, match_case=True)
# This will remove BOLD from "strING" and "formatting"
s = s.unformat_matching("[A-Za-z]+ing", AnsiFormat.BOLD, regex=True)
print(s)
```
#### clear_formatting
Calling the method `AnsiString.clear_formatting()` will clear all formatting applied. The method `AnsiStr.clear_formatting()` works similarly except it returns a new object since `AnsiStr` is immutable.
### String Assignment
The method `AnsiString.assign_str()` may be used to assign the internal string and adjust formatting as necessary. There is no associated function available in `AnsiStr`.
### Base String Retrieval
The attributes `AnsiString.base_str` and `AnsiStr.base_str` may be used to retrieve the unformatted base string.
### Format Status
The methods `AnsiString.ansi_settings_at()` and `AnsiString.settings_at()` may be used to retrieve the settings applied over a single character. The same methods exist in `AnsiStr`.
### Other String Methods
Many other methods that are found in the `str` class such as `replace()` are available in `AnsiString` and `AnsiStr` which manipulate the string while applying formatting where necessary.
- capitalize
- casefold
- center
- count
- encode
- endswith
- expandtabs
- find
- index
- isalnum
- isalpha
- isascii
- isdecimal
- isdigit
- isidentifier
- islower
- isnumeric
- isprintable
- isspace
- istitle
- isupper
- ljust
- lower
- lstrip
- partition
- removeprefix
- removesuffix
- replace
- rfind
- rindex
- rjust
- rpartition
- rsplit
- rstrip
- split
- splitlines
- strip
- swapcase
- title
- upper
- zfill
Raw data
{
"_id": null,
"home_page": "https://github.com/Tails86/ansi-string",
"name": "ansi-string",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "ANSI, string",
"author": "James Smith",
"author_email": "jmsmith86@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/51/ac/aeef1a1fccd0c6098f83698d26eb5847e2763263c38b113ce73e71d4a930/ansi-string-1.1.2.tar.gz",
"platform": null,
"description": "# ansi-string\n\nANSI String Formatter in Python for CLI Color and Style Formatting\n\n## Introduction\n\nThis code was originally written for [greplica](https://pypi.org/project/greplica/), but I felt it deserved its own, separate library.\n\nThe main goals for this project are:\n- To provide a simple way to construct a string-like object with embedded ANSI formatting without requiring the developer to know how ANSI formatting works\n- Provide a way to further format the object using format string\n- Allow for concatenation of the object\n\n## Contribution\n\nFeel free to open a bug report or make a merge request on [github](https://github.com/Tails86/ansi-string/issues).\n\n## Installation\nThis project is uploaded to PyPI at https://pypi.org/project/ansi-string\n\nTo install, ensure you are connected to the internet and execute: `python3 -m pip install ansi-string --upgrade`\n\n## Examples\n\n### AnsiString\n\n#### Example 1\nCode:\n```py\nfrom ansi_string import AnsiString\ns = AnsiString('This string is red and bold', AnsiFormat.BOLD, AnsiFormat.RED)\nprint(s)\n```\nOutput:\n![Example 1 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out1.png)\n\n#### Example 2\n\nCode:\n```py\nfrom ansi_string import AnsiString, AnsiFormat\ns = AnsiString.join('This ', AnsiString('string', AnsiFormat.BOLD))\ns += AnsiString(' contains ') + AnsiString('multiple', AnsiFormat.BG_BLUE)\ns += ' color settings across different ranges'\ns.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)\n# Blue and orange will conflict - blue applied on bottom, so orange will show for [21:35]\ns.apply_formatting(AnsiFormat.FG_BLUE, 21, 44, topmost=False)\nprint(s)\n```\nOutput:\n![Example 2 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out2.png)\n\n#### Example 3\n\nCode:\n```py\nfrom ansi_string import AnsiString\ns = AnsiString('This string will be formatted bold and red, right justify')\n# An AnsiString format string uses the format: [string_format[:ansi_format]]\n# For ansi_format, use any name within AnsiFormat and separate directives with semicolons\nprint('{:>90:bold;red}'.format(s))\n```\nOutput:\n![Example 3 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out3.png)\n\n#### Example 4\n\nCode:\n```py\nfrom ansi_string import AnsiString\ns = AnsiString('This string will be formatted bold and red')\n# Use double colon to skip specification of string_format\nprint('{::bold;red}'.format(s))\n```\nOutput:\n![Example 4 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out4.png)\n\n#### Example 5\n\nCode:\n```py\nfrom ansi_string import AnsiString\ns1 = 'This is a normal string'\ns2 = AnsiString('This is an ANSI string')\n# AnsiString may also be used in an F-String\nprint(f'String 1: \"{s1}\" String 2: \"{s2::bold;purple}\"')\n```\nOutput:\n![Example 5 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out5.png)\n\n#### Example 6\n\nCode:\n```py\nfrom ansi_string import AnsiString\ns = AnsiString('Manually adjust colors of foreground, background, and underline')\nprint(f'{s::rgb(0x8A2BE2);bg_rgb(100, 232, 170);ul_rgb(0xFF, 0x63, 0x47)}')\n```\nOutput:\n![Example 6 Output](https://raw.githubusercontent.com/Tails86/ansi-string/76fd7fe127ab65c2b0ff5215f1b1ce9e253d50e9/docs/out6.png)\n\n#### Example 7\n\nCode:\n```py\nfrom ansi_string import AnsiString, AnsiFormat\ns = AnsiString(\n 'This example shows how to format and unformat matching',\n AnsiFormat.dul_rgb(0xFF, 0x80, 0x00),\n AnsiFormat.ITALIC\n)\ns.format_matching('[a-z]*mat', AnsiFormat.RED, match_case=True, regex=True)\ns.unformat_matching('unformat') # don't specify any format to remove all formatting in matching range\nprint(s)\n```\nOutput:\n![Example 7 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out7.png)\n\n#### More Examples\n\nRefer to the [AnsiString test file](https://github.com/Tails86/ansi-string/blob/main/tests/test_ansi_string.py) for more examples on how to use the AnsiString class.\n\n### AnsiStr\n\nAnsiStr is an immutable version of AnsiString. The advantage of this object is that isinstance(AnsiStr(), str) returns True. The disadvantages are that all formatting functionality return a new object rather than formatting in-place, and the output is always automatically simplified, so using escape codes outside of the internally-known ones may result in undesired behavior.\n\n#### Example 1\nCode:\n```py\nfrom ansi_string import AnsiStr\ns = AnsiStr('This string is red and bold', AnsiFormat.BOLD, AnsiFormat.RED)\nprint(s)\n```\nOutput:\n![Example 1 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out1.png)\n\n#### Example 2\n\nCode:\n```py\nfrom ansi_string import AnsiStr, AnsiFormat\ns = AnsiStr.join('This ', AnsiStr('string', AnsiFormat.BOLD))\ns += AnsiStr(' contains ') + AnsiStr('multiple', AnsiFormat.BG_BLUE)\ns += ' color settings across different ranges'\n# Since AnsiStr is immutable, apply_formatting() returns a new object rather than formatting in-place\ns = s.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)\n# Blue and orange will conflict - blue applied on bottom, so orange will show for [21:35]\ns = s.apply_formatting(AnsiFormat.FG_BLUE, 21, 44, topmost=False)\nprint(s)\n```\nOutput:\n![Example 2 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out2.png)\n\n#### Example 3\n\nCode:\n```py\nfrom ansi_string import AnsiStr\ns = AnsiStr('This string will be formatted bold and red, right justify')\n# An AnsiStr format string uses the format: [string_format[:ansi_format]]\n# For ansi_format, use any name within AnsiFormat and separate directives with semicolons\nprint('{:>90:bold;red}'.format(s))\n```\nOutput:\n![Example 3 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out3.png)\n\n#### Example 4\n\nCode:\n```py\nfrom ansi_string import AnsiStr\ns = AnsiStr('This string will be formatted bold and red')\n# Use double colon to skip specification of string_format\nprint('{::bold;red}'.format(s))\n```\nOutput:\n![Example 4 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out4.png)\n\n#### Example 5\n\nCode:\n```py\nfrom ansi_string import AnsiStr\ns1 = 'This is a normal string'\ns2 = AnsiStr('This is an ANSI string')\n# AnsiStr may also be used in an F-String\nprint(f'String 1: \"{s1}\" String 2: \"{s2::bold;purple}\"')\n```\nOutput:\n![Example 5 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out5.png)\n\n#### Example 6\n\nCode:\n```py\nfrom ansi_string import AnsiStr\ns = AnsiStr('Manually adjust colors of foreground, background, and underline')\nprint(f'{s::rgb(0x8A2BE2);bg_rgb(100, 232, 170);ul_rgb(0xFF, 0x63, 0x47)}')\n```\nOutput:\n![Example 6 Output](https://raw.githubusercontent.com/Tails86/ansi-string/76fd7fe127ab65c2b0ff5215f1b1ce9e253d50e9/docs/out6.png)\n\n#### Example 7\n\nCode:\n```py\nfrom ansi_string import AnsiStr, AnsiFormat\ns = AnsiStr(\n 'This example shows how to format and unformat matching',\n AnsiFormat.dul_rgb(0xFF, 0x80, 0x00),\n AnsiFormat.ITALIC\n)\n# Since AnsiStr is immutable, these calls return a new object rather than formatting in-place\ns = s.format_matching('[a-z]*mat', AnsiFormat.RED, match_case=True, regex=True)\ns = s.unformat_matching('unformat') # don't specify any format to remove all formatting in matching range\nprint(s)\n```\nOutput:\n![Example 7 Output](https://raw.githubusercontent.com/Tails86/ansi-string/32d5b2fed1c1ac061a5382b80faa65bbf794290c/docs/out7.png)\n\n#### More Examples\n\nRefer to the [AnsiStr test file](https://github.com/Tails86/ansi-string/blob/main/tests/test_ansi_str.py) for examples on how to use AnsiStr.\n\n## Usage\n\nTo begin, import AnsiString from the ansi_string module.\n\n```py\nfrom ansi_string import en_tty_ansi, AnsiFormat, AnsiString\n```\n\n### Enabling ANSI Formatting\n\nWindows requires ANSI formatting to be enabled before it can be used. This can either be set in the environment or by simply calling the following before printing so that ANSI is enabled locally.\n```py\nen_tty_ansi()\n```\n\nIf this also needs to be enabled for stderr, stderr may also be passed to this method.\n```py\nimport sys\nen_tty_ansi(sys.stderr)\n```\n\nFor Windows, this returns True if the given IO is a TTY (i.e. not piped to a file) and enabling ANSI was successful. For all other operating systems, this will return True if and only if the given IO is a TTY (i.e. isatty()); no other action is taken.\n\n### Construction\n\nThe AnsiString and AnsiStr classes contains the following `__init__` method.\n\n```py\n def __init__(self, s:str='', *setting_or_settings:Union[List[str], str, List[int], int, List[AnsiFormat], AnsiFormat]): ...\n```\n\nThe first argument, `s`, is a string to be formatted. The next 0 to N arguments are formatting setting directives that can be applied to the entire string. These arguments can be in the form of any of the following.\n- An AnsiFormat enum (ex: `AnsiFormat.BOLD`)\n- The result of calling `AnsiFormat.rgb()`, `AnsiFormat.fg_rgb()`, `AnsiFormat.bg_rgb()`, `AnsiFormat.ul_rgb()`, or `AnsiFormat.dul_rgb()`\n- A string color or formatting name (i.e. any name of the AnsiFormat enum in lower or upper case)\n- An `rgb(...)` function directive as a string (ex: `\"rgb(255, 255, 255)\"`)\n - `rgb(...)` or `fg_rgb(...)` to adjust text color\n - `bg_rgb(...)` to adjust background color\n - `ul_rgb(...)` to enable underline and set the underline color\n - `dul_rgb(...)` to enable double underline and set the underline color\n - Value given may be either a 24-bit integer or 3 x 8-bit integers, separated by commas\n - Each given value within the parenthesis is treated as hexadecimal if the value starts with \"0x\", otherwise it is treated as a decimal value\n\nA formatting setting may also be any of the following, but it's not advised to specify settings in any of these ways unless there is a specific reason to do so.\n- An AnsiSetting object\n- A string containing known ANSI directives (ex: `\"01;31\"` for BOLD and FG_RED)\n - The string will normally be parsed into separate settings unless the character \"[\" is the first character of the string (ex: `\"[38;5;214\"`)\n - Never specify the reset directive (0) because this is implicitly handled internally\n- A single ANSI directive as an integer\n\nExamples:\n\n```py\n# Set foreground to light_sea_green using string directive\n# Set background to chocolate using AnsiFormat directive\n# Underline in gray using ul_rgb() directive\n# Enable italics using explicit string directive (\"3\")\n# Enable bold using explicit integer directive (1)\ns = AnsiString(\"This is an ANSI string\", \"light_sea_green\", AnsiFormat.BG_CHOCOLATE, \"ul_rgb(0x808080)\", \"3\", 1)\nprint(s)\n```\n\n### Concatenation\n\n- The static methods `AnsiString.join()` and `AnsiStr.join()` are provided to join together 0 to many `AnsiStr`, `AnsiString`, and `str` values into a single `AnsiString` or `AnsiStr`.\n- The `+` operator may be used to join an `AnsiString` or `AnsiStr` with another `AnsiStr`, `AnsiString`, or `str` into a new object\n - The `+` operator may not be used if the left-hand-side value is a `str` and the right-hand-side values is an `AnsiString` or `AnsiStr`\n- The `+=` operator may be used to append an `AnsiStr`, `AnsiString`, or `str` to an `AnsiString` or `AnsiStr`\n\nExamples:\n\n```py\ns = AnsiString.join(\"This \", AnsiStr(\"string\", AnsiFormat.BOLD))\ns += AnsiStr(\" contains \") + AnsiStr(\"multiple\", AnsiFormat.BG_BLUE)\ns += AnsiString(\" color \", AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC) + \"settings accross different ranges\"\nprint(s)\n```\n\n### Formatting\n\n#### apply_formatting\n\nThe method `AnsiString.apply_formatting()` is provided to append formatting to a previously constructed `AnsiString`. The method `AnsiStr.apply_formatting()` works similarly except it returns a new object since `AnsiStr` is immutable.\n\nExample:\n\n```py\ns = AnsiString(\"This string contains multiple color settings across different ranges\")\ns.apply_formatting(AnsiFormat.BOLD, 5, 11)\ns.apply_formatting(AnsiFormat.BG_BLUE, 21, 29)\ns.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)\nprint(s)\n\n# This will result in the same printout using AnsiStr instead of AnsiString\ns = AnsiStr(\"This string contains multiple color settings across different ranges\")\ns = s.apply_formatting(AnsiFormat.BOLD, 5, 11)\ns = s.apply_formatting(AnsiFormat.BG_BLUE, 21, 29)\ns = s.apply_formatting([AnsiFormat.FG_ORANGE, AnsiFormat.ITALIC], 21, 35)\nprint(s)\n```\n\n#### Format String\n\nA format string may be used to format an AnsiString before printing. The format specification string must be in the format `\"[string_format][:ansi_format]\"` where `string_format` is the standard string format specifier and `ansi_format` contains 0 or more ANSI directives separated by semicolons (;). The ANSI directives may be any of the same string values that can be passed to the `AnsiString` constructor. If no `string_format` is desired, then it can be set to an empty string. This same functionality is available in `AnsiStr`.\n\nExamples:\n\n```py\nansi_str = AnsiString(\"This is an ANSI string\")\n# Right justify with width of 100, formatted bold and red\nprint(\"{:>100:bold;red}\".format(ansi_str))\n# No justification settings, formatted bold and red\nprint(\"{::bold;red}\".format(ansi_str))\n# No justification settings, formatted bold and red\nprint(\"{::bold;rgb(255, 0, 0)}\".format(ansi_str))\n# No justification settings, formatted bold and red\nprint(f\"{ansi_str::bold;red}\")\n# Format text, background, and underline with custom colors\nfg_color = 0x8A2BE2\nbg_colors = [100, 232, 170]\nul_colors = [0xFF, 0x63, 0x47]\nprint(f\"{ansi_str::rgb({fg_color});bg_rgb({bg_colors});ul_rgb({ul_colors})}\")\n```\n\n#### format_matching and unformat_matching\n\nThe methods `AnsiString.format_matching()` and `AnsiString.unformat_matching()` are provided to apply or remove formatting of an `AnsiString` based on a match specification. The methods `AnsiStr.format_matching()` and `AnsiStr.unformat_matching()` work similarly except they return a new object since `AnsiStr` is immutable.\n\nExample:\n\n```py\ns = AnsiString(\"Here is a strING that I will match formatting\", AnsiFormat.BOLD)\n# This will make the word \"formatting\" cyan with a pink background\ns.format_matching(\"[A-Za-z]+ing\", \"cyan\", AnsiFormat.BG_PINK, regex=True, match_case=True)\n# This will remove BOLD from \"strING\" and \"formatting\"\ns.unformat_matching(\"[A-Za-z]+ing\", AnsiFormat.BOLD, regex=True)\nprint(s)\n\n# This will result in the same printout using AnsiStr instead of AnsiString\ns = AnsiStr(\"Here is a strING that I will match formatting\", AnsiFormat.BOLD)\n# This will make the word \"formatting\" cyan with a pink background\ns = s.format_matching(\"[A-Za-z]+ing\", \"cyan\", AnsiFormat.BG_PINK, regex=True, match_case=True)\n# This will remove BOLD from \"strING\" and \"formatting\"\ns = s.unformat_matching(\"[A-Za-z]+ing\", AnsiFormat.BOLD, regex=True)\nprint(s)\n```\n\n#### clear_formatting\n\nCalling the method `AnsiString.clear_formatting()` will clear all formatting applied. The method `AnsiStr.clear_formatting()` works similarly except it returns a new object since `AnsiStr` is immutable.\n\n### String Assignment\n\nThe method `AnsiString.assign_str()` may be used to assign the internal string and adjust formatting as necessary. There is no associated function available in `AnsiStr`.\n\n### Base String Retrieval\n\nThe attributes `AnsiString.base_str` and `AnsiStr.base_str` may be used to retrieve the unformatted base string.\n\n### Format Status\n\nThe methods `AnsiString.ansi_settings_at()` and `AnsiString.settings_at()` may be used to retrieve the settings applied over a single character. The same methods exist in `AnsiStr`.\n\n### Other String Methods\n\nMany other methods that are found in the `str` class such as `replace()` are available in `AnsiString` and `AnsiStr` which manipulate the string while applying formatting where necessary.\n\n- capitalize\n- casefold\n- center\n- count\n- encode\n- endswith\n- expandtabs\n- find\n- index\n- isalnum\n- isalpha\n- isascii\n- isdecimal\n- isdigit\n- isidentifier\n- islower\n- isnumeric\n- isprintable\n- isspace\n- istitle\n- isupper\n- ljust\n- lower\n- lstrip\n- partition\n- removeprefix\n- removesuffix\n- replace\n- rfind\n- rindex\n- rjust\n- rpartition\n- rsplit\n- rstrip\n- split\n- splitlines\n- strip\n- swapcase\n- title\n- upper\n- zfill\n",
"bugtrack_url": null,
"license": null,
"summary": "ANSI String Formatter in Python for CLI Color and Style Formatting",
"version": "1.1.2",
"project_urls": {
"Bug Reports": "https://github.com/Tails86/ansi-string/issues",
"Documentation": "https://github.com/Tails86/ansi-string",
"Homepage": "https://github.com/Tails86/ansi-string",
"Source Code": "https://github.com/Tails86/ansi-string"
},
"split_keywords": [
"ansi",
" string"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9d2928a5b3bbe51f3625f256b6ac8bab7170cc53fde4d412e46569437229803f",
"md5": "084f7b5203f34e5ffc46443c542236df",
"sha256": "b9abf5cc29918e7a58637eaca6221e89732566f5f2ab011a4bdb09e26b15e77d"
},
"downloads": -1,
"filename": "ansi_string-1.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "084f7b5203f34e5ffc46443c542236df",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 38454,
"upload_time": "2024-11-17T19:55:47",
"upload_time_iso_8601": "2024-11-17T19:55:47.838254Z",
"url": "https://files.pythonhosted.org/packages/9d/29/28a5b3bbe51f3625f256b6ac8bab7170cc53fde4d412e46569437229803f/ansi_string-1.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "51acaeef1a1fccd0c6098f83698d26eb5847e2763263c38b113ce73e71d4a930",
"md5": "be3765eb6bd3d0e8963257e5f40eacf6",
"sha256": "712c90ec1b15c28be6da88b2b9de67611d3175e66ec253950910e8105cc35bd7"
},
"downloads": -1,
"filename": "ansi-string-1.1.2.tar.gz",
"has_sig": false,
"md5_digest": "be3765eb6bd3d0e8963257e5f40eacf6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 42930,
"upload_time": "2024-11-17T19:55:49",
"upload_time_iso_8601": "2024-11-17T19:55:49.890368Z",
"url": "https://files.pythonhosted.org/packages/51/ac/aeef1a1fccd0c6098f83698d26eb5847e2763263c38b113ce73e71d4a930/ansi-string-1.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-17 19:55:49",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Tails86",
"github_project": "ansi-string",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "ansi-string"
}