diff --git a/.gitignore b/.gitignore index c2a9c3f..9839280 100644 --- a/.gitignore +++ b/.gitignore @@ -1,162 +1,4 @@ -## Python gitignore -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python +*.pyc build/ -develop-eggs/ dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ - -## Jetbrains -# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm -# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 - -# User-specific stuff -.idea/**/workspace.xml -.idea/**/tasks.xml -.idea/**/usage.statistics.xml -.idea/**/dictionaries -.idea/**/shelf - -# Sensitive or high-churn files -.idea/**/dataSources/ -.idea/**/dataSources.ids -.idea/**/dataSources.local.xml -.idea/**/sqlDataSources.xml -.idea/**/dynamic.xml -.idea/**/uiDesigner.xml -.idea/**/dbnavigator.xml - -# Gradle -.idea/**/gradle.xml -.idea/**/libraries - -# Mongo Explorer plugin -.idea/**/mongoSettings.xml - -# Editor-based Rest Client -.idea/httpRequests - -# SonarLint -.idea/sonarlint - -# CMake -cmake-build-*/ - -# File-based project format -*.iws - -# IntelliJ -out/ - -# mpeltonen/sbt-idea plugin -.idea_modules/ - -# JIRA plugin -atlassian-ide-plugin.xml - -# Cursive Clojure plugin -.idea/replstate.xml - -# Crashlytics plugin (for Android Studio and IntelliJ) -com_crashlytics_export_strings.xml -crashlytics.properties -crashlytics-build.properties -fabric.properties +colout.egg-info/ diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b7997b5..0000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: python -python: - - "3.5" - - "3.6" - - "3.7" - - "3.8" - - "pypy3" -install: - - pip install . -script: - - colout --help - - echo heyoo | colout hey yellow diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 1aba38f..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include LICENSE diff --git a/README.md b/README.md index 10bde37..c6993aa 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,16 @@ -colout — Color Up Arbitrary Command Output -========================================== +colout(1) -- Color Up Arbitrary Command Output +============================================== -

-Colout logo -

+## SYNOPSIS -## Synopsis +`colout` [-h] [-r] -`colout [-h] [-r [RESOURCE]]` +`colout` [-g] [-c] [-l] [-a] [-t] [-T] [-P] [-s] PATTERN [COLOR(S) [STYLE(S)]] -`colout [-g] [-c] [-l min,max] [-a] [-t] [-T DIR] [-P DIR] [-d COLORMAP] [-s] [-e CHAR] [-E CHAR] [--debug] PATTERN [COLOR(S) [STYLE(S)]]` - -## Description +## DESCRIPTION `colout` read lines of text stream on the standard input and output characters -matching a given regular expression *PATTERN* in given *COLOR* and *STYLE*. +matching a given regular expression *PATTERN* in given and *STYLE*. If groups are specified in the regular expression pattern, only them are taken into account, else the whole matching pattern is colored. @@ -29,43 +21,31 @@ If you ask for fewer colors, the last one will be duplicated across remaining groups. Available colors are: blue, black, yellow, cyan, green, magenta, white, red, -rainbow, random, Random, Spectrum, spectrum, scale, Scale, hash, Hash, none, an -RGB hexadecimal triplet (`#11aaff`, for example) or any number between 0 and 255. +rainbow, random, Random, scale, none, an RGB hexadecimal triplet or any number +between 0 and 255. Available styles are: normal, bold, faint, italic, underline, blink, rapid_blink, reverse, conceal or random (some styles may have no effect, depending on your terminal). -In some case, you can indicate a foreground and a background color, by indicating both colors -separated by a period (for example: `red.blue`). You can also use this system to combine two styles -(for example, for a bold style that also blinks: `bold.blink`). +`rainbow` will cycle over a 8 colors rainbow at each matching pattern. +`Rainbow` will do the same over 24 colors (this requires a terminal that supports +the 256 color escape sequences). -`rainbow` will cycle over a the default colormap at each matching pattern. -`Rainbow` will do the same over the default colormap for the 256-colors mode -(this requires a terminal that supports the 256 color escape sequences). +`Random` will color each matching pattern with a random color among the 255 +available in the ANSI table. `random` will do the same in 8 colors mode. -`Random` will color each matching pattern with a random color among the default colormap -(the 255 available in the ANSI table, by default). -`random` will do the same in 8 colors mode. - -`spectrum` and `Spectrum` are like rainbows, but with more colors (8 and 36 -colors). - -`scale` (8 colors) and `Scale` (256 colors) will parse the numbers characters in -the matching text as a decimal number and apply the default colormap according +`scale` (8 colors) and `Scale` (36 colors) will parse the numbers characters in +the matching text as a decimal number and apply the rainbow colormap according to its position on the scale defined by the `-l` option (see below, "0,100" by default). -`hash` (8 colors) and `Hash` (256 colors) will take a fingerprint of the matching -text and apply the default colormap according to it. This ensure that matching -texts appearing several times will always get the same color. - Before interpreting the matched string as a number, colout will remove any character not supposed to be used to write down numbers. This permits to apply this special color on a large group, while interpreting only its numerical part. -You can use the name of a syntax-coloring ["lexer"](http://pygments.org/docs/lexers/) -as a color (for example: "Cpp", "ruby", "xml+django", etc.). +If the python-pygments library is installed, you can use the name of a +syntax-coloring "lexer" as a color (for example: "Cpp", "ruby", "xml+django", etc.). If GIMP palettes files (*.gpl) are available, you can also use their names as a colormap (see the `-P` switch below). @@ -78,7 +58,8 @@ When not specified, a *COLOR* defaults to _red_ and a *STYLE* defaults to _bold_ `colout` comes with some predefined themes to rapidly color well-known outputs (see the `-t` switch below). -`colout` can be used as an interface to pygments (see also the `--source` switch below). +If the python-pygments library is available, `colout` can be used as an interface +to it (see also the `-s` switch below). To have a list of all colors, styles, special colormaps, themes, palettes and lexers, use the `-r` switch (see below). @@ -86,29 +67,37 @@ use the `-r` switch (see below). `colout` is released under the GNU Public License v3. -## Installation +## INSTALLATION -The recomended method is using pip to install the package for the local user: + sudo python3 setup.py install -```console -$ pip install --user colout -``` +and then soft link `/usr/local/bin/colout` to your colout.py under your installation +directory, which is usually something like -Another method is using [pipsi](https://github.com/mitsuhiko/pipsi) -(_pipsi is no longer maintained, _) -```console -$ pipsi install colout -``` + /usr/local/lib/python3/dist-packages/colout-0.1-py3.egg/colout/colout.py -There is also a PPA for Ubuntu 16.04 (Xenial)/18.04 (Bionic) (@`0.6.1-3~dist7`, not actively maintained) -```console -$ sudo add-apt-repository ppa:csaba-kertesz/random -$ sudo apt-get update -$ sudo apt-get/aptitude install colout -``` +## OTHER INSTALLATION METHOD -## Options +Pypi (the Python Package Index) + + sudo pip install colout + +or + + sudo easy_install colout + +Ubuntu 13.04's ppa + + sudo add-apt-repository ppa:ciici123/colout + sudo apt-get update + sudo apt-get/aptitude install colout + +Gentoo + + sudo emerge colout + +## OPTIONS * `-h`, `--help`: Show a help message and exit @@ -120,9 +109,8 @@ $ sudo apt-get/aptitude install colout Use the given list of comma-separated colors as a colormap (cycle the colors at each match). * `-l min,max`, `--scale min,max`: - When using the 'scale' colormap, parse matches as decimal numbers (taking your locale into - account) or as arithmetic expression (like "1+2/0.9*3") and apply the rainbow colormap linearly - between the given min,max (0,100, by default). + When using the 'scale' colormap, parse matches as decimal numbers (taking your locale into account) + and apply the rainbow colormap linearly between the given min,max (0,100, by default). * `-a`, `--all`: Color the whole input at once instead of line per line @@ -137,35 +125,21 @@ $ sudo apt-get/aptitude install colout * `-P DIR`, `--palettes-dir DIR`: Search for additional palettes (*.gpl files) in this directory. -* `-d COLORMAP`, `--default COLORMAP`: - When using special colormaps (`random`, `scale` or `hash`), use this COLORMAP instead of the default one. - This can be either one of the available colormaps or a comma-separated list of colors. - WARNING: be sure to specify a default colormap that is compatible with the special colormap's mode, - or else the colors may not appear the same. - Also, external palettes are converted from RGB to 256-ANSI and will thus not work if you use - them as default colormaps for a 8-colors mode special color. - -* `-r [TYPE(S)]`, `--resources [TYPE(S)]`: - Print the names of available resources. Use a comma-separated list of resources names - (styles, colors, special, themes, palettes, colormaps or lexers), - use 'all' (or no argument) to print all resources. +* `-r`, `--resources`: + Print the names of all available colors, styles, themes and palettes. + A bug currently made it mandatory to use an additional dummy argument to this option + to make it work correctly, use `-r x`. * `-s`, `--source`: Interpret PATTERN as source code readable by the Pygments library. If the first letter of PATTERN is upper case, use the 256 color mode, if it is lower case, use the 8 colors mode. In 256 color mode, interpret COLOR as a Pygments style (e.g. "default"). -* `-e CHAR`, `--sep-list CHAR`: - Use this character as a separator for list of colors/resources/numbers (instead of comma). - -* `-E CHAR`, `--sep-pair CHAR`: - Use this character as a separator for foreground/background pairs (instead of period). - * `--debug`: Debug mode: print what's going on internally, if you want to check what features are available. -## Regular expressions +## REGULAR EXPRESSIONS A regular expression (or _regex_) is a pattern that describes a set of strings that matches it. @@ -175,25 +149,21 @@ that matches it. special characters that would be recognize by your shell. -## Dependencies +## DEPENDENCIES -Necessary Python modules: +Recommended packages: +* `argparse` for a usable arguments parsing * `pygments` for the source code syntax coloring * `babel` for a locale-aware number parsing -## Limitations +## LIMITATIONS -Don't use nested groups or colout will duplicate the corresponding input text -with each matching colors. +Don't use nested groups or colout will duplicate the corresponding input text with each matching colors. -Using a default colormap that is incompatible with the special colormap's mode -(i.e. number of colors) will end badly. -Color pairs (`foreground.background`) work in 8-colors mode for simple coloring, but may fail with `--colormap`. - -## Examples +## EXAMPLES ### Simple @@ -203,7 +173,7 @@ Color pairs (`foreground.background`) work in 8-colors mode for simple coloring, * Color in bold violet home directories in _/etc/passwd_: `colout '/home/[a-z]+' 135 < /etc/passwd` -* Color in yellow user/groups id, in bold green name and in bold red home directories in `/etc/passwd`: +* Color in yellow user/groups id, in bold green name and in bold red home directories in _/etc/passwd_: `colout ':x:([0-9]+:[0-9]+):([^:]+).*(/home/[a-z]+)' yellow,green,red normal,bold < /etc/passwd` * Color in yellow file permissions with read rights for everyone: @@ -236,7 +206,7 @@ Color pairs (`foreground.background`) work in 8-colors mode for simple coloring, * Color a make output, line numbers in yellow, errors in bold red, warning in magenta, pragma in green and C++ file base names in cyan: `make 2>&1 | colout ':([0-9]+):[0-9]*' yellow normal | colout error | colout warning magenta | colout pragma green normal | colout '/(\w+)*\.(h|cpp)' cyan normal` Or using themes: - `make 2>&1 | colout -t cmake | colout -t g++` + `make 2>&³ | colout -t cmake | colout -t g++` * Color each word in the head of auth.log with a rainbow color map, starting a new colormap at each new line (the beginning of the command is just bash magic to repeat the string "(\\w+)\\W+": @@ -258,140 +228,18 @@ Color pairs (`foreground.background`) work in 8-colors mode for simple coloring, related to the value of the progress (from 0%=blue to 100%=red): `cmake .. && make | colout "^(\[\s*[0-9]+%\])" Scale` -* Color hosts and users in `auth.log`, with consistent colors: - `cat /var/log/auth.log | colout "^(\S+\s+){3}(\S+)\s(\S+\s+){3}(\S+)\s+(\S+\s+){2}(\S+)\s*" none,hash,none,hash,none,hash` - ### Bash alias The following bash function color the output of any command with the -cmake and g++ themes: +cmake and g77 themes: -```bash -function cm() -{ - set -o pipefail - $@ 2>&1 | colout -t cmake | colout -t g++ -} -``` + function cm() + { + set -o pipefail + $@ 2>&1 | colout -t cmake | colout -t g++ + } You then can use the `cm` alias as a prefix to your build command, for example: `cm make test` - -### GDB integration - -You can use `colout` within the GNU debuger (`gbd`) to color its output. -For example, the following script `.gdbinit` configuration will color -the output of the backtrace command: - -```gdb -set confirm off - -# Don't wrap line or the coloring regexp won't work. -set width 0 - -# Create a named pipe to get outputs from gdb -shell test -e /tmp/coloutPipe && rm /tmp/coloutPipe -shell mkfifo /tmp/coloutPipe - -define logging_on - # Instead of printing on stdout only, log everything... - set logging redirect on - # ... in our named pipe. - set logging on /tmp/coloutPipe -end - -define logging_off - set logging off - set logging redirect off - # Because both gdb and our commands are writing on the same pipe at the same - # time, it is more than probable that gdb will end before our (higher level) - # commands. The gdb prompt will thus render before the result of the command, - # which is highly akward. To prevent this, we need to wait before displaying - # the prompt again. The more your commands are complex, the higher you will - # need to set this. - shell sleep 0.4s -end - -define hook-backtrace - # Note: match path = [path]file[.ext] = (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)) - # This line color highlights: - # – lines that link to source code, - # – function call in green, - # – arguments names in yellow, values in magenta, - # — the parent directory in bold red (assuming that the debug session would be in a "project/build/" directory). - shell cat /tmp/coloutPipe | colout "^(#)([0-9]+)\s+(0x\S+ )*(in )*(.*) (\(.*\)) (at) (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,red,green,magenta,red,none,white,white,yellow normal,bold,normal,normal,normal,normal,normal,bold,bold,bold | colout "([\w\s]*?)(=)([^,]*?)([,\)])" yellow,blue,magenta,blue normal | colout "/($(basename $(dirname $(pwd))))/" red bold & - logging_on -end -define hookpost-backtrace - logging_off -end - -# Don't forget to clean the adhoc pipe. -define hook-quit - set confirm off - shell rm -f /tmp/coloutPipe -end -``` - -Take a look at the `example.gdbinit` file distributed with colout for more gdb commands. - - - -### Themes - -You can easily add your own theme to colout. -A theme is basically a module with a function named `theme` that take the configuration context as -an argument and return back the (modified) context and a list of triplets. -Each triplet figures the same arguments than those of the command line interface. - -```python -def theme(context): - return context,[ [regexp, colors, styles] ] -``` - -With the context dictionary at hand, you have access to the internal configuration of colout, you -can thus change colormaps for special keywords, the scale, even the available colors, styles or -themes. - -See the cmake them for how to modify an existing colormap if (and only if) the user didn't ask for an alternative one. -See the ninja theme for how to extend an existing theme with more regexps and a different configuration. -See the gcc theme for an example of how to use the localization of existing softwares to build translated regexp. - - -### Buffering - -Note that when you use colout within real time streams (like `tail -f X | grep Y | colout Z`) of -commands, you may observe that the lines are printed by large chunks and not one by one, in real -time. -This is not due to colout but to the buffering behavior of your shell. - -To fix that, use `stdbuf`, for example: `tail -f X | stdbuf -o0 grep Y | colout Z`. - -## Authors - -* nojhan : original idea, main developer, maintainer. -* Adrian Sadłocha -* Alex Burka -* Brian Foley -* Charles Lewis -* DainDwarf -* Dimitri Merejkowsky -* Dong Wei Ming -* Fabien MARTY -* Jason Green -* John Anderson -* Jonathan Poelen -* Louis-Kenzo Furuya Cahier -* Mantas -* Martin Ueding -* Nicolas Pouillard -* Nurono -* Oliver Bristow -* orzrd <61966225@qq.com> -* Philippe Daouadi -* Piotr Staroszczyk -* Scott Lawrence -* Xu Di -* https://github.com/stdedos: maintainer. diff --git a/bin/colout b/bin/colout new file mode 100644 index 0000000..7702d17 --- /dev/null +++ b/bin/colout @@ -0,0 +1,11 @@ +#!/bin/bash +# Copyright (c) 2013 Martin Ueding + +# Small launcher script for the main module. + +# Licence: GPL 3 + +set -e +set -u + +python3 -m colout.colout "$@" diff --git a/colout/colout.py b/colout/colout.py index 2d51fac..fdc523d 100755 --- a/colout/colout.py +++ b/colout/colout.py @@ -1,147 +1,30 @@ #!/usr/bin/env python3 #encoding: utf-8 -# Color Up Arbitrary Command Output +# Color Up Arbitrary Command Ouput # Licensed under the GPL version 3 # 2012 (c) nojhan -import os -import re import sys -import copy +import re +import random +import os import glob import math -import pprint -import random +import importlib +import logging import signal import string -import hashlib -import logging -import argparse -import importlib -import functools -import babel.numbers as bn # set the SIGPIPE handler to kill the program instead of # ending in a write error when a broken pipe occurs signal.signal( signal.SIGPIPE, signal.SIG_DFL ) -############################################################################### -# Global variable(s) -############################################################################### - -context = {} -debug = False - -# Available styles -context["styles"] = { - "normal": 0, "bold": 1, "faint": 2, "italic": 3, "underline": 4, - "blink": 5, "rapid_blink": 6, - "reverse": 7, "conceal": 8 -} - -error_codes = {"UnknownColor": 1, "DuplicatedPalette": 2, "MixedModes": 3, "UnknownLexer": 4, "UnknownResource": 5} - -# Available color names in 8-colors mode. -eight_colors = ["black","red","green","yellow","blue","magenta","cyan","white"] -# Given in that order, the ASCII code is the index. -eight_color_codes = {n:i for i,n in enumerate(eight_colors)} -# One can add synonyms. -eight_color_codes["orange"] = eight_color_codes["yellow"] -eight_color_codes["purple"] = eight_color_codes["magenta"] - -# Foreground colors has a special "none" item. -# Note: use copy to avoid having the same reference over fore/background. -context["colors"] = copy.copy(eight_color_codes) -context["colors"]["none"] = -1 - -# Background has the same colors than foreground, but without the none code. -context["backgrounds"] = copy.copy(eight_color_codes) - -context["themes"] = {} - -# pre-defined colormaps -# 8-colors mode should start with a lower-case letter (and can contains either named or indexed colors) -# 256-colors mode should start with an upper-case letter (and should contains indexed colors) -context["colormaps"] = { - # Rainbows - "rainbow" : ["magenta", "blue", "cyan", "green", "yellow", "red"], - "Rainbow" : [92, 93, 57, 21, 27, 33, 39, 45, 51, 50, 49, 48, 47, 46, 82, 118, 154, 190, 226, 220, 214, 208, 202, 196], - - # From magenta to red, with white in the middle - "spectrum" : ["magenta", "blue", "cyan", "white", "green", "yellow", "red"], - "Spectrum" : [91, 92, 56, 57, 21, 27, 26, 32, 31, 37, 36, 35, 41, 40, 41, 77, 83, 84, 120, 121, 157, 194, 231, 254, 255, 231, 230, 229, 228, 227, 226, 220, 214, 208, 202, 196], - - # All the colors are available for the default `random` special - "random" : context["colors"], - "Random" : list(range(256)) -} # colormaps - -context["colormaps"]["scale"] = context["colormaps"]["spectrum"] -context["colormaps"]["Scale"] = context["colormaps"]["Spectrum"] -context["colormaps"]["hash"] = context["colormaps"]["rainbow"] -context["colormaps"]["Hash"] = context["colormaps"]["Rainbow"] -context["colormaps"]["default"] = context["colormaps"]["spectrum"] -context["colormaps"]["Default"] = context["colormaps"]["Spectrum"] - -context["user_defined_colormaps"] = False - -context["colormap_idx"] = 0 - -context["scale"] = (0,100) - -context["lexers"] = [] - -# Character use as a delimiter -# between foreground and background. -context["sep_pair"]="." -context["sep_list"]="," - -class UnknownColor(Exception): - pass - -class DuplicatedPalette(Exception): - pass - -class DuplicatedTheme(Exception): - pass - -class MixedModes(Exception): - pass - - ############################################################################### # Ressource parsing helpers ############################################################################### -def make_colormap( colors, sep_list = context["sep_list"] ): - cmap = colors.split(sep_list) - - # Check unicity of mode. - modes = [mode(c) for c in cmap] - if len(uniq(modes)) > 1: - # Format a list of color:mode, for error display. - raise MixedModes(", ".join(["%s:%s" % cm for cm in zip(cmap,modes)])) - - return cmap - - -def set_special_colormaps( cmap, sep_list = context["sep_list"] ): - """Change all the special colors to a single colormap (which must be a list of colors).""" - global context - context["colormaps"]["scale"] = cmap - context["colormaps"]["Scale"] = cmap - context["colormaps"]["hash"] = cmap - context["colormaps"]["Hash"] = cmap - context["colormaps"]["default"] = cmap - context["colormaps"]["Default"] = cmap - context["colormaps"]["random"] = cmap - context["colormaps"]["Random"] = cmap - context["user_defined_colormaps"] = True - logging.debug("user-defined special colormap: %s" % sep_list.join([str(i) for i in cmap]) ) - - def parse_gimp_palette( filename ): """ Parse the given filename as a GIMP palette (.gpl) @@ -177,7 +60,7 @@ def parse_gimp_palette( filename ): palette = [] for line in lines: # skip lines with only a comment - if re.match(r"^\s*#.*$", line ): + if re.match("^\s*#.*$", line ): continue # decode the columns-ths codes. Generally [R G B] followed by a comment colors = [ int(c) for c in line.split()[:columns] ] @@ -205,13 +88,7 @@ def uniq( lst ): def rgb_to_ansi( r, g, b ): """Convert a RGB color to its closest 256-colors ANSI index""" - - # Range limits for the *colored* section of ANSI, - # this does not include the *gray* section. - ansi_min = 16 - ansi_max = 234 - - # ansi_max is the higher possible RGB value for ANSI *colors* + # ansi_max is the higher possible RGB value for ANSI colors # limit RGB values to ansi_max red,green,blue = tuple([ansi_max if c>ansi_max else c for c in (r,g,b)]) @@ -242,91 +119,131 @@ def hex_to_rgb(h): return tuple( int(h[i:i+lh//3], 16) for i in range(0, lh, lh//3) ) +############################################################################### +# Global variables +############################################################################### + +# Escaped end markers for given color modes +endmarks = {8: ";", 256: ";38;5;"} + +ansi_min = 16 +ansi_max = 234 + +# Available styles +styles = { + "normal": 0, "bold": 1, "faint": 2, "italic": 3, "underline": 4, + "blink": 5, "rapid_blink": 6, + "reverse": 7, "conceal": 8 +} + +# Available color names in 8-colors mode +colors = { + "black": 0, "red": 1, "green": 2, "yellow": 3, "blue": 4, + "magenta": 5, "cyan": 6, "white": 7, "none": -1 +} + +themes = {} + +# pre-defined colormaps +# 8-colors mode should start with a lower-case letter (and can contains either named or indexed colors) +# 256-colors mode should start with an upper-case letter (and should contains indexed colors) +colormaps = { + # Rainbows + "rainbow" : ["magenta", "blue", "cyan", "green", "yellow", "red"], + "Rainbow" : [92, 93, 57, 21, 27, 33, 39, 45, 51, 50, 49, 48, 47, 46, 82, 118, 154, 190, 226, 220, 214, 208, 202, 196], + + # from magenta to red, with white in the middle + "spectrum" : ["magenta", "blue", "cyan", "white", "green", "yellow", "red"], + "Spectrum" : [91, 92, 56, 57, 21, 27, 26, 32, 31, 37, 36, 35, 41, 40, 41, 77, 83, 84, 120, 121, 157, 194, 231, 254, 255, 231, 230, 229, 228, 227, 226, 220, 214, 208, 202, 196] +} # colormaps + +colormap = colormaps["rainbow"] # default colormap to rainbow +colormap_idx = 0 + +scale = (0,100) + +class UnknownColor(Exception): + pass + +class DuplicatedPalette(Exception): + pass + +class DuplicatedTheme(Exception): + pass + + ############################################################################### # Load available extern resources ############################################################################### def load_themes( themes_dir): - global context + global themes logging.debug("search for themes in: %s" % themes_dir) - sys.path.append( themes_dir ) + os.chdir( themes_dir ) # load available themes - for f in glob.iglob(os.path.join(themes_dir, "colout_*.py")): - basename = os.path.basename(f) # Remove path. - module = os.path.splitext(basename)[0] # Remove extension. - name = "_".join(module.split("_")[1:]) # Remove the 'colout_' prefix. - if name in context["themes"]: + for f in glob.iglob("colout_*.py"): + module = ".".join(f.split(".")[:-1]) # remove extension + name = "_".join(module.split("_")[1:]) # remove the prefix + if name in themes: raise DuplicatedTheme(name) logging.debug("load theme %s" % name) - context["themes"][name] = importlib.import_module(module) + themes[name] = importlib.import_module(module) -def load_palettes( palettes_dir, ignore_duplicates = True ): - global context +def load_palettes( palettes_dir ): + global colormaps logging.debug("search for palettes in: %s" % palettes_dir) + os.chdir( palettes_dir ) # load available colormaps (GIMP palettes format) - for p in glob.iglob(os.path.join(palettes_dir, "*.gpl")): + for p in glob.iglob("*.gpl"): try: name,palette = parse_gimp_palette(p) except Exception as e: logging.warning("error while parsing palette %s: %s" % ( p,e ) ) continue - if name in context["colormaps"]: - if ignore_duplicates: - logging.warning("ignore this duplicated palette name: %s" % name) - else: - raise DuplicatedPalette(name) + if name in colormaps: + raise DuplicatedPalette(name) # Convert the palette to ANSI ansi_palette = [ rgb_to_ansi(r,g,b) for r,g,b in palette ] # Compress it so that there isn't two consecutive identical colors compressed = uniq(ansi_palette) logging.debug("load %i ANSI colors in palette %s: %s" % (len(compressed), name, compressed)) - context["colormaps"][name] = compressed + colormaps[name] = compressed def load_lexers(): - global context + global lexers # load available pygments lexers lexers = [] - global get_lexer_by_name - from pygments.lexers import get_lexer_by_name - - global highlight - from pygments import highlight - - global Terminal256Formatter - from pygments.formatters import Terminal256Formatter - - global TerminalFormatter - from pygments.formatters import TerminalFormatter - - from pygments.lexers import get_all_lexers try: + global get_lexer_by_name + from pygments.lexers import get_lexer_by_name + + global highlight + from pygments import highlight + + global Terminal256Formatter + from pygments.formatters import Terminal256Formatter + + global TerminalFormatter + from pygments.formatters import TerminalFormatter + + from pygments.lexers import get_all_lexers + except ImportError: + logging.warning("the pygments module has not been found, syntax coloring is not available") + pass + else: for lexer in get_all_lexers(): - l = None - # If the tuple has one-word aliases - # (which are usually a better option than the long names - # for a command line argument). - if lexer[1]: - l = lexer[1][0] # Take the first one. - else: - assert(lexer[0]) - l = lexer[0] # Take the long name, which should alway exists. - if not l: + try: + lexers.append(lexer[1][0]) + except IndexError: logging.warning("cannot load lexer: %s" % lexer[1][0]) - pass # Forget about this lexer. + pass else: - assert(" " not in l) # Should be very rare, but probably a source of bugs. - lexers.append(l) - except: - logging.warning("error while executing the pygment module, syntax coloring is not available") - - lexers.sort() - logging.debug("loaded %i lexers: %s" % (len(lexers), ", ".join(lexers))) - - context["lexers"] = lexers + logging.debug("loaded lexer %s" % lexer[1][0]) + lexers.sort() def load_resources( themes_dir, palettes_dir ): @@ -339,184 +256,10 @@ def load_resources( themes_dir, palettes_dir ): # Library ############################################################################### -def mode( color ): - global context - if type(color) is int: - if 0 <= color and color <= 255 : - return 256 - else: - raise UnknownColor(color) - elif color in context["colors"]: - return 8 - elif color in context["colormaps"].keys(): - if color[0].islower(): - return 8 - elif color[0].isupper(): - return 256 - elif color.lower() in ("scale","hash","random") or color.lower() in context["lexers"]: - if color[0].islower(): - return 8 - elif color[0].isupper(): - return 256 - elif color[0] == "#": - return 256 - elif color.isdigit() and (0 <= int(color) and int(color) <= 255) : - return 256 - else: - raise UnknownColor(color) - - -def next_in_map( name ): - global context - # loop over indices in colormap - return (context["colormap_idx"]+1) % len(context["colormaps"][name]) - - -def color_random( color ): - global context - m = mode(color) - if m == 8: - color_name = random.choice(list(context["colormaps"]["random"])) - color_code = context["colors"][color_name] - color_code = str(30 + color_code) - - elif m == 256: - color_nb = random.choice(context["colormaps"]["Random"]) - color_code = str(color_nb) - - return color_code - - -def color_in_colormaps( color ): - global context - m = mode(color) - if m == 8: - c = context["colormaps"][color][context["colormap_idx"]] - if c.isdigit(): - color_code = str(30 + c) - else: - color_code = str(30 + context["colors"][c]) - - else: - color_nb = context["colormaps"][color][context["colormap_idx"]] - color_code = str( color_nb ) - - context["colormap_idx"] = next_in_map(color) - - return color_code - - -def color_scale( name, text ): - # filter out everything that does not seem to be necessary to interpret the string as a number - # this permits to transform "[ 95%]" to "95" before number conversion, - # and thus allows to color a group larger than the matched number - chars_in_numbers = "-+.,e/*" - allowed = string.digits + chars_in_numbers - nb = "".join([i for i in filter(allowed.__contains__, text)]) - - # interpret as decimal - f = None - try: - f = float(bn.parse_decimal(nb)) - except bn.NumberFormatError: - pass - if f is not None: - # normalize with scale if it's a number - f = (f - context["scale"][0]) / (context["scale"][1]-context["scale"][0]) - else: - # interpret as float between 0 and 1 otherwise - f = eval(nb) - - # if out of scale, do not color - if f < 0 or f > 1: - return None - - # normalize and scale over the nb of colors in cmap - colormap = context["colormaps"][name] - i = int( math.ceil( f * (len(colormap)-1) ) ) - color = colormap[i] - - # infer mode from the color in the colormap - m = mode(color) - - if m == 8: - color_code = str(30 + context["colors"][color]) - else: - color_code = str(color) - - return color_code - - -def color_hash( name, text ): - hasher = hashlib.md5() - hasher.update(text.encode('utf-8')) - hash = hasher.hexdigest() - - f = float(functools.reduce(lambda x, y: x+ord(y), hash, 0) % 101) - - # normalize and scale over the nb of colors in cmap - colormap = context["colormaps"][name] - i = int( math.ceil( (f - context["scale"][0]) / (context["scale"][1]-context["scale"][0]) * (len(colormap)-1) ) ) - color = colormap[i] - - # infer mode from the color in the colormap - m = mode(color) - - if m == 8: - color_code = str(30 + context["colors"][color]) - else: - color_code = str(color) - - return color_code - - -def color_map(name): - global context - # current color - color = context["colormaps"][name][ context["colormap_idx"] ] - - m = mode(color) - if m == 8: - color_code = str(30 + context["colors"][color]) - else: - color_nb = int(color) - assert( 0 <= color_nb <= 255 ) - color_code = str(color_nb) - - context["colormap_idx"] = next_in_map(name) - - return color,color_code - - -def color_lexer( name, style, text ): - lexer = get_lexer_by_name(name.lower()) - # Python => 256 colors, python => 8 colors - m = mode(name) - if m == 256: - try: - formatter = Terminal256Formatter(style=style) - except: # style not found - formatter = Terminal256Formatter() - else: - if style not in ("light","dark"): - style = "dark" # dark color scheme by default - formatter = TerminalFormatter(bg=style) - # We should return all but the last character, - # because Pygments adds a newline char. - if not debug: - return highlight(text, lexer, formatter)[:-1] - else: - return "<"+name+">"+ highlight(text, lexer, formatter)[:-1] + "" - - -def colorin(text, color="red", style="normal", sep_pair=context["sep_pair"]): +def colorin(text, color="red", style="normal"): """ Return the given text, surrounded by the given color ASCII markers. - The given color may be either a single name, encoding the foreground color, - or a pair of names, delimited by the given sep_pair, - encoding foreground and background, e.g. "red.blue". - If the given color is a name that exists in available colors, a 8-colors mode is assumed, else, a 256-colors mode. @@ -530,115 +273,163 @@ def colorin(text, color="red", style="normal", sep_pair=context["sep_pair"]): assert( type(color) is str ) + global colormap_idx global debug # Special characters. start = "\033[" stop = "\033[0m" - # Escaped end markers for given color modes - endmarks = {8: ";", 256: ";38;5;"} - color_code = "" style_code = "" - background_code = "" - style_codes = [] # Convert the style code if style == "random" or style == "Random": - style = random.choice(list(context["styles"].keys())) + style = random.choice(list(styles.keys())) else: - styles = style.split(sep_pair) - for astyle in styles: - if astyle in context["styles"]: - style_codes.append(str(context["styles"][astyle])) - style_code = ";".join(style_codes) + if style in styles: + style_code = str(styles[style]) - color_pair = color.strip().split(sep_pair) - color = color_pair[0] - background = color_pair[1] if len(color_pair) == 2 else "none" - - if color == "none" and background == "none": + if color == "none": # if no color, style cannot be applied if not debug: return text else: return ""+text+"" - elif color.lower() == "random": - color_code = color_random( color ) + elif color == "random": + mode = 8 + color_code = random.choice(list(colors.values())) + color_code = str(30 + color_code) + + elif color == "Random": + mode = 256 + color_nb = random.randint(0, 255) + color_code = str(color_nb) + + elif color in colormaps.keys(): + if color[0].islower(): # lower case first letter + mode = 8 + c = colormaps[color][colormap_idx] + if c.isdigit(): + color_code = str(30 + c) + else: + color_code = str(30 + colors[c]) + + else: # upper case + mode = 256 + color_nb = colormaps[color][colormap_idx] + color_code = str( color_nb ) + + if colormap_idx < len(colormaps[color])-1: + colormap_idx += 1 + else: + colormap_idx = 0 elif color.lower() == "scale": # "scale" or "Scale" - color_code = color_scale( color, text ) - # "hash" or "Hash"; useful to randomly but consistently color strings - elif color.lower() == "hash": - color_code = color_hash( color, text ) + # filter out everything that does not seem to be necessary to interpret the string as a number + # this permits to transform "[ 95%]" to "95" before number conversion, + # and thus allows to color a group larger than the matched number + chars_in_numbers = "-+.,e" + allowed = string.digits + chars_in_numbers + nb = "".join([i for i in filter(allowed.__contains__, text)]) - # The user can change the "colormap" variable to its favorite one before calling colorin. + # interpret as decimal + try: + # babel is a specialized module + import babel.numbers as bn + f = float(bn.parse_decimal(nb)) + except ImportError: + f = float(nb) + + # if out of scale, do not color + if f < scale[0] or f > scale[1]: + return text + + if color[0].islower(): + mode = 8 + cmap = colormaps["spectrum"] + + # normalize and scale over the nb of colors in cmap + i = int( math.ceil( (f - scale[0]) / (scale[1]-scale[0]) * (len(cmap)-1) ) ) + + color = cmap[i] + color_code = str(30 + colors[color]) + + else: + mode = 256 + cmap = colormaps["Spectrum"] + i = int( math.ceil( (f - scale[0]) / (scale[1]-scale[0]) * (len(cmap)-1) ) ) + color = cmap[i] + color_code = str(color) + + # Really useful only when using colout as a library + # thus you can change the "colormap" variable to your favorite one before calling colorin elif color == "colormap": - # "default" should have been set to the user-defined colormap. - color,color_code = color_map("default") + color = colormap[colormap_idx] + if color in colors: + mode = 8 + color_code = str(30 + colors[color]) + else: + mode = 256 + color_nb = int(color) + assert(0 <= color_nb <= 255) + color_code = str(color_nb) - # Registered colormaps should be tested after special colors, - # because special tags are also registered as colormaps, - # but do not have the same simple behavior. - elif color in context["colormaps"].keys(): - color_code = color_in_colormaps( color ) + if colormap_idx < len(colormap)-1: + colormap_idx += 1 + else: + colormap_idx = 0 # 8 colors modes - elif color in context["colors"]: - color_code = str(30 + context["colors"][color]) + elif color in colors: + mode = 8 + color_code = str(30 + colors[color]) # hexadecimal color elif color[0] == "#": + mode = 256 color_nb = rgb_to_ansi(*hex_to_rgb(color)) assert(0 <= color_nb <= 255) color_code = str(color_nb) # 256 colors mode elif color.isdigit(): + mode = 256 color_nb = int(color) assert(0 <= color_nb <= 255) color_code = str(color_nb) # programming language - elif color.lower() in context["lexers"]: - # bypass color encoding and return text colored by the lexer - return color_lexer(color,style,text) + elif color.lower() in lexers: + lexer = get_lexer_by_name(color.lower()) + # Python => 256 colors, python => 8 colors + ask_256 = color[0].isupper() + if ask_256: + try: + formatter = Terminal256Formatter(style=style) + except: # style not found + formatter = Terminal256Formatter() + else: + if style not in ("light","dark"): + style = "dark" # dark color scheme by default + formatter = TerminalFormatter(bg=style) + # We should return all but the last character, + # because Pygments adds a newline char. + if not debug: + return highlight(text, lexer, formatter)[:-1] + else: + return "<"+color+">"+ highlight(text, lexer, formatter)[:-1] + "" # unrecognized else: raise UnknownColor(color) - m = mode(color) - - if background in context["backgrounds"] and m == 8: - background_code = endmarks[m] + str(40 + context["backgrounds"][background]) - elif background == "none": - background_code = "" + if not debug: + return start + style_code + endmarks[mode] + color_code + "m" + text + stop else: - raise UnknownColor(background) - - if color_code is not None: - if not debug: - return start + style_code + endmarks[m] + color_code + background_code + "m" + text + stop - else: - return start + style_code + endmarks[m] + color_code + background_code + "m" \ - + "" \ - + text + "" + stop - else: - if not debug: - return text - else: - return "" + text + "" + return start + style_code + endmarks[mode] + color_code + "m<" + color + ">" + text + "" + stop def colorout(text, match, prev_end, color="red", style="normal", group=0): @@ -654,7 +445,7 @@ def colorout(text, match, prev_end, color="red", style="normal", group=0): return colored_text, end -def colorup(text, pattern, color="red", style="normal", on_groups=False, sep_list=context["sep_list"]): +def colorup(text, pattern, color="red", style="normal", on_groups=False): """ Color up every characters that match the given regexp patterns. If groups are specified, only color up them and not the whole pattern. @@ -663,10 +454,21 @@ def colorup(text, pattern, color="red", style="normal", on_groups=False, sep_lis in which case the different matching groups may be formatted differently. If there is less colors/styles than groups, the last format is used for the additional groups. - """ - global context - global debug + >>> colorup("Fetchez la vache", "vache", "red", "bold") + 'Fetchez la \x1b[1;31mvache\x1b[0m' + >>> colorup("Faites chier la vache", "[Fv]a", "red", "bold") + '\x1b[1;31mFa\x1b[0mites chier la \x1b[1;31mva\x1b[0mche' + >>> colorup("Faites Chier la Vache", "[A-Z](\S+)\s", "red", "bold") + 'F\x1b[1;31maites\x1b[0m C\x1b[1;31mhier\x1b[0m la Vache' + >>> colorup("Faites Chier la Vache", "([A-Z])(\S+)\s", "red,green", "bold") + '\x1b[1;31mF\x1b[0m\x1b[1;32maites\x1b[0m \x1b[1;31mC\x1b[0m\x1b[1;32mhier\x1b[0m la Vache' + >>> colorup("Faites Chier la Vache", "([A-Z])(\S+)\s", "green") + '\x1b[0;32mF\x1b[0m\x1b[0;32maites\x1b[0m \x1b[0;32mC\x1b[0m\x1b[0;32mhier\x1b[0m la Vache' + >>> colorup("Faites Chier la Vache", "([A-Z])(\S+)\s", "blue", "bold,italic") + '\x1b[1;34mF\x1b[0m\x1b[3;34maites\x1b[0m \x1b[1;34mC\x1b[0m\x1b[3;34mhier\x1b[0m la Vache' + """ + global colormap_idx if not debug: regex = re.compile(pattern) @@ -690,17 +492,17 @@ def colorup(text, pattern, color="red", style="normal", on_groups=False, sep_lis # Build a list of colors that match the number of grouped, # if there is not enough colors, duplicate the last one. - colors_l = color.split(sep_list) + colors_l = color.split(",") group_colors = colors_l + [colors_l[-1]] * (nb_groups - len(colors_l)) # Same for styles - styles_l = style.split(sep_list) + styles_l = style.split(",") group_styles = styles_l + [styles_l[-1]] * (nb_groups - len(styles_l)) # If we want to iterate colormaps on groups instead of patterns if on_groups: # Reset the counter at the beginning of each match - context["colormap_idx"] = 0 + colormap_idx = 0 # For each group index. # Note that match.groups returns a tuple (thus being indexed in [0,n[), @@ -765,8 +567,6 @@ def map_write( stream_in, stream_out, function, *args ): while True: try: item = stream_in.readline() - except UnicodeDecodeError: - continue except KeyboardInterrupt: break if not item: @@ -774,7 +574,7 @@ def map_write( stream_in, stream_out, function, *args ): write( function(item, *args), stream_out ) -def colorgen(stream, pattern, color="red", style="normal", on_groups=False, sep_list=context["sep_list"]): +def colorgen(stream, pattern, color="red", style="normal", on_groups=False): """ A generator that colors the items given in an iterable input. @@ -790,14 +590,71 @@ def colorgen(stream, pattern, color="red", style="normal", on_groups=False, sep_ break if not item: break - yield colorup(item, pattern, color, style, on_groups, sep_list) + yield colorup(item, pattern, color, style, on_groups) ###################### # Command line tools # ###################### -def _args_parse(argv, usage=""): +def __args_dirty__(argv, usage=""): + """ + Roughly extract options from the command line arguments. + To be used only when argparse is not available. + + Returns a tuple of (pattern,color,style,on_stderr). + + >>> colout.__args_dirty__(["colout","pattern"],"usage") + ('pattern', 'red', 'normal', False) + >>> colout.__args_dirty__(["colout","pattern","colors","styles"],"usage") + ('pattern', 'colors', 'styles', False) + >>> colout.__args_dirty__(["colout","pattern","colors","styles","True"],"usage") + ('pattern', 'colors', 'styles', True) + """ + + # Use a dirty argument picker + # Check for bad usage or an help flag + if len(argv) < 2 \ + or len(argv) > 10 \ + or argv[1] == "--help" \ + or argv[1] == "-h": + print(usage+"\n") + print("Usage:", argv[0], " [] [] []") + print("\tAvailable colors:", " ".join(colors)) + print("\tAvailable styles:", " ".join(styles)) + print("Example:", argv[0], "'^(def)\s+(\w*).*$' blue,magenta italic,bold < colout.py") + sys.exit(1) + + assert(len(argv) >= 2) + # Get mandatory arguments + pattern = argv[1] + + # default values for optional args + color = "red" + style = "normal" + on_stderr = False + + if len(argv) >= 3: + color = argv[2] + if len(argv) >= 4: + style = argv[3] + if len(argv) == 5: + on_groups = bool(argv[4]) + if len(argv) == 6: + as_colormap = bool(argv[5]) + if len(argv) == 7: + as_theme = bool(argv[6]) + if len(argv) == 8: + as_source = bool(argv[7]) + if len(argv) == 9: + as_all = bool(argv[8]) + if len(argv) == 10: + scale = bool(argv[9]) + + return pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, scale + + +def __args_parse__(argv, usage=""): """ Parse command line arguments with the argparse library. Returns a tuple of (pattern,color,style,on_stderr). @@ -808,30 +665,25 @@ def _args_parse(argv, usage=""): parser.add_argument("pattern", metavar="REGEX", type=str, nargs=1, help="A regular expression") - pygments_warn=" You can use a language name to activate syntax coloring (see `-r all` for a list)." - parser.add_argument("color", metavar="COLOR", type=str, nargs='?', default="red", help="A number in [0…255], a color name, a colormap name, \ - a palette or a comma-separated list of those values." + pygments_warn) + a palette or a comma-separated list of those values.") parser.add_argument("style", metavar="STYLE", type=str, nargs='?', default="bold", help="One of the available styles or a comma-separated list of styles.") parser.add_argument("-g", "--groups", action="store_true", - help="For color maps (random, rainbow, etc.), iterate over matching groups \ + help="For color maps (random, rainbow), iterate over matching groups \ in the pattern instead of over patterns") parser.add_argument("-c", "--colormap", action="store_true", - help="Interpret the given COLOR comma-separated list of colors as a colormap \ - (cycle the colors at each match)") + help="Use the given colors as a colormap (cycle the colors at each match)") - babel_warn=" (numbers will be parsed according to your locale)" - - parser.add_argument("-l", "--scale", metavar="SCALE", - help="When using the 'scale' colormap, parse matches as decimal numbers \ - and apply the rainbow colormap linearly between the given SCALE=min,max" + babel_warn) + parser.add_argument("-l", "--scale", + help="When using the 'scale' colormap, parse matches as decimal numbers (taking your locale into account) \ + and apply the rainbow colormap linearly between the given SCALE=min,max") parser.add_argument("-a", "--all", action="store_true", help="Color the whole input at once instead of line per line \ @@ -842,50 +694,28 @@ def _args_parse(argv, usage=""): help="Interpret REGEX as a theme.") parser.add_argument("-T", "--themes-dir", metavar="DIR", action="append", - help="Search for additional themes (colout_*.py files) in the given directory") + help="Search for additional themes (colout_*.py files) in this directory") parser.add_argument("-P", "--palettes-dir", metavar="DIR", action="append", - help="Search for additional palettes (*.gpl files) in the given directory") + help="Search for additional palettes (*.gpl files) in this directory") - parser.add_argument("-d", "--default", metavar="COLORMAP", default=None, - help="When using special colormaps (`random`, `scale` or `hash`), use this COLORMAP. \ - This can be either one of the available colormaps or a comma-separated list of colors. \ - WARNING: be sure to specify a default colormap that is compatible with the special colormap's mode \ - (8 or 256 colors).") - - # This normally should be an option with an argument, but this would end in an error, - # as no regexp is supposed to be passed after calling this option, - # we use it as the argument to this option. - # The only drawback is that the help message lacks a metavar... parser.add_argument("-r", "--resources", action="store_true", - help="Print the names of available resources. Use a comma-separated list of resources names \ - (styles, colors, special, themes, palettes, colormaps or lexers), \ - use 'all' to print everything.") - - parser.add_argument("-s", "--source", action="store_true", - help="Interpret REGEX as a source code readable by the Pygments library. \ - If the first letter of PATTERN is upper case, use the 256 colors mode, \ - if it is lower case, use the 8 colors mode. \ - Interpret COLOR as a Pygments style." + pygments_warn) - - parser.add_argument("-e", "--sep-list", metavar="CHAR", default=",", type=str, - help="Use this character as a separator for list of colors/resources/numbers (instead of comma).") - - parser.add_argument("-E", "--sep-pair", metavar="CHAR", default=".", type=str, - help="Use this character as a separator for foreground/background pairs (instead of period).") + help="Print the names of all available colors, styles, themes and palettes.") parser.add_argument("--debug", action="store_true", help="Debug mode: print what's going on internally, useful if you want to check what features are available.") - # HACK: Mock up "--resources ALL" if just "--resources" on command line - if (len(sys.argv) == 2 and (sys.argv[1] in ["-r", "--resources"])): - sys.argv.append("ALL") + parser.add_argument("-s", "--source", action="store_true", + help="Interpret REGEX as a source code readable by the Pygments library. \ + If the first letter of PATTERN is upper case, use the 256 colors mode, \ + if it is lower case, use the 8 colors mode. \ + Interpret COLOR as a Pygments style.") args = parser.parse_args() return args.pattern[0], args.color, args.style, args.groups, \ args.colormap, args.theme, args.source, args.all, args.scale, args.debug, args.resources, args.palettes_dir, \ - args.themes_dir, args.default, args.sep_list, args.sep_pair + args.themes_dir def write_all( as_all, stream_in, stream_out, function, *args ): @@ -899,16 +729,29 @@ def write_all( as_all, stream_in, stream_out, function, *args ): map_write( stream_in, stream_out, function, *args ) -def main(): - global context +if __name__ == "__main__": + + global debug + error_codes = {"UnknownColor":1, "DuplicatedPalette":2} + usage = "A regular expression based formatter that color up an arbitrary text stream." ##################### # Arguments parsing # ##################### - pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, myscale, \ - debug, resources, palettes_dirs, themes_dirs, default_colormap, sep_list, sep_pair \ - = _args_parse(sys.argv, usage) + try: + import argparse + + # if argparse is not installed + except ImportError: + pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, myscale \ + = __args_dirty__(sys.argv, usage) + + # if argparse is available + else: + pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, myscale, \ + debug, resources, palettes_dirs, themes_dirs \ + = __args_parse__(sys.argv, usage) if debug: lvl = logging.DEBUG @@ -921,12 +764,6 @@ def main(): ################## # Load resources # ################## - - context["sep_list"] = sep_list - logging.debug("Color list separator: '%s'" % context["sep_list"]) - context["sep_pair"] = sep_pair - logging.debug("Color pair separator: '%s'" % context["sep_pair"]) - try: # Search for available resources files (themes, palettes) # in the same dir as the colout.py script @@ -938,84 +775,48 @@ def main(): # try additional directories if asked if palettes_dirs: for adir in palettes_dirs: - if os.path.isdir(adir): - load_palettes( adir ) - else: + try: + os.chdir( adir ) + except OSError as e: logging.warning("cannot read palettes directory %s, ignore it" % adir) + continue + else: + load_palettes( adir ) if themes_dirs: for adir in themes_dirs: - if os.path.isdir(adir): - load_themes( adir ) - else: + try: + os.chdir( adir ) + except OSError as e: logging.warning("cannot read themes directory %s, ignore it" % adir) + continue + else: + load_themes( adir ) except DuplicatedPalette as e: logging.error( "duplicated palette file name: %s" % e ) sys.exit( error_codes["DuplicatedPalette"] ) - # if debug: - # setting = pprint.pformat(context, depth=2) - # logging.debug(setting) - if resources: - asked=[r.lower() for r in pattern.split(context["sep_list"])] + print("Available resources:") + print("STYLES: %s" % ", ".join(styles) ) + print("COLORS: %s" % ", ".join(colors) ) + print("SPECIAL: %s" % ", ".join(["random", "Random", "scale", "Scale", "colormap"]) ) - def join_sort( l ): - """ - Sort the given list in lexicographical order, - with upper-cases first, then lower cases - join the list with a comma. + if len(themes) > 0: + print("THEMES: %s" % ", ".join(themes.keys()) ) + else: + print("NO THEME") - >>> join_sort(["a","B","A","b"]) - 'A, a, B, b' - """ - return ", ".join(sorted(l, key=lambda s: s.lower()+s)) + if len(colormaps) > 0: + print("COLORMAPS: %s" % ", ".join(colormaps) ) + else: + print("NO COLORMAPS") - # print("Available resources:") - resources_not_found = [] - for res in asked: - resource_found = False - - if "style" in res or "all" in res: - print("STYLES: %s" % join_sort(context["styles"]) ) - resource_found = True - - if "color" in res or "all" in res: - print("COLORS: %s" % join_sort(context["colors"]) ) - resource_found = True - - if "special" in res or "all" in res: - print("SPECIAL: %s" % join_sort(["random", "Random", "scale", "Scale", "hash", "Hash", "colormap"]) ) - resource_found = True - - if "theme" in res or "all" in res: - if len(context["themes"]) > 0: - print("THEMES: %s" % join_sort(context["themes"].keys()) ) - else: - print("NO THEME") - resource_found = True - - if "colormap" in res or "all" in res: - if len(context["colormaps"]) > 0: - print("COLORMAPS: %s" % join_sort(context["colormaps"]) ) - else: - print("NO COLORMAPS") - resource_found = True - - if "lexer" in res or "all" in res: - if len(context["lexers"]) > 0: - print("SYNTAX COLORING: %s" % join_sort(context["lexers"]) ) - else: - print("NO SYNTAX COLORING (check that python3-pygments is installed)") - resource_found = True - - if not resource_found: - resources_not_found.append(res) - - if resources_not_found: - logging.error( "Unknown resources: %s" % ", ".join(resources_not_found) ) - sys.exit( error_codes["UnknownResource"] ) + if len(lexers) > 0: + print("LEXERS: %s" % ", ".join(lexers) ) + else: + print("NO LEXER") sys.exit(0) # not an error, we asked for help @@ -1025,39 +826,25 @@ def main(): try: if myscale: - context["scale"] = tuple([float(i) for i in myscale.split(context["sep_list"])]) - logging.debug("user-defined scale: %f,%f" % context["scale"]) + scale = tuple([float(i) for i in myscale.split(",")]) + logging.debug("user-defined scale: %f,%f" % scale) - # Default color maps - if default_colormap: - if default_colormap not in context["colormaps"]: - cmap = make_colormap(default_colormap,context["sep_list"]) - - elif default_colormap in context["colormaps"]: - cmap = context["colormaps"][default_colormap] - - set_special_colormaps( cmap, context["sep_list"] ) - - # explicit color map - if as_colormap is True and color not in context["colormaps"]: - context["colormaps"]["Default"] = make_colormap(color,context["sep_list"]) # replace the colormap by the given colors - context["colormaps"]["default"] = make_colormap(color,context["sep_list"]) # replace the colormap by the given colors + # use the generator: output lines as they come + if as_colormap is True and color != "rainbow": + colormap = color.split(",") # replace the colormap by the given colors color = "colormap" # use the keyword to switch to colormap instead of list of colors - logging.debug("used-defined default colormap: %s" % context["sep_list"].join(context["colormaps"]["Default"]) ) + logging.debug("used-defined colormap: %s" % ",".join(colormap) ) # if theme if as_theme: logging.debug( "asked for theme: %s" % pattern ) - assert(pattern in context["themes"].keys()) - context,theme = context["themes"][pattern].theme(context) - write_all( as_all, sys.stdin, sys.stdout, colortheme, theme ) + assert(pattern in themes.keys()) + write_all( as_all, sys.stdin, sys.stdout, colortheme, themes[pattern].theme() ) # if pygments elif as_source: logging.debug("asked for lexer: %s" % pattern.lower()) - if pattern.lower() not in context["lexers"]: - logging.error("Lexer %r is not available. Run with \"--resources all\" to see the options.") - sys.exit(error_codes["UnknownLexer"]) + assert(pattern.lower() in lexers) lexer = get_lexer_by_name(pattern.lower()) # Python => 256 colors, python => 8 colors ask_256 = pattern[0].isupper() @@ -1076,20 +863,9 @@ def main(): # if color else: - write_all( as_all, sys.stdin, sys.stdout, colorup, pattern, color, style, on_groups, context["sep_list"] ) + write_all( as_all, sys.stdin, sys.stdout, colorup, pattern, color, style, on_groups ) except UnknownColor as e: - if debug: - import traceback - print(traceback.format_exc()) - logging.error("Unknown color: %s (maybe you forgot to install python3-pygments?)" % e ) + logging.error("unknown color: %s" % e ) sys.exit( error_codes["UnknownColor"] ) - except MixedModes as e: - logging.error("You cannot mix up color modes when defining your own colormap." \ - + " Check the following 'color:mode' pairs: %s." % e ) - sys.exit( error_codes["MixedModes"] ) - - -if __name__ == "__main__": - main() diff --git a/colout/colout_catch2.py b/colout/colout_catch2.py deleted file mode 100644 index e67d86a..0000000 --- a/colout/colout_catch2.py +++ /dev/null @@ -1,23 +0,0 @@ -def theme(context): - - return context,[ - ["^ (Start)(.*): (.*):(.*)$", "yellow", "normal,normal,normal,bold"], # Test start. - # path file ext:line : - ["^(tests): (/.*?)/([^/:]+):([0-9]+): (.*)", "yellow,none,white,yellow,red", "bold,normal,bold,normal,bold"], - ["(`)(.*)('.*)", "red,Cpp,red", "bold,normal,bold"], - [r"^\.+$", "yellow", "bold"], - ["^=+$", "yellow", "bold"], - ["(/.*?)/([^/:]+):([0-9]+): (FAILED):", "white,white,yellow,red", "normal,bold,normal,bold"], - [r"(REQUIRE\(|CHECK\(|REQUIRE_THAT\()(.*)(\))$","yellow,Cpp,yellow","bold,normal,bold"], - # Hide uninteresting stuff: - ["[0-9]+/[0-9]+ Test.*","blue"], - ["^Filters:.*","blue"], - ["^Randomness seeded to:.*","blue"], - ["^tests is a Catch2.*","blue"], - ["^Run with.*", "blue"], - ["^~+$","blue"], - ["^-+$","blue"], - [r"^\s*(Scenario:|Given:|When:|Then:).*","blue"], - ["^(/.*?)/([^/:]+):([0-9]+)", "blue"], - ["^(test cases|assertions)(.*)", "blue"], - ] diff --git a/colout/colout_clang.py b/colout/colout_clang.py deleted file mode 100644 index a5525ef..0000000 --- a/colout/colout_clang.py +++ /dev/null @@ -1,85 +0,0 @@ -#encoding: utf-8 - -def default_gettext( msg ): - return msg - -def theme(context): - import os - import gettext - import locale - - section="blue" - - # get g++ version - gv = os.popen("g++ -dumpversion").read().strip() - - # get the current translations of gcc - try: - t = gettext.translation("gcc-"+gv) - except IOError: - _ = default_gettext - else: - _ = t.gettext - # _("msg") will return the given message, translated - - # if the locale is unicode - enc = locale.getpreferredencoding() - if "UTF" in enc: - # gcc will use unicode quotes - qo = "[‘`]" - qc = "[’']" - else: - # rather than ascii ones - qo = "['`]" - qc = "'" - - return context,[ - # Command line - [ r"[/\s]([cg]\+\+-*[0-9]*\.*[0-9]*)", "white", "bold" ], - [ r"\s(\-D)(\s*[^\s]+)", "none,green", "normal,bold" ], - [ r"\s(-g)", "green", "normal" ], - [ r"\s-O[0-4]", "green", "normal" ], - [ r"\s-[Wf][^\s]*", "magenta", "normal" ], - [ r"\s-pedantic", "magenta", "normal" ], - [ r"\s(-I)(/*[^\s]+/)([^/\s]+)", "none,blue", "normal,normal,bold" ], - [ r"\s(-L)(/*[^\s]+/)([^/\s]+)", "none,cyan", "normal,normal,bold" ], - [ r"\s(-l)([^/\s]+)", "none,cyan", "normal,bold" ], - [ r"\s-[oc]", "red", "bold" ], - [ r"\s(-+std(?:lib)?)=?([^\s]+)", "red", "normal,bold" ], - - # Important messages - [ _("error: "), "red", "bold" ], - [ _("fatal error: "), "red", "bold" ], - [ _("warning: "), "magenta", "bold" ], - [ _("undefined reference to "), "red", "bold" ], - # [-Wflag] - [ r"\[-W.*\]", "magenta"], - - # Highlight message start: - # path file ext : line : col … - [ "(/.*?)/([^/:]+): (In .*)"+qo, - section, - "normal,normal,bold" ], - - [ "(/.*?)/([^/:]+): (At .*)", - section, - "normal,normal,bold" ], - - [ _("In file included from"), section ], - - # Highlight locations: - # path file ext : line : col … - [ "(/.*?)/([^/:]+):([0-9]+):*([0-9]*)(.*)", - "none,white,yellow,none,none", - "normal,normal,normal,normal" ], - - # source code in single quotes - [ qo+"(.*?)"+qc, "Cpp", "monokai" ], - - # source code after a "note: candidate are/is:" - [ _("note: ")+"((?!.*("+qo+"|"+qc+")).*)$", "Cpp", "monokai" ], - # [ _("note: ")+"(candidate:)(.*)$", "green,Cpp", "normal,monokai" ], - # after the code part, to avoid matching ANSI escape chars - [ _("note: "), "green", "normal" ] - ] - diff --git a/colout/colout_cmake.py b/colout/colout_cmake.py index 66ab5a8..0a78395 100644 --- a/colout/colout_cmake.py +++ b/colout/colout_cmake.py @@ -1,5 +1,5 @@ -def theme(context): +def theme(): # CMake theme: # actions performing in cyan performing="cyan" @@ -8,13 +8,7 @@ def theme(context): # actions taking an unknown time untimed="blue" - # If the user do not ask for his own colormap - if not context["user_defined_colormaps"]: - # A palette that goes: purple, orange, white - percs = [45, 39, 33, 27, 21, 57, 63, 62, 98, 97, 133, 132, 138, 173, 172, 208, 214, 220, 226, 228, 229, 230, 231, 255] - context["colormaps"]["Scale"] = percs - - return context,[ + return [ # Configure... [ "^--.*works", performed ], [ "^--.*done", performed ], @@ -25,31 +19,26 @@ def theme(context): [ "^-- Configuring incomplete, errors occurred!", "red" ], [ "^--.*", performing ], # Errors - [ "CMake Error", "red" ], - [ "CMake Warning", "magenta" ], - [ "CMake Deprecation Warning", "magenta" ], + [ "CMake Error:", "red" ], + [ "CMake Warning", "yellow" ], # Scan [ "^(Scanning dependencies of target)(.*)$", performing, "normal,bold" ], - # Link (make) - # [ "^(Linking .* )(library|executable) (.*/)*(.+(\.[aso]+)*)$", - [ "^(Linking .* )(library|executable) (.*)$", + # Link + [ "^(Linking .* )(library|executable) (.*/)*(.+(\.[aso]+)*)$", untimed, "normal,normal,bold" ], - # [percent] Creating something - [ r"^\[\s*[0-9/]+%?\]\s(.*Creating.*)$", - performing, "normal" ], # [percent] Built - [ r"^\[\s*[0-9/]+%?\]\s(Built target)(\s.*)$", + [ "^\[\s*[0-9]+%\]\s(Built target)(\s.*)$", performed, "normal,bold" ], # [percent] Building - [ r"^\[\s*[0-9/]+%?\]\s(Building \w* object)\s+(.*)(\.dir)(.*/)([-\w]+).c.*.o$", - performing+","+performing+","+performing+",Hash,"+performing, "normal,normal,normal,normal,bold"], + [ "^\[\s*[0-9]+%\]\s(Building \w* object)(\s+.*/)([-\w]+.c.*)(.o)$", + performing, "normal,normal,bold,normal"], # [percent] Generating - [ r"^\[\s*[0-9/]+%?\]\s(Generating)(\s+.*)$", + [ "^\[\s*[0-9]+%\]\s(Generating)(\s+.*)$", performing, "normal,bold"], # make errors - [ r"make\[[0-9]+\].*", "yellow"], - [ r"(make: \*\*\* \[.+\] )(.* [0-9]+)", "red", "normal,bold"], - # progress percentage (make) - [ r"^(\[\s*[0-9]+%\])","Scale" ] + [ "make\[[0-9]+\].*", "yellow"], + [ "(make: \*\*\* \[.+\] )(.* [0-9]+)", "red", "normal,bold"], + # progress percentage + [ "^(\[\s*[0-9]+%\])","Scale" ] ] diff --git a/colout/colout_configure.py b/colout/colout_configure.py deleted file mode 100644 index 63e63a4..0000000 --- a/colout/colout_configure.py +++ /dev/null @@ -1,16 +0,0 @@ -#encoding: utf-8 - -def theme(context): - - return context, [ - ["^(checking .*)(yes|found|ok)$","green", "normal,bold"], - ["^(checking .*)(no|none)$", "yellow", "normal,bold"], - ["^(configure:) (error:)(.*)", "red","normal,bold"], - ["^(configure:)(.*)", "magenta","normal,bold"], - ["^(checking .*)", "blue",""], - ["^(config.status:) (creating|linking)(.*)", "cyan,blue","normal,normal,bold"], - ["^(config.status:) (executing )(.*)", "cyan,green","normal,normal,bold"], - ["^(config.status:) (.*)(is unchanged)", "cyan,green","normal,normal,bold"], - [r"^\s*(Build.*)(yes)$","green", "normal,bold"], - [r"^\s*(Build.*)(no)$","yellow", "normal,bold"], - ] diff --git a/colout/colout_ctest.py b/colout/colout_ctest.py deleted file mode 100644 index f2dd372..0000000 --- a/colout/colout_ctest.py +++ /dev/null @@ -1,19 +0,0 @@ - -def theme(context): - # CTest theme: - passed="green" - notrun="yellow" - notpassed="red" - - # If the user do not ask for his own colormap - # if not context["user_defined_colormaps"]: - # # A palette that goes: purple, orange, white - # percs = [45, 39, 33, 27, 21, 57, 63, 62, 98, 97, 133, 132, 138, 173, 172, 208, 214, 220, 226, 228, 229, 230, 231, 255] - # context["colormaps"]["Scale"] = percs - - return context,[ - # Passed - [ r"^\s*[0-9]+/[0-9]+ Test\s+#[0-9]+: (.*)\s+\.+\s+(Passed)", "blue,"+passed], - [ r"^\s*[0-9]+/[0-9]+ Test\s+#[0-9]+: (.*)\s+\.+(\*{3}Not Run.*)\s+.*", "blue,"+notrun], - [ r"^\s*[0-9]+/[0-9]+ Test\s+#[0-9]+: (.*)\s+\.+(.*\*{3}.*)\s+.*", "blue,"+notpassed], - ] diff --git a/colout/colout_django.py b/colout/colout_django.py deleted file mode 100644 index fcacc00..0000000 --- a/colout/colout_django.py +++ /dev/null @@ -1,36 +0,0 @@ - -def theme(context): - return context,[ - # Waiting - ["^Waiting for .*$", "red", "bold"], - [".*Sending.*", "green"], - # Watches - [r"^(Watching) (\S*) (.*)", "yellow", "bold,bold,normal"], - [".*reloading.$","yellow"], - # File from python/lib - [r"^(File) (/.*/lib/python[^/]*/site-packages/)([^/]*)\S* (first seen) (with mtime [0-9]*.*)$", - "blue,blue,white,blue,blue", "bold,normal,bold,bold,normal"], - # File from app (last 3 name highlighted) - [r"^(File) (/\S*/)(\S*/\S*/)(\S*) (first seen) (with mtime [0-9]*.*)$", - "magenta,magenta,white,white,magenta,magenta", "bold,normal,normal,bold,bold,normal"], - # SQL - ["(.*)(SELECT)(.*)(FROM)(.*)", - "green", "normal,bold,normal,bold,normal"], - ["(.*)(SELECT)(.*)(FROM)(.*)(WHERE)(.*)", - "green", "normal,bold,normal,bold,normal,bold,normal"], - # HTTP - [r"\"(GET) (\S*) (HTTP\S*)\" ([0-9]+) (.*)$", - "green,white,green,green,green", "bold,bold,normal,bold,normal"], - # Errors - ["(Exception) (while .*) '(.*)' (in) (.*) '(.*)'", "red,red,white,red,red,white", "bold,normal,bold,bold,normal,bold"], - ["(.*Error): (.*) '(.*)'", "red,red,white", "bold,normal,bold"], - [r"(django[^:\s]*)\.([^.:\s]*): (.*)", "red","normal,bold,normal"], - ["Traceback.*:","yellow"], - ["During handling.*","yellow"], - # File, line, in - [ - r"^\s{2}(File \")(/*.*?/)*([^/:]+)(\", line) ([0-9]+)(, in) (.*)$", - "blue, none, white,blue, yellow,blue", - "normal,normal,bold, normal,normal,bold" - ], - ] diff --git a/colout/colout_g++.py b/colout/colout_g++.py index a5525ef..adc3e79 100644 --- a/colout/colout_g++.py +++ b/colout/colout_g++.py @@ -3,7 +3,7 @@ def default_gettext( msg ): return msg -def theme(context): +def theme(): import os import gettext import locale @@ -33,27 +33,12 @@ def theme(context): qo = "['`]" qc = "'" - return context,[ - # Command line - [ r"[/\s]([cg]\+\+-*[0-9]*\.*[0-9]*)", "white", "bold" ], - [ r"\s(\-D)(\s*[^\s]+)", "none,green", "normal,bold" ], - [ r"\s(-g)", "green", "normal" ], - [ r"\s-O[0-4]", "green", "normal" ], - [ r"\s-[Wf][^\s]*", "magenta", "normal" ], - [ r"\s-pedantic", "magenta", "normal" ], - [ r"\s(-I)(/*[^\s]+/)([^/\s]+)", "none,blue", "normal,normal,bold" ], - [ r"\s(-L)(/*[^\s]+/)([^/\s]+)", "none,cyan", "normal,normal,bold" ], - [ r"\s(-l)([^/\s]+)", "none,cyan", "normal,bold" ], - [ r"\s-[oc]", "red", "bold" ], - [ r"\s(-+std(?:lib)?)=?([^\s]+)", "red", "normal,bold" ], - - # Important messages + return [ [ _("error: "), "red", "bold" ], - [ _("fatal error: "), "red", "bold" ], [ _("warning: "), "magenta", "bold" ], [ _("undefined reference to "), "red", "bold" ], # [-Wflag] - [ r"\[-W.*\]", "magenta"], + [ "\[-W.*\]", "magenta"], # Highlight message start: # path file ext : line : col … @@ -77,8 +62,7 @@ def theme(context): [ qo+"(.*?)"+qc, "Cpp", "monokai" ], # source code after a "note: candidate are/is:" - [ _("note: ")+"((?!.*("+qo+"|"+qc+")).*)$", "Cpp", "monokai" ], - # [ _("note: ")+"(candidate:)(.*)$", "green,Cpp", "normal,monokai" ], + [ _("note: ")+"((?!.*(candidate|"+qo+"|"+qc+")).*)$", "Cpp", "monokai" ], # after the code part, to avoid matching ANSI escape chars [ _("note: "), "green", "normal" ] ] diff --git a/colout/colout_javac.py b/colout/colout_javac.py deleted file mode 100644 index 92e5a2c..0000000 --- a/colout/colout_javac.py +++ /dev/null @@ -1,15 +0,0 @@ -#encoding: utf-8 - -def theme(context): - style="monokai" - return context,[ - [ r"^(.*\.java):([0-9]+):\s*(warning:.*)$", "white,yellow,magenta", "normal,normal,bold" ], - [ r"^(.*\.java):([0-9]+):(.*)$", "white,yellow,red", "normal,normal,bold" ], - [ r"^(symbol|location)\s*:\s*(.*)$", "blue,Java", "bold,"+style ], - [ r"^(found)\s*:\s*(.*)", "red,Java", "bold,"+style ], - [ r"^(required)\s*:\s*(.*)", "green,Java", "bold,"+style ], - [ r"^\s*\^$", "cyan", "bold" ], - [ r"^\s+.*$", "Java", style ], - [ "[0-9]+ error[s]*", "red", "bold" ], - [ "[0-9]+ warning[s]*", "magenta", "bold" ], - ] diff --git a/colout/colout_json.py b/colout/colout_json.py index 2f9898e..5eaefeb 100644 --- a/colout/colout_json.py +++ b/colout/colout_json.py @@ -1,12 +1,12 @@ -def theme(context): +def theme(): # This theme expect a formatted JSON input, with items spread across lines. # See tools like "python -m json.tool" or "json_xs" - return context,[ - [ r'[\[\]{}],*\s*\n' ], + return [ + [ '[\[\]{}],*\s*\n' ], [ '" (:) ', "yellow" ], - [ r'[\]}"](,)', "yellow" ], - [ r"\"(-*[0-9]+\.*[0-9]*e*-*[0-9]*)\"", "blue" ], + [ '[\]}"](,)', "yellow" ], + [ "\"(-*[0-9]+\.*[0-9]*e*-*[0-9]*)\"", "blue" ], [ '"(.*)"', "green" ], [ """["']""", "cyan" ] ] diff --git a/colout/colout_latex.py b/colout/colout_latex.py deleted file mode 100644 index 5567fbd..0000000 --- a/colout/colout_latex.py +++ /dev/null @@ -1,30 +0,0 @@ - -def theme(context): - return context,[ - # LaTeX - ["This is .*TeX.*$", "white", "bold"], - ["(LaTeX Warning): (.*) `(.*)' on page [0-9] (.*) on input line [0-9]+.$", - "magenta,magenta,white,magenta", "normal,bold,normal" ], - ["(LaTeX Warning): (.*)", "magenta", "normal,bold" ], - ["(LaTeX Error): (.*)", "red", "normal,bold" ], - [r"^(.*\.tex):([0-9]+): (.*)", "white,yellow,red", "normal,normal,bold" ], - # ["on (page [0-9]+)", "yellow", "normal" ], - ["on input (line [0-9]+)", "yellow", "normal" ], - ["^! .*$", "red", "bold"], - [r"(.*erfull) ([^\s]+).* in [^\s]+ at (lines [0-9]+--[0-9]+)", - "magenta,magenta,yellow", "normal"], - [r"\\[^\s]+\s", "white", "bold"], - [r"^l\.([0-9]+) (.*)", "yellow,tex"], - [r"^\s+(.*)", "tex"], - [r"(Output written on) (.*) \(([0-9]+ pages), [0-9]+ bytes\).", - "blue,white,blue", "normal,bold,normal"], - ["WARNING.*", "magenta", "normal"], - ["[wW]arning.*", "magenta", "normal"], - ["No pages of output", "red", "bold"], - - # BiBTeX - ["^(I couldn't) (.*)", "red", "normal,bold"], - ["(I found) no (.*)", "red"], - ["^---(line [0-9]+) of file (.*)", "yellow,white", "normal"], - ] - diff --git a/colout/colout_ninja.py b/colout/colout_ninja.py deleted file mode 100644 index 34dd9ec..0000000 --- a/colout/colout_ninja.py +++ /dev/null @@ -1,19 +0,0 @@ - -import colout_cmake - -def theme(context): - # Ninja theme - - # Inherit from the CMake theme - context,th = colout_cmake.theme(context) - - # Because Ninja note progress as a fraction, we do not want the scale of a percentage - context["scale"] = (0,1) - - # Link (ninja) - th.append( [ r"^\[[0-9/]+\]\s?(Linking .* )(library|executable) (.*/)*(.+(\.[aso]+)*)$", - "blue", "normal,normal,bold" ] ) - # progress percentage (ninja) - th.append( [ r"^(\[[0-9]+/[0-9]+\])","Scale" ] ) - - return context,th diff --git a/colout/colout_perm.py b/colout/colout_perm.py index 048230c..3d2ed6a 100644 --- a/colout/colout_perm.py +++ b/colout/colout_perm.py @@ -1,8 +1,8 @@ -def theme(context): - p="([-rwxsStT])" - reg=r"^([-dpcCDlMmpPs?])"+p*9+r"\s.*$" +def theme(): + p="([rwxs-])" + reg="^([d-])"+p*9+"\s.*$" colors="blue"+",green"*3+",yellow"*3+",red"*3 styles="normal"+ ",normal,italic,bold"*3 - return context,[ [reg, colors, styles] ] + return [ [reg, colors, styles] ] diff --git a/colout/colout_python.py b/colout/colout_python.py deleted file mode 100644 index 40e4b34..0000000 --- a/colout/colout_python.py +++ /dev/null @@ -1,20 +0,0 @@ - -def theme(context): - return context,[ - # traceback header - ["^Traceback .*$", "blue" ], - # File, line, in - [ - r"^\s{2}(File \")(/*.*?/)*([^/:]+)(\", line) ([0-9]+)(, in) (.*)$", - "blue, none, white,blue, yellow,blue", - "normal,normal,bold, normal,normal,bold" - ], - # [r"^\s{2}File \"(.*)\", line ([0-9]+), in (.*)$", "white,yellow,white", "normal,normal,bold" ], - # Error name - ["^([A-Za-z]*Error):*", "red", "bold" ], - ["^([A-Za-z]*Exception):*", "red", "bold" ], - # any quoted things - [r"Error.*['\"](.*)['\"]", "magenta" ], - # python code - [r"^\s{4}.*$", "Python", "monokai" ], - ] diff --git a/colout/colout_slurm.py b/colout/colout_slurm.py deleted file mode 100644 index 9f5af8d..0000000 --- a/colout/colout_slurm.py +++ /dev/null @@ -1,117 +0,0 @@ - -def theme(context): - # SLURM's states (from squeue manual). - - col_width = 9 - - COMPLETED =r"\bCOMPLETED" - PENDING =r"\bPENDING" - RUNNING =r"\bRUNNING" - CONFIGURING =r"\bCONFIGURING" - COMPLETING =r"\bCOMPLETING" - FAILED =r"\bFAILED" - DEADLINE =r"\bDEADLINE" - OUT_OF_MEMORY=r"\bOUT_OF_MEMORY" - TIMEOUT =r"\bTIMEOUT" - CANCELLED =r"\bCANCELLED" - BOOT_FAIL =r"\bBOOT_FAIL" - NODE_FAIL =r"\bNODE_FAIL" - PREEMPTED =r"\bPREEMPTED" - RESV_DEL_HOLD=r"\bRESV_DEL_HOLD" - REQUEUE_FED =r"\bREQUEUE_FED" - REQUEUE_HOLD =r"\bREQUEUE_HOLD" - REQUEUED =r"\bREQUEUED" - RESIZING =r"\bRESIZING" - REVOKED =r"\bREVOKED" - SIGNALING =r"\bSIGNALING" - SPECIAL_EXIT =r"\bSPECIAL_EXIT" - STAGE_OUT =r"\bSTAGE_OUT" - STOPPED =r"\bSTOPPED" - SUSPENDED =r"\bSUSPENDED" - - return context,[ - - ## No problem: greens - - #Job has terminated all processes on all nodes with an exit code of zero. - [r"\bCD\b", "22"], - [COMPLETED[0:col_width]+r"\w*\b", "22"], - #Job is awaiting resource allocation. - [r"\bPD\b", "28"], - [PENDING[0:col_width]+r"\w*\b", "28"], - #Job currently has an allocation. - [r"\bR\b", "34"], - [RUNNING[0:col_width]+r"\w*\b", "34"], - #Job has been allocated resources, but are waiting for them to become ready for use (e.g. booting). - [r"\bCF\b", "58"], - [CONFIGURING[0:col_width]+r"\w*\b", "58"], - #Job is in the process of completing. Some processes on some nodes may still be active. - [r"\bCG\b", "23"], - [COMPLETING[0:col_width]+r"\w*\b", "23"], - - ## Problem for the user: bold reds - - #Job terminated with non-zero exit code or other failure condition. - [r"\bF\b", "196"], - [FAILED[0:col_width]+r"\w*\b", "196", "bold"], - #Job terminated on deadline. - [r"\bDL\b", "160"], - [DEADLINE[0:col_width]+r"\w*\b", "160", "bold"], - #Job experienced out of memory error. - [r"\bOO\b", "197"], - [OUT_OF_MEMORY[0:col_width]+r"\w*\b", "197", "bold"], - #Job terminated upon reaching its time limit. - [r"\bTO\b", "161"], - [TIMEOUT[0:col_width]+r"\w*\b", "161", "bold"], - - ## Problem for the sysadmin: oranges - - #Job was explicitly cancelled by the user or system administrator. The job may or may not have been initiated. - [r"\bCA\b", "202"], - [CANCELLED[0:col_width]+r"\w*\b", "202", "bold"], - #Job terminated due to launch failure, typically due to a hardware failure (e.g. unable to boot the node or block and the job can not be requeued). - [r"\bBF\b", "166"], - [BOOT_FAIL[0:col_width]+r"\w*\b", "166"], - #Job terminated due to failure of one or more allocated nodes. - [r"\bNF\b", "208"], - [NODE_FAIL[0:col_width]+r"\w*\b", "208"], - - ## Non-blocking events: blues - - #Job terminated due to preemption. - [r"\bPR\b", "105"], - [PREEMPTED[0:col_width]+r"\w*\b", "105", "bold"], - #Job is being held after requested reservation was deleted. - [r"\bRD\b", "25"], - [RESV_DEL_HOLD[0:col_width]+r"\w*\b", "25"], - #Job is being requeued by a federation. - [r"\bRF\b", "26"], - [REQUEUE_FED[0:col_width]+r"\w*\b", "26"], - #Held job is being requeued. - [r"\bRH\b", "27"], - [REQUEUE_HOLD[0:col_width]+r"\w*\b", "27"], - #Completing job is being requeued. - [r"\bRQ\b", "31"], - [REQUEUED[0:col_width]+r"\w*\b", "31"], - #Job is about to change size. - [r"\bRS\b", "32"], - [RESIZING[0:col_width]+r"\w*\b", "32"], - #Sibling was removed from cluster due to other cluster starting the job. - [r"\bRV\b", "33"], - [REVOKED[0:col_width]+r"\w*\b", "33"], - #Job is being signaled. - [r"\bSI\b", "37"], - [SIGNALING[0:col_width]+r"\w*\b", "37"], - #The job was requeued in a special state. This state can be set by users, typically in EpilogSlurmctld, if the job has terminated with a particular exit value. - [r"\bSE\b", "38"], - [SPECIAL_EXIT[0:col_width]+r"\w*\b", "38"], - #Job is staging out files. - [r"\bSO\b", "39"], - [STAGE_OUT[0:col_width]+r"\w*\b", "39"], - #Job has an allocation, but execution has been stopped with SIGSTOP signal. CPUS have been retained by this job. - [r"\bST\b", "44"], - [STOPPED[0:col_width]+r"\w*\b", "44"], - #Job has an allocation, but execution has been suspended and CPUs have been released for other jobs. - [r"\bS\b", "45"], - [SUSPENDED[0:col_width]+r"\w*\b", "45"], - ] diff --git a/colout/colout_valgrind.py b/colout/colout_valgrind.py deleted file mode 100644 index 7fc33a2..0000000 --- a/colout/colout_valgrind.py +++ /dev/null @@ -1,33 +0,0 @@ -#encoding: utf-8 - -def theme(context): - - return context, [ - # section title - [r"^(==[0-9]+==\s{1})(Memcheck|Copyright|Using)(.*)$","blue",""], - [r"^(==[0-9]+==\s{1})(Warning)(.*)$","magenta",""], - [r"^(==[0-9]+==\s{1}Command: )(\S*)(.*)$","green,white","normal,bold,normal"], - [r"^(==[0-9]+==\s{1})(HEAP SUMMARY:)(.*)$","green",""], - [r"^(==[0-9]+==\s{1})(All heap blocks were freed)(.*)$","green",""], - [r"^(==[0-9]+==\s{1})(.*[rR]erun.*)$","blue",""], - [r"^(==[0-9]+==\s{1})(Use --.*)$","blue",""], - [r"^(==[0-9]+==\s{1}\S+.*)$","red",""], - # section explanation - [r"^==[0-9]+==\s{2}(\S+.*)$","orange",""], - # locations adresses - [r"^==[0-9]+==\s{4}([atby]{2}) (0x0): (\?{3})", - "blue,yellow,red", "normal,normal,bold"], - [r"^==[0-9]+==\s{4}([atby]{2}) (0x)([^:]*:) (\S+)", - "blue,blue,blue,none", "normal"], - # locations: library - [r"\(in (.*)\)", "cyan", "normal"], - # locations: file - [r"\(([^\.]*\.[^:]+):([0-9]+)\)", "white,yellow", "bold,normal"], - # leak summary - [r"^==[0-9]+==\s{4}(definitely lost): .* (in) .*","red","bold"], - [r"^==[0-9]+==\s{4}(indirectly lost): .* (in) .*","orange","bold"], - [r"^==[0-9]+==\s{6}(possibly lost): .* (in) .*","yellow","bold"], - [r"^==[0-9]+==\s{4}(still reachable): .* (in) .*","green","bold"], - [r"^==[0-9]+==\s{9}(suppressed): .* (in) .*","cyan","bold"], - ] - diff --git a/colout/colout_vivado.py b/colout/colout_vivado.py deleted file mode 100644 index aa74216..0000000 --- a/colout/colout_vivado.py +++ /dev/null @@ -1,26 +0,0 @@ - -def theme(context): - # Theme for coloring AMD/Xilinx Vivado IDE synthesis and implementation output - return context,[ - [ r"^\s*\*+.+$", "green" ], - [ "^#.+", "green" ], - - [ "^.+ Checksum: .+$", "green" ], - - [ r"^.+Time \(s\).+", "green" ], - [ r"^Time \(s\).+", "green" ], - - [ r"Estimated Timing Summary \|.+\|.+\|", "cyan", "bold" ], - [ r"Intermediate Timing Summary \|.+\|.+\|", "cyan", "bold" ], - - [ "^INFO:", "white", "bold" ], - [ "^WARNING:.+$", "yellow" ], - [ "^CRITICAL WARNING:.+$", "red" ], - [ "^ERROR:.+$", "red" ], - - [ "^Phase [0-9]+.[0-9]+.[0-9]+.[0-9]+.+$", "magenta", "bold" ], - [ "^Phase [0-9]+.[0-9]+.[0-9]+.+$", "magenta", "bold" ], - [ "^Phase [0-9]+.[0-9]+.+$", "magenta", "bold" ], - [ "^Phase [0-9]+.+$", "magenta", "bold" ] - ] - diff --git a/colout/example.gdbinit b/colout/example.gdbinit deleted file mode 100644 index e4c3116..0000000 --- a/colout/example.gdbinit +++ /dev/null @@ -1,104 +0,0 @@ - -# Don't wrap line or the coloring regexp won't work. -set width 0 - -# Create a named pipe to get outputs from gdb -shell test -e /tmp/coloutPipe && rm /tmp/coloutPipe -shell mkfifo /tmp/coloutPipe - -# A yellow prompt -set prompt \033[0;33mgdb>>>\033[0m - -define logging_on - # Instead of printing on stdout only, log everything... - set logging redirect on - # ... in our named pipe. - set logging on /tmp/coloutPipe -end - -define logging_off - set logging off - set logging redirect off - # Because both gdb and our commands are writing on the same pipe at the same - # time, it is more than probable that gdb will end before our (higher level) - # commands. The gdb prompt will thus render before the result of the command, - # which is highly akward. To prevent this, we need to wait before displaying - # the prompt again. The more your commands are complex, the higher you will - # need to set this. - shell sleep 0.4s -end - - -define hook-break - # Don't forget to run the command in the background - shell cat /tmp/coloutPipe | colout "(Breakpoint) ([0-9]+) at (0x\S+): file (.+/)([^/]+), line ([0-9]+)." blue,red,cyan,none,white,yellow normal,bold,normal,normal,bold,normal & - # You should start to consume the pipe before actually redirecting the command output into it. - logging_on -end -define hookpost-break - logging_off -end - - -define hook-run - shell cat /tmp/coloutPipe | colout "^(Breakpoint) ([0-9]+),*\s+(0x\S+ )*(in )*(\S+) (\(.*\)) at (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,none,green,cpp,none,white,white,yellow normal,bold,normal,normal,bold,normal,normal,bold,bold,bold | colout "^(Starting program): (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" green,none,white,white,yellow normal,normal,bold,bold,bold | colout "^[0-9]+\s+(.*)$" Cpp & - logging_on -end -define hookpost-run - logging_off -end - - -define hook-continue - shell cat /tmp/coloutPipe | colout "^(Program received signal )(.*)(,.*)$" yellow,red,yellow bold | colout "^(Breakpoint) ([0-9]+),*\s+(0x\S+ )*(in )*(\S+) (\(.*\)) at (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,none,green,cpp,none,white,white,yellow normal,bold,normal,normal,bold,normal,normal,bold,bold,bold | colout "^[0-9]+\s+(.*)$" Cpp & - logging_on -end -define hookpost-continue - logging_off -end - - -# Full syntax highlighting for the `list` command. -define hook-list - shell cat /tmp/coloutPipe | colout --all --source Cpp & - logging_on -end -# Don't forget the hookpost- or next coloring commands will fail. -define hookpost-list - logging_off -end - - -define hook-backtrace - # match the [path]file[.ext]: (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)) - shell cat /tmp/coloutPipe | colout "^(#)([0-9]+)\s+(0x\S+ )*(in )*(\S+) (\(.*\)) at (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,none,green,cpp,none,white,white,yellow normal,bold,normal,normal,bold,normal,normal,bold,bold,bold & - logging_on -end -define hookpost-backtrace - logging_off -end - - -define info hook-breakpoints - shell cat /tmp/coloutPipe | colout "^([0-9]+)" red bold | colout "\sy\s" green | colout "\sn\s" red | colout "breakpoint" green normal | colout "watchpoint" orange normal | colout "\s0x\S+\s" blue normal | colout "(.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)$" none,white,white,yellow normal,bold & - logging_on -end -define info hookpost-breakpoints - logging_off -end - - -define info hook-line - shell cat /tmp/coloutPipe | colout "^Line ([0-9]+) of \"(.*/)?(?:$|(.+?)(?:(\.[^.]*)|))\"" yellow,none,white,white bold | colout "(0x\S+) <(\S+)\+([0-9]+)>" blue,green,blue normal & - logging_on -end -define info hookpost-line - logging_off -end - - -# Don't forget to clean the adhoc pipe. -define hook-quit - shell rm -f /tmp/coloutPipe -end - diff --git a/colout_logo.svg b/colout_logo.svg deleted file mode 100644 index 8db7984..0000000 --- a/colout_logo.svg +++ /dev/null @@ -1,612 +0,0 @@ - - - - - colout logo - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - colout logo - 2022-08-31 - - - nojhan - - - - - - diff --git a/example.gdbinit b/example.gdbinit deleted file mode 100644 index b40a960..0000000 --- a/example.gdbinit +++ /dev/null @@ -1,132 +0,0 @@ - -set confirm off - -# Reversed yellow >>>, underlined green frame name, yellow »»» -set extended-prompt \[\e[7;33m\]>>>\[\e[0m\]\[\] \[\e[4;32m\]\f\[\e[0m\]\[\]\[\e[0;33m\] \n»»» \[\e[0m\] - - -# Don't wrap line or the coloring regexp won't work. -set width 0 - -# Create a named pipe to get outputs from gdb -shell test -e /tmp/coloutPipe && rm /tmp/coloutPipe -shell mkfifo /tmp/coloutPipe - -define logging_on - # Instead of printing on stdout only, log everything... - set logging redirect on - # ... in our named pipe. - set logging on /tmp/coloutPipe -end - -define logging_off - set logging off - set logging redirect off - # Because both gdb and our commands are writing on the same pipe at the same - # time, it is more than probable that gdb will end before our (higher level) - # commands. The gdb prompt will thus render before the result of the command, - # which is highly akward. To prevent this, we need to wait before displaying - # the prompt again. The more your commands are complex, the higher you will - # need to set this. - shell sleep 0.4s -end - - -define hook-break - # Don't forget to run the command in the background - shell cat /tmp/coloutPipe | colout "(Breakpoint) ([0-9]+) at (0x\S+): file (.+/)([^/]+), line ([0-9]+)." blue,red,cyan,none,white,yellow normal,bold,normal,normal,bold,normal & - # You should start to consume the pipe before actually redirecting the command output into it. - logging_on -end -define hookpost-break - logging_off -end - - -define hook-run - shell cat /tmp/coloutPipe | colout "^(Program received signal )(.+), (.+).$" yellow,red,yellow normal,bold | colout "^(Breakpoint) ([0-9]+),*\s+(0x\S+ )*(in )*(\S+) (\(.*\)) at (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,none,green,cpp,none,white,white,yellow normal,bold,normal,normal,bold,normal,normal,bold,bold,bold | colout "^(Starting program): (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" green,none,white,white,yellow normal,normal,bold,bold,bold | colout "^[0-9]+\s+(.*)$" Cpp & - logging_on -end -define hookpost-run - logging_off -end - - -define hook-continue - shell cat /tmp/coloutPipe | colout "^(Program received signal )(.*)(,.*)$" yellow,red,yellow bold | colout "^(Breakpoint) ([0-9]+),*\s+(0x\S+ )*(in )*(\S+) (\(.*\)) at (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,none,green,cpp,none,white,white,yellow normal,bold,normal,normal,bold,normal,normal,bold,bold,bold | colout "^[0-9]+\s+(.*)$" Cpp & - logging_on -end -define hookpost-continue - logging_off -end - - -# Full syntax highlighting for the `list` command. -define hook-list - #shell cat /tmp/coloutPipe | colout --all --source cpp & - shell cat /tmp/coloutPipe | colout "^([0-9]+)\s*(.*)$" red,Cpp & - logging_on -end -# Don't forget the hookpost- or next coloring commands will fail. -define hookpost-list - logging_off -end - - -define hook-backtrace - # Note: match path = [path]file[.ext] = (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)) - # This line color highlights: - # – lines that link to source code, - # – function call in green, - # – arguments names in yellow, values in magenta, - # — the parent directory in bold red (assuming that the debug session would be in a "project/build/" directory). - shell cat /tmp/coloutPipe | colout "^(#)([0-9]+)\s+(0x\S+ )*(in )*(.*) (\(.*\)) (at) (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,red,green,magenta,red,none,white,white,yellow normal,bold,normal,normal,normal,normal,normal,bold,bold,bold | colout "([\w\s]*?)(=)([^,]*?)([,\)])" yellow,blue,magenta,blue normal | colout "/($(basename $(dirname $(pwd))))/" red bold & - logging_on -end -define hookpost-backtrace - logging_off -end - - -define info hook-breakpoints - shell cat /tmp/coloutPipe | colout "^([0-9]+)" red bold | colout "\sy\s" green | colout "\sn\s" red | colout "breakpoint" green normal | colout "watchpoint" orange normal | colout "\s0x\S+\s" blue normal | colout "(.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)$" none,white,white,yellow normal,bold & - logging_on -end -define info hookpost-breakpoints - logging_off -end - - -define info hook-line - shell cat /tmp/coloutPipe | colout "^Line ([0-9]+) of \"(.*/)?(?:$|(.+?)(?:(\.[^.]*)|))\"" yellow,none,white,white bold | colout "(0x\S+) <(\S+)\+([0-9]+)>" blue,green,blue normal & - logging_on -end -define info hookpost-line - logging_off -end - - -define hook-frame - #shell cat /tmp/coloutPipe | colout "^(#)([0-9]+)\s+(0x\S+ )*(in )*(.*) (at) (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,red,green,red,magenta,none,white,white,yellow normal,bold,normal,normal,bold,normal,normal,bold,bold,bold | colout "^([0-9]+)\s+(.*)$" yellow,Cpp & - shell cat /tmp/coloutPipe | colout "^(#)([0-9]+)\s+(0x\S+ )*(in )*(.*) (\(.*\)) (at) (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,red,green,magenta,red,none,white,white,yellow normal,bold,normal,normal,normal,normal,normal,bold,bold,bold | colout "([\w\s]*?)(=)([^,]*?)([,\)])" yellow,blue,magenta,blue normal & - logging_on -end -define hookpost-frame - logging_off -end - -# Don't forget to clean the adhoc pipe. -define hook-quit - set confirm off - shell rm -f /tmp/coloutPipe -end - -define hook-display - shell cat /tmp/coloutPipe | colout "^([0-9]+)(:) (.+?) (=) " red,blue,white,blue normal,normal,bold,normal | colout "(@)(0x\S+)(:)" red,blue,red normal & - logging_on -end -define hookpost-display - logging_off -end - - diff --git a/requirements-build.txt b/requirements-build.txt deleted file mode 100644 index d50412d..0000000 --- a/requirements-build.txt +++ /dev/null @@ -1,3 +0,0 @@ -tox -tox-wheel -twine diff --git a/setup.py b/setup.py index 6bf5211..2ad8b72 100644 --- a/setup.py +++ b/setup.py @@ -3,57 +3,35 @@ import os import sys +import colout + try: from setuptools import setup except ImportError: from distutils.core import setup if sys.argv[-1] == 'publish': - os.system('python setup.py bdist_wheel --universal upload') + os.system('python3 setup.py sdist upload') sys.exit() packages = ['colout'] -requires = ['pygments', 'babel'] - -setup_requires = ['setuptools_scm'] - -classifiers = """ -Environment :: Console -Development Status :: 5 - Production/Stable -License :: OSI Approved :: GNU General Public License v3 (GPLv3) -Operating System :: POSIX -Operating System :: POSIX :: Linux -Programming Language :: Python :: 3 -Programming Language :: Python :: 3.5 -Programming Language :: Python :: 3.6 -Programming Language :: Python :: 3.7 -Programming Language :: Python :: 3.8 -Topic :: Utilities -Topic :: Text Processing -Topic :: Text Processing :: Filters -""".strip().split('\n') +requires = ['argparse', 'pygments', 'babel'] setup( name='colout', - use_scm_version=True, - classifiers=classifiers, - description='Color Up Arbitrary Command Output.', - entry_points={ - 'console_scripts': ['colout=colout.colout:main'], - }, - long_description=open(os.path.join(os.path.dirname(__file__), 'README.md')).read(), - long_description_content_type='text/markdown;variant=CommonMark', + version='0.1', + description='Color Up Arbitrary Command Ouput.', + long_description=open('README.md').read(), author='nojhan', author_email='nojhan@nojhan.net', url='http://nojhan.github.com/colout/', packages=packages, - package_data={'': ['LICENSE', 'README.md']}, + package_data={'': ['LICENSE']}, package_dir={'colout': 'colout'}, - python_requires='>=3.5', - setup_requires=setup_requires, + scripts=['bin/colout'], include_package_data=True, install_requires=requires, - license='GPLv3', + license=open('LICENSE').read(), zip_safe=False, ) diff --git a/tox.ini b/tox.ini deleted file mode 100644 index ff4e1ca..0000000 --- a/tox.ini +++ /dev/null @@ -1,15 +0,0 @@ -[tox] -envlist=py35,py36,py37,py38,cov - -[testenv] -wheel = true -deps= - pytest - pytest-cov - pytest-xdist -setenv= - py{35,36,37,38}: COVERAGE_FILE=.coverage.{envname} -commands= - py{35,36,37,38}: python -m pytest --cov=colout --cov-report=term-missing --no-cov-on-fail - cov: coverage combine - cov: coverage html --fail-under=85