[![PyPI version](https://badge.fury.io/py/styled.svg)](https://badge.fury.io/py/styled) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/styled.svg) [![Coverage Status](https://coveralls.io/repos/github/emdb-empiar/styled/badge.svg?branch=master)](https://coveralls.io/github/emdb-empiar/styled?branch=master) [![Build Status](https://travis-ci.org/emdb-empiar/styled.svg?branch=master)](https://travis-ci.org/emdb-empiar/styled)
# `styled`: Style your terminal with ease!
## Getting Started
To get it from `PyPI` use
```bash
pip install styled
```
It's best to do this in a virtual environment.
```bash
# anaconda/miniconda
conda create -n styled python
source activate styled
pip install styled
# virtualenv
virtualenv /path/to/env/styled -p /path/to/python
source /path/to/envs/styled/bin/activate
pip install styled
```
There are two ways to use `styled`:
* _interactively_ using the `styled` CLI which has three commands: `try`, `demo` and `version`; type `styled` to read the instructions;
* _programmatically_ through the `Styled` class.
## Concepts
To style a string, you need to delimit the portion to be styled with double brackets `[[ ... ]]` then make sure that the following _three (3)_ conditions hold:
* separate the text from the styles with a pipe (`|`),
* quote the text part with either a pair of single (`'...'`) or double (`"..."`) quotes, then
* separate each style with a colon (`:`)
There are _three (3)_ types of styles:
* _text styling_ such as `bold`, `blink`, `underlined` etc.
* *foreground colours*, such as `fg-red`,
* *background colours*, such as `bg-blue`.
If you want to style an extended piece of text you can use the special style marker `no-end` signaling that current style will not be interrupted for as long as possible. This can be useful if you want to style a long stretch of text e.g. a paragraph. Use the
special marker `yes-end` to terminate a `no-end` marker.
## Interactive Use
The fastest way to get started is to use the `try` command:
![Trying your hand out of a string of formatted text](try.png) _Trying out a formatted string._
You can reference the available styles using the `demo` command, which by default shows colours.
![Viewing the colour palette](colours.png) _Colour Palette_
Use `demo formats` to view formatting options.
![Viewing the formatting options](formats.png) _Formatting Options_
## Programmatic Use
To use `styled` programmatically, use the `Styled` class as follows:
```python
from styled import Styled
s = Styled("We are [[ 'bold'|bold ]] men!")
print(s)
```
You can perform string formatting _directly_ in the constructor.
```python
from styled import Styled
s = Styled("There were up to [[ '{}'|bold:fg-red ]] people who handed over themselves to the \
[[ '{police}'|fg-black:bg-red:bold ]].", 24, police='policia')
print(s)
```
```python
from styled import Styled
s = Styled("There were up to [[ '{}'|bold:fg-red:no-end ]] people who handed over themselves to the \
[[ '{police}'|fg-black:bg-red:bold ]].", 24, police='policia')
print(s)
```
The above example will have all the text until the next marker affected by the red foreground styling. You can also
manually enforce an end marker by using `yes-end` as a style. By default, all style markers will terminate on the
text to be styled. So, for example
```python
from styled import Styled
# an example of a terminating end marker
s = Styled("There were up to [[ '{}'|bold:fg-red:no-end ]] people who handed over themselves [[ ''|yes-end ]] to the \
[[ '{police}'|fg-black:bg-red:bold ]].", 24, police='policia')
print(s)
```
will suspend red foreground at the end of the word 'themselves'.
You can only have one foreground and one background colour. Ignoring this produces a `StyleError`
```python
from styled import Styled
s = Styled("There were up to [[ '{}'|bold:fg-red:fg-blue ]] people who handed over themselves to the [[ '{police}'|fg-black:bg-red:bold ]].", 24, police='policia')
```
```shell
Traceback (most recent call last):
File "/Users/pkorir/miniconda2/envs/styled/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2878, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-3-0993b680f88b>", line 1, in <module>
s = Styled("There were up to [[ '{}'|bold:fg-red:fg-blue ]] people who handed over themselves to the [[ '{police}'|fg-black:bg-red:bold ]].", 24, police='policia')
File "/Users/pkorir/PycharmProjects/styled/styled/styled.py", line 55, in __init__
self._validate(self._tokens)
File "/Users/pkorir/PycharmProjects/styled/styled/styled.py", line 156, in _validate
raise StyleError("Multiple foreground styles for text '{}': {}".format(text, ', '.join(styles)))
StyleError: Multiple foreground styles for text '24': bold, fg-red, fg-blue
```
Inputting an invalid `style` also raises a `StyleError`
```python
from styled import Styled
s = Styled("This just can't just [[ 'go'|underline ]] on forever! ")
```
```shell
Traceback (most recent call last):
File "/Users/pkorir/miniconda2/envs/styled/lib/python2.7/site-packages/IPython/core/interactiveshell.py", line 2878, in run_code
exec(code_obj, self.user_global_ns, self.user_ns)
File "<ipython-input-4-528d6d2ac4f4>", line 1, in <module>
s = Styled("This just can't just [[ 'go'|underline ]] on forever! ")
File "/Users/pkorir/PycharmProjects/styled/styled/styled.py", line 59, in __init__
self._styled = self._transform(self._plain, self._cleaned_tokens)
File "/Users/pkorir/PycharmProjects/styled/styled/styled.py", line 99, in _transform
styled += plain[i:start] + self.transform(token)
File "/Users/pkorir/PycharmProjects/styled/styled/styled.py", line 87, in transform
raise StyleError("Unknown style '{}'".format(style_))
StyleError: Unknown style 'underline'
```
(In case you're wondering, it should have been `underlined` not `underline`.)
## Concatenation
Concatenating a normal string and a `Styled` string produces a `Styled` string, which is a subclass of string.
Internally, though, everything is a Unicode string.
```shell
from styled import Styled
s = Styled("This just can't just [[ 'go'|underlined ]] on forever! ")
u = "She shouted back!"
print(type(s + u))
# <class 'styled.styled.Styled'>
print(type(u + s))
# <class 'styled.styled.Styled'>
s += "Gloria!"
print(type(s))
# <class 'styled.styled.Styled'>
```
## Validation
The process of generating the output involves some validation - to check that styles are sane. At present,
only multiple fore- and background colours are checked. This will be expanded as needed.
## Cleaning Styles
In addition to validation, styles are cleaned. Cleaning ensures that the final set of styles is non-redundant.
```python
from styled import Styled
s = Styled("It takes enormous [[ 'courage'|bold:bold:bold ]] to admit that you're wrong.")
print(s._tokens)
# [(19, 49, 'courage', ['bold', 'bold', 'bold'])]
print(s._cleaned_tokens)
# [(19, 49, 'courage', ['bold'])]
```
## Backstory
Welcome to `styled`, a simple Python package that makes a breeze of writing beautiful text to the terminal.
The main innovation behind `styled` is the dead-simple user interface which does away with the user's need to know
anything other than the style names. Behind the scenes `styled` handles everything to keep
your styles consistent and redundant and informing you when you have made formatting errors.
`styled` was borne out of the frustration encountered in using other packages which muddle the boundary between
_user-space_ and _design-space_. The user should be free to be a _user_, and it is the _designer's_ job to hide the
implementation behind a simple user interface that facilitates the user's task. This is what I've tried to do. If I have
failed to live up to this please let me know. I'm sure together we can come up with something better.
## Aspirations?
When I grow up I want to have my own Python string declaration like so:
```shell
# hey! I'm a styled string
s = s"You have to [[ 'believe'|fg-red ]] it to [[ 'see'|fg-green ]] it!"
```
## Special Thanks
To the following people
* **Dimitris Zlatanidis** (for the inspiration and resources in his package `colored` available at <https://gitlab.com/dslackw/colored>)
* **Cesare Catavitello** (for being the _first_ user)
Raw data
{
"_id": null,
"home_page": "https://github.com/emdb-empiar/styled",
"name": "styled",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "style,terminal,colours,format",
"author": "Paul K Korir, PhD",
"author_email": "pkorir@ebi.ac.uk",
"download_url": "https://files.pythonhosted.org/packages/b8/90/7bcb48d254824945d34e8cd79c5062abcdb2e56e401cf2d6f75311e3ce0a/styled-0.3.1.tar.gz",
"platform": null,
"description": "[![PyPI version](https://badge.fury.io/py/styled.svg)](https://badge.fury.io/py/styled) ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/styled.svg) [![Coverage Status](https://coveralls.io/repos/github/emdb-empiar/styled/badge.svg?branch=master)](https://coveralls.io/github/emdb-empiar/styled?branch=master) [![Build Status](https://travis-ci.org/emdb-empiar/styled.svg?branch=master)](https://travis-ci.org/emdb-empiar/styled)\n\n# `styled`: Style your terminal with ease!\n\n## Getting Started\n\nTo get it from `PyPI` use\n\n```bash\npip install styled\n```\n\nIt's best to do this in a virtual environment.\n\n```bash\n# anaconda/miniconda\nconda create -n styled python\nsource activate styled\npip install styled\n\n# virtualenv\nvirtualenv /path/to/env/styled -p /path/to/python\nsource /path/to/envs/styled/bin/activate\npip install styled\n\n```\n\nThere are two ways to use `styled`:\n* _interactively_ using the `styled` CLI which has three commands: `try`, `demo` and `version`; type `styled` to read the instructions;\n* _programmatically_ through the `Styled` class. \n\n## Concepts\nTo style a string, you need to delimit the portion to be styled with double brackets `[[ ... ]]` then make sure that the following _three (3)_ conditions hold:\n\n* separate the text from the styles with a pipe (`|`),\n* quote the text part with either a pair of single (`'...'`) or double (`\"...\"`) quotes, then \n* separate each style with a colon (`:`)\n\nThere are _three (3)_ types of styles:\n\n* _text styling_ such as `bold`, `blink`, `underlined` etc.\n* *foreground colours*, such as `fg-red`,\n* *background colours*, such as `bg-blue`.\n\nIf you want to style an extended piece of text you can use the special style marker `no-end` signaling that current style will not be interrupted for as long as possible. This can be useful if you want to style a long stretch of text e.g. a paragraph. Use the \nspecial marker `yes-end` to terminate a `no-end` marker.\n\n## Interactive Use\nThe fastest way to get started is to use the `try` command:\n\n![Trying your hand out of a string of formatted text](try.png) _Trying out a formatted string._\n\nYou can reference the available styles using the `demo` command, which by default shows colours.\n\n![Viewing the colour palette](colours.png) _Colour Palette_\n\nUse `demo formats` to view formatting options.\n\n![Viewing the formatting options](formats.png) _Formatting Options_\n\n## Programmatic Use\n\nTo use `styled` programmatically, use the `Styled` class as follows:\n\n```python\nfrom styled import Styled\ns = Styled(\"We are [[ 'bold'|bold ]] men!\")\nprint(s)\n```\n\nYou can perform string formatting _directly_ in the constructor.\n\n```python\nfrom styled import Styled\ns = Styled(\"There were up to [[ '{}'|bold:fg-red ]] people who handed over themselves to the \\\n[[ '{police}'|fg-black:bg-red:bold ]].\", 24, police='policia')\nprint(s)\n```\n\n```python\nfrom styled import Styled\ns = Styled(\"There were up to [[ '{}'|bold:fg-red:no-end ]] people who handed over themselves to the \\\n[[ '{police}'|fg-black:bg-red:bold ]].\", 24, police='policia')\nprint(s)\n``` \n\nThe above example will have all the text until the next marker affected by the red foreground styling. You can also \nmanually enforce an end marker by using `yes-end` as a style. By default, all style markers will terminate on the \ntext to be styled. So, for example\n\n```python\nfrom styled import Styled\n# an example of a terminating end marker\ns = Styled(\"There were up to [[ '{}'|bold:fg-red:no-end ]] people who handed over themselves [[ ''|yes-end ]] to the \\\n[[ '{police}'|fg-black:bg-red:bold ]].\", 24, police='policia')\nprint(s)\n``` \n\nwill suspend red foreground at the end of the word 'themselves'.\n\nYou can only have one foreground and one background colour. Ignoring this produces a `StyleError`\n\n```python\nfrom styled import Styled\ns = Styled(\"There were up to [[ '{}'|bold:fg-red:fg-blue ]] people who handed over themselves to the [[ '{police}'|fg-black:bg-red:bold ]].\", 24, police='policia')\n```\n\n```shell\nTraceback (most recent call last):\n File \"/Users/pkorir/miniconda2/envs/styled/lib/python2.7/site-packages/IPython/core/interactiveshell.py\", line 2878, in run_code\n exec(code_obj, self.user_global_ns, self.user_ns)\n File \"<ipython-input-3-0993b680f88b>\", line 1, in <module>\n s = Styled(\"There were up to [[ '{}'|bold:fg-red:fg-blue ]] people who handed over themselves to the [[ '{police}'|fg-black:bg-red:bold ]].\", 24, police='policia')\n File \"/Users/pkorir/PycharmProjects/styled/styled/styled.py\", line 55, in __init__\n self._validate(self._tokens)\n File \"/Users/pkorir/PycharmProjects/styled/styled/styled.py\", line 156, in _validate\n raise StyleError(\"Multiple foreground styles for text '{}': {}\".format(text, ', '.join(styles)))\nStyleError: Multiple foreground styles for text '24': bold, fg-red, fg-blue\n```\n\nInputting an invalid `style` also raises a `StyleError`\n\n```python\nfrom styled import Styled\ns = Styled(\"This just can't just [[ 'go'|underline ]] on forever! \")\n```\n\n```shell\nTraceback (most recent call last):\n File \"/Users/pkorir/miniconda2/envs/styled/lib/python2.7/site-packages/IPython/core/interactiveshell.py\", line 2878, in run_code\n exec(code_obj, self.user_global_ns, self.user_ns)\n File \"<ipython-input-4-528d6d2ac4f4>\", line 1, in <module>\n s = Styled(\"This just can't just [[ 'go'|underline ]] on forever! \")\n File \"/Users/pkorir/PycharmProjects/styled/styled/styled.py\", line 59, in __init__\n self._styled = self._transform(self._plain, self._cleaned_tokens)\n File \"/Users/pkorir/PycharmProjects/styled/styled/styled.py\", line 99, in _transform\n styled += plain[i:start] + self.transform(token)\n File \"/Users/pkorir/PycharmProjects/styled/styled/styled.py\", line 87, in transform\n raise StyleError(\"Unknown style '{}'\".format(style_))\nStyleError: Unknown style 'underline'\n```\n\n(In case you're wondering, it should have been `underlined` not `underline`.)\n\n\n## Concatenation\n\nConcatenating a normal string and a `Styled` string produces a `Styled` string, which is a subclass of string. \nInternally, though, everything is a Unicode string.\n\n```shell\nfrom styled import Styled\ns = Styled(\"This just can't just [[ 'go'|underlined ]] on forever! \")\nu = \"She shouted back!\"\nprint(type(s + u))\n# <class 'styled.styled.Styled'>\nprint(type(u + s))\n# <class 'styled.styled.Styled'>\ns += \"Gloria!\"\nprint(type(s))\n# <class 'styled.styled.Styled'>\n```\n\n## Validation\n\nThe process of generating the output involves some validation - to check that styles are sane. At present,\nonly multiple fore- and background colours are checked. This will be expanded as needed.\n\n## Cleaning Styles\n\nIn addition to validation, styles are cleaned. Cleaning ensures that the final set of styles is non-redundant.\n\n```python\nfrom styled import Styled\ns = Styled(\"It takes enormous [[ 'courage'|bold:bold:bold ]] to admit that you're wrong.\")\nprint(s._tokens)\n# [(19, 49, 'courage', ['bold', 'bold', 'bold'])]\nprint(s._cleaned_tokens)\n# [(19, 49, 'courage', ['bold'])]\n```\n\n## Backstory\nWelcome to `styled`, a simple Python package that makes a breeze of writing beautiful text to the terminal. \nThe main innovation behind `styled` is the dead-simple user interface which does away with the user's need to know \nanything other than the style names. Behind the scenes `styled` handles everything to keep \nyour styles consistent and redundant and informing you when you have made formatting errors.\n\n`styled` was borne out of the frustration encountered in using other packages which muddle the boundary between\n_user-space_ and _design-space_. The user should be free to be a _user_, and it is the _designer's_ job to hide the \nimplementation behind a simple user interface that facilitates the user's task. This is what I've tried to do. If I have \nfailed to live up to this please let me know. I'm sure together we can come up with something better.\n\n## Aspirations?\n\nWhen I grow up I want to have my own Python string declaration like so:\n\n```shell\n# hey! I'm a styled string\ns = s\"You have to [[ 'believe'|fg-red ]] it to [[ 'see'|fg-green ]] it!\"\n```\n\n## Special Thanks\n\nTo the following people\n\n* **Dimitris Zlatanidis** (for the inspiration and resources in his package `colored` available at <https://gitlab.com/dslackw/colored>)\n* **Cesare Catavitello** (for being the _first_ user)\n\n",
"bugtrack_url": null,
"license": "Apache Software License 2.0",
"summary": "Style your terminal with ease!",
"version": "0.3.1",
"project_urls": {
"Homepage": "https://github.com/emdb-empiar/styled"
},
"split_keywords": [
"style",
"terminal",
"colours",
"format"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c76ee44591992690213d2d94b4210d8633a28c9ad4ba2e8ec427f22cca8a413c",
"md5": "2def9367975cee0094db65bc9cfccb44",
"sha256": "e2f993568985eb78232543b37799aee5c4c89a26f5305b47e0964d5e0df21594"
},
"downloads": -1,
"filename": "styled-0.3.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "2def9367975cee0094db65bc9cfccb44",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 15780,
"upload_time": "2023-10-26T10:35:27",
"upload_time_iso_8601": "2023-10-26T10:35:27.785437Z",
"url": "https://files.pythonhosted.org/packages/c7/6e/e44591992690213d2d94b4210d8633a28c9ad4ba2e8ec427f22cca8a413c/styled-0.3.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b8907bcb48d254824945d34e8cd79c5062abcdb2e56e401cf2d6f75311e3ce0a",
"md5": "afaf20bbd3ea3b2378383dc7d25a933d",
"sha256": "9d161d911126d7c8be738a142753b35a4e68bcf66a4083fd3b3243ee33eb2822"
},
"downloads": -1,
"filename": "styled-0.3.1.tar.gz",
"has_sig": false,
"md5_digest": "afaf20bbd3ea3b2378383dc7d25a933d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 1019883,
"upload_time": "2023-10-26T10:35:30",
"upload_time_iso_8601": "2023-10-26T10:35:30.376427Z",
"url": "https://files.pythonhosted.org/packages/b8/90/7bcb48d254824945d34e8cd79c5062abcdb2e56e401cf2d6f75311e3ce0a/styled-0.3.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-26 10:35:30",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "emdb-empiar",
"github_project": "styled",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "styled"
}