Package: autopalette
autopalette===========Terminal palettes and themes, without tears.::pip install autopalette**Status: Alpha; being developed.**Do you write python scripts that ``print()`` text on the command-lineterminal? Do you feel the interface could convey a bit more meaning, butthe effort needed to get it right has kept you away from using ANSIcolors? These things should be easy, right?Here’s a regular Python program that prints a word:.. code:: pythonprint("Tring!").. figure:: https://user-images.githubusercontent.com/23116/40859649-0da89ab0-65d2-11e8-8026-19ba6a2ad003.png:alt: 01-regular-print01-regular-printHere is what it looks like with autopalette, using a shortcut called``AutoFormat`` or in short: ``af``... code:: pythonfrom autopalette import afprint(af("Tring!")).. figure:: https://user-images.githubusercontent.com/23116/40859706-3b61f3c0-65d2-11e8-996b-da4e218e192c.png:alt: 02-autoformat-wrapped-print02-autoformat-wrapped-printWe added one line to import, and four characters around the string.And it does nothing - autopalette is non-intrusive that way. You canleave your ``af``-wrapped strings around and they will not rununnecessary code until you ask for more.What’s more?.. code:: pythonfrom autopalette import afprint(af("Hello, world!").id)print(af("Hello, world!").id256).. figure:: https://user-images.githubusercontent.com/23116/40859765-63bec9b0-65d2-11e8-886c-82011ea96f8b.png:alt: 03-id-deterministic-color03-id-deterministic-colorIf your terminal / emulator reports that it supports color, you shouldsee the second line formatted in fuschia/ magenta. Try changing the textand observe that the color changes when the text changes, but it staysfixed for the same text. Across function calls, across program runs,across machines, across time itself! Okay maybe that was too dramatic,but it is kind of true because, mathematics.Autopalette’s ``id`` feature hashes the supplied text and generates acolor unique to the text within the range of colors reported by theterminal. ``id256`` generates a color within the ANSI 256 palette.``id256`` is not portable, but feel free to use it for your personalscripts where color limits are known.Why is this useful?It helps to identify unique names that your program may output, such as:-  hostnames, when working with remote machines.-  usernames, for logs of multi-user environments.-  you know better what matters to your program’s output :)Sometimes you want a little more….. code:: pythonfrom autopalette import afprint(af("Hello again!").h1).. figure:: https://user-images.githubusercontent.com/23116/40859801-858c3ef6-65d2-11e8-90d7-69a80fc57c57.png:alt: 04-header-one04-header-oneAnd we have a nicely decorated header, just like that. You can use oneof the several pre-defined styles, or read further below how you candesign your own.Here are the various styles built into autopalette.-  ``p``: plain-text, or paragraph - as you like to read it.-  ``light``: where color range allows it, lighter text.-  ``dark``: darker text if terminal supports enough colors withinpalette.-  ``h1``: highlighted text style 1, or header-1.-  ``h2``:-  ``h3``-  ``h4``-  ``li``: list element.-  ``err``: an error-  ``warn``: a warning-  ``info``: a warning-  ``ok``: a warning-  ``b``: bold.-  ``i``: italic.-  ``u``: underline.-  ``r``: reversed colors.-  ``raw``: useful to debug, displays the ANSI code instead of applyingit.Let us try superimposing two styles... code:: pythonfrom autopalette import afprint(af("Hey! We've met before!?").info.b).. figure:: https://user-images.githubusercontent.com/23116/40859850-abe90afc-65d2-11e8-905d-d8a875d0f021.png:alt: 05-superimpose-styles05-superimpose-stylesYou get the idea, tack the names of styles you want at the end-bracketof the call to ``af``.If you are wondering, “Wait, what’s with that weird syntax?”, inPython’s spirit of quick protoyping, autopalette encouragesexperimenting with minimal mental and physical effort to tweak knobs.Your program’s actual task matters more, but you care enough about yourfuture self and users using the app to style it well and be a delight touse. Autopalette’s syntax is an expriment to help manage this dilemma.While you compose and read your code, this syntax separates the stylingfrom rest of the function calls. You don’t have to think about stylingunless you want to, and when you do, which is often as you look at thestring you just put together to print - assuming you started with``af("``, close the quote and bracket, type out a style shortcut and youare done.Although, few times you want a bit more than that….. code:: pythonfrom autopalette import af, GameBoyGreenPaletteaf.init(palette=GameBoyGreenPalette)print(af("There you are!").h1).. figure:: https://user-images.githubusercontent.com/23116/40860027-550d2046-65d3-11e8-9fbe-b0ecdf3ec50c.png:alt: 06-select-palette06-select-paletteLook at that! Yummy.Autopalette goes the length to support a handful of palettes.-  GameBoyChocolate-  GameBoyOriginal-  Grayscale-  Oil-  Arcade-  CLRSIf this is exciting to you too, read further below how to create yourown!How does this look on a terminal with only 16 colors?.. figure:: https://user-images.githubusercontent.com/23116/40860055-74e898aa-65d3-11e8-8bfc-3873c1ea4a4b.png:alt: 06-select-palette-16-color06-select-palette-16-colorNot too shabby, eh?How do you test how your app will look on terminals with limited colors?Try these as prefix to your script invocation for a temporary change:-  ``env TERM=vt100``-  ``env TERM=rxvt``-  ``env TERM=xterm``-  ``env TERM=xterm-256color``-  ``env COLORTERM=truecolor``-  ``env NO_COLOR``like so:``$ env TERM=xterm-256color python app.py``To save a setting permanently, put ``export TERM=...`` in your``~/.bash_profile`` or your default shell’s configuration.If the environment variable NO_COLOR is set, autopalette honors theconfiguration and disables all color. Same with redirected output andpipes - autopalette will handle it fully automatically, if it fails todo so, please open an issue in the tracker and I’ll do my best to fixit. In case you can fix the issue yourself, a pull request will beawesome!And we would be essentially done, except, there’s this little voice inthe head that’s saying something mojibªke something, but it’s allgarbled up... code:: pythonfrom autopalette import afaf.init(fix_text=True)print(af("&macr;\\_(ã\x83\x84)_/&macr;").info).. figure:: https://user-images.githubusercontent.com/23116/40860106-abf343f4-65d3-11e8-9272-89733b0790bd.png:alt: 07-fix-text07-fix-textNeat, with the ``fix_text`` option set, autopalette transparently passesyour text through ``ftfy``\ ’s ``fix_text()`` function call, ensuringyour application does not output garbage when badly encoded strings findtheir way to your app’s print statement.There’s more, not all terminal and emulators support unicode, and willstill produce garbage if we feed them strings that they do not know howto display. Use the ``fix_all`` option to let autopalette and theterminal it is running on figure out the rest... code:: pythonfrom autopalette import afaf.init(fix_all=True)print(af("I 💛 Unicode!"))Try this example with ``env TERM=vt100`` for the full cleanup!.. figure:: https://user-images.githubusercontent.com/23116/40860125-c4f0343e-65d3-11e8-9bfe-d92f177c5852.png:alt: 08-fix-all08-fix-allNote that fixing text and emoji requires additional libraries to beloaded and can slow down startup time. If your program does not outputstrings generated by other programs, (which includes strings receivedfrom http APIs!) and the program is invoked repeatedly instead ofrunning for a while, you may want to skip ``fix_...`` options.And that’s about it for three-line examples!You can start your scripts with ``af.init(fix_all=True)`` and use``af()`` to wrap your strings, even if you ignore colors and styles,your program will display text correctly on most popular (and manyobscure) terminals.Here’s the basic theme:.. figure:: https://user-images.githubusercontent.com/23116/40860445-e69d057a-65d4-11e8-9926-228beaf3c429.png:alt: 09-basic-palette09-basic-paletteBut there’s more!Your users have the ability to define their own themes, and autopalettewill automatically\* recolor your application to their preferences orneeds. (*mostly automatically, or with a little help.).. code:: text# ~/.autopalettepalette = Dutronrender = Truecolor.. figure:: https://user-images.githubusercontent.com/23116/40860487-0589dd50-65d5-11e8-9360-2fb29a2d213e.png:alt: 10-restricted-color-palette10-restricted-color-paletteYour terminal applications look beautiful as you intend, to everyone, asthey expect.It is almost two decades since Y2K! And with over 50 years of theterminal technology behind us, this should be a thing we expect as anorm.Autopalette is another attempt at fixing some of these gaps by making itnear trivial to style terminal apps and do the right thing for thevarious terminals it runs on… without the complexity often involved as aresult of the rich legacy of the technology.Autopalette would not dare exist without the libraries published bythese generous individuals who made it possible to think and write codein simple mental models that are just right for the task:-  ``colorhash``: Felix Krull (https://pypi.org/project/colorhash/)-  ``colortrans.py``: Micah Elliott(https://gist.github.com/MicahElliott/719710/)-  ``colour``: Valentin LAB (https://pypi.org/project/colour/)-  ``emoji2text``: Sam CB (https://pypi.org/project/emoji2text/)-  ``ftfy``: Rob Speer / Luminoso (https://pypi.org/project/ftfy/)-  ``kdtree``: Stefan Kögl (https://pypi.org/project/kdtree/)-  ``sty``: Felix Meyer-Wolters (https://pypi.org/project/sty/)