styled


Namestyled JSON
Version 0.3.1 PyPI version JSON
download
home_pagehttps://github.com/emdb-empiar/styled
SummaryStyle your terminal with ease!
upload_time2023-10-26 10:35:30
maintainer
docs_urlNone
authorPaul K Korir, PhD
requires_python
licenseApache Software License 2.0
keywords style terminal colours format
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![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"
}
        
Elapsed time: 0.13126s