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/AUTHORS b/AUTHORS new file mode 100644 index 0000000..63be891 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,6 @@ +Colout is written by nojhan and maintained by Dongweiming: + +Writer +`````` + +- Nojhan \ No newline at end of file diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..8fbff91 --- /dev/null +++ b/CHANGES @@ -0,0 +1,4 @@ +Version 0.1 +----------- + +Released on May 5th 2013, First public preview release. \ No newline at end of file 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/PKG-INFO b/PKG-INFO new file mode 100644 index 0000000..26455a4 --- /dev/null +++ b/PKG-INFO @@ -0,0 +1,195 @@ +Metadata-Version: 1.1 +Name: Colout +Version: 0.1 +Summary: Color text streams with this simple command +Home-page: http://nojhan.github.com/colout/ +Author: Nojhan +Author-email: nojhan@nojhan.net +License: GPL3 +Description: + Colout + ----- + + Colout is Color text streams with this simple commandinja 2 and good + intentions. And before you ask: It's BSD licensed! + + SYNOPSIS + ```````````` + + ``colout`` [-h][-e] [-g][-t] [-s][-l] PATTERN [COLOR(S)][STYLE(S)] + + DESCRIPTION + ````````````````` + + ``colout`` read lines of text stream on the standard input and output + characters 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. + + You can specify severall colors or styles when using groups by + separating them with commas. If you indicate more colors than groups, + the last ones will be ignored. If you ask for less colors, the last one + will be duplicated across remaining groups. + + Available colors are: blue, black, yellow, cyan, green, magenta, white, + red, rainbow, random, Random, scale, none or any number between 0 and + 255. + + Available styles are: normal, bold, faint, italic, underline, blink, + rapid\_blink, reverse, conceal or random. + + ``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. + + rainbow\` will cycle over a 8 colors rainbow at each matching pattern. + + ``scale`` will parse the matching text as a decimal number and apply the + rainbow colormap according to its position on a scale defined by the + ``-l`` option (see below, [0-100] by default). + + When not specified, a *COLOR* defaults to *red* and a *STYLE* defaults + to *bold*. + + ``colout`` comes with some predefined themes to rapidely color + well-known outputs (see the ``-t`` switch below). + + If the python-pygments library is available, ``colout`` can be used as + an interface to it (see also the ``-s`` switch below). + + ``colout`` is released under the GNU Public License v3. + + OPTIONS + ``````` + + - ``-h``, ``--help``: Show an help message and exit + + - ``-g``, ``--groups``: For color maps (like "rainbow"), iterate over + matching groups in the pattern instead of over patterns. + + - ``-c``, ``--colormap``: Use the given list of comma-separated colors + as a colormap (cycle the colors at each match). + + - ``-l``, ``--scale``: 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 + (SCALE=0,100, by default). + + - ``-a``, ``--all``: Color the whole input at once instead of line per + line (really useful for coloring a source code file with strings on + multiple lines). + + - ``-t``, ``--theme``: Interpret PATTERN as a predefined theme (perm, + cmake, g++, etc.) + + - ``-s``, ``--source``: Interpret PATTERN 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. + In 256 colors, interpret COLOR as a Pygments style (e.g. "default"). + + + REGULAR EXPRESSIONS + ``````````````````` + + A regular expression (or *regex*) is a pattern that describes a set of + strings that matches it. + + ``colout`` understands regex as specifed in the *re* python module. + Given that ``colout`` is generally called by the command line, you may + have to escape special characters that would be recognize by your shell. + + DEPENDENCIES + ```````````` + + Recommended packages : + + - ``argparse`` for a usable arguments parsing + - ``pygments`` for the source code syntax coloring + - ``babel`` for a locale-aware number parsing + + EXAMPLES + ```````` + + - Color in bold red every occurence of the word *color* in colout + sources: ``cat colout.py | colout color red bold`` + + - Color in bold violet home directories in */etc/passwd*: + ``colout '/home/[a-z]+' 135 < /etc/passwd`` + + - Use a different color for each line of the auth log + ``grep user /var/log/auth.log | colout "^.*$" rainbow`` + + - 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: + ``ls -l | colout '.(r.-){3}' yellow normal`` + + - Color in green read permission, in bold red write and execution ones: + ``ls -l | colout '(r)(w*)(x*)' green,red normal,bold`` + + - Color permissions with a predefined template: + ``ls -l | colout -t perm`` + + - Color in green comments in colout sources: + ``colout '.*(#.*)$' green normal < colout.py`` + + - Color permissions with a predefined template: + ``ls -l | colout -t perm`` + + - Color in green comments in colout sources: + ``colout '.*(#.*)$' green normal < colout.py`` + + - Color in light green comments in non-empty colout sources, with the + sharp in bold green: + ``grep -v '^\s*$' colout.py | colout '.*(#)(.*)$' green,119 bold,normal`` + + - Color in bold green every numbers and in bold red the words *error* + in make output: + ``make 2>&1 | colout '[0-9]+' green normal | colout error`` + + - 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>&³ | 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 begining of the command + is just bash magic to repeat the string "(\\w+)\\W+": + ``L=$(seq 10) ; P=${L//??/(\\w+)\\W+} ; head /var/log/auth.log | colout -g "^${P}(.*)$" rainbow`` + + - Color each line of a file with a different color among a 256 color + gradient from cyan to green: + ``head /var/log/auth.log | colout -c "^.*$" 39,38,37,36,35,34`` + + - Color a source code in 8 colors mode, without seeing comments: + ``cat colout.py | grep -v "#" | colout -s python`` + + - Color a source code in 256 colors mode: + ``cat colout.py | colout -s Python monokai`` + + - Color a JSON stream: + ``echo '{"foo": "lorem", "bar":"ipsum"}' | python -mjson.tool | colout -t json`` + + - Color a source code substring: + ``echo "There is an error in 'static void Functor::operator()( EOT& indiv ) { return indiv; }' you should fix it" | colout "'(.*)'" Cpp monokai`` + + + + +Platform: any +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Console +Classifier: Intended Audience :: End Users/Desktop +Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3) +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.5 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Text Processing +Classifier: Topic :: Utilities +Classifier: Topic :: Software Development :: Libraries :: Python Modules \ No newline at end of file diff --git a/README b/README new file mode 100644 index 0000000..7a5a505 --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +Colout +----- + +This is the [colout](http://nojhan.github.com/colout/)'s pypi source diff --git a/README.md b/README.md deleted file mode 100644 index 10bde37..0000000 --- a/README.md +++ /dev/null @@ -1,397 +0,0 @@ -colout — Color Up Arbitrary Command Output -========================================== - -

-Colout logo -

- -## Synopsis - -`colout [-h] [-r [RESOURCE]]` - -`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 - -`colout` read lines of text stream on the standard input and output characters -matching a given regular expression *PATTERN* in given *COLOR* and *STYLE*. - -If groups are specified in the regular expression pattern, only them are taken -into account, else the whole matching pattern is colored. - -You can specify several colors or styles when using groups by separating them -with commas. If you indicate more colors than groups, the last ones will be ignored. -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. - -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 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 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 -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 GIMP palettes files (*.gpl) are available, you can also use their names as a -colormap (see the `-P` switch below). - -Note that the RGB colors (either the hex triplets or the palettes's colors) will -be converted to their nearest ANSI 256 color mode equivalents. - -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). - -To have a list of all colors, styles, special colormaps, themes, palettes and lexers, -use the `-r` switch (see below). - -`colout` is released under the GNU Public License v3. - - -## Installation - -The recomended method is using pip to install the package for the local user: - -```console -$ pip install --user colout -``` - -Another method is using [pipsi](https://github.com/mitsuhiko/pipsi) -(_pipsi is no longer maintained, _) -```console -$ pipsi install colout -``` - -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 -``` - -## Options - -* `-h`, `--help`: - Show a help message and exit - -* `-g`, `--groups`: - For color maps (like "rainbow"), iterate over matching groups in the pattern instead of over patterns. - -* `-c`, `--colormap`: - 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). - -* `-a`, `--all`: - Color the whole input at once instead of line per line - (really useful for coloring a source code file with strings on multiple lines). - -* `-t`, `--theme`: - Interpret PATTERN as a predefined theme (perm, cmake, g++, etc.). - -* `-T DIR`, `--themes-dir DIR`: - Search for additional themes (colout_*.py files) in this directory. - -* `-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. - -* `-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 - -A regular expression (or _regex_) is a pattern that describes a set of strings -that matches it. - -`colout` understands regex as specified in the _re_ python module. Given that -`colout` is generally called by the command line, you may have to escape -special characters that would be recognize by your shell. - - -## Dependencies - -Necessary Python modules: - -* `pygments` for the source code syntax coloring -* `babel` for a locale-aware number parsing - - -## Limitations - -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 - -### Simple - -* Color in bold red every occurrence of the word _color_ in colout sources: - `cat colout.py | colout color red bold` - -* 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`: - `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: - `ls -l | colout '.(r.-){3}' yellow normal` - -* Color in green read permission, in bold red write and execution ones: - `ls -l | colout '(r)(w*)(x*)' green,red normal,bold` - -* Color in green comments in colout sources: - `colout '.*(#.*)$' green normal < colout.py` - -* Color in bold green every numbers and in bold red the words _error_ in make output: - `make 2>&1 | colout '[0-9]+' green normal | colout error` - - -### Somewhat useful - -* Use a different color for each line of the auth log - `grep user /var/log/auth.log | colout "^.*$" rainbow` - -* Color each line of a file with a different color among a 256 color gradient from cyan to green: - `head /var/log/auth.log | colout -c "^.*$" 39,38,37,36,35,34` - -* Color permissions with a predefined template: - `ls -l | colout -t perm` - -* Color in light green comments in non-empty colout sources, with the sharp in bold green: - `grep -v '^\s*$' colout.py | colout '.*(#)(.*)$' green,119 bold,normal` - -* 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++` - -* 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+": - `L=$(seq 10) ; P=${L//??/(\\w+)\\W+} ; head /var/log/auth.log | colout -g "^${P}(.*)$" rainbow` - -* Color source code in 8 colors mode, without seeing comments: - `cat colout.py | grep -v "#" | colout -s python` - -* Color source code in 256 color mode: - `cat colout.py | colout -s Python monokai` - -* Color a JSON stream: - `echo '{"foo": "lorem", "bar":"ipsum"}' | python -mjson.tool | colout -t json` - -* Color a source code substring: - `echo "There is an error in 'static void Functor::operator()( EOT& indiv ) { return indiv; }' you should fix it" | colout "'(.*)'" Cpp monokai` - -* Color the percent of progress part of a CMake's makefile output, with a color - 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: - -```bash -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..aedc3eb --- /dev/null +++ b/bin/colout @@ -0,0 +1,11 @@ +#!/bin/bash +# Copyright @ 2013 Martin Ueding + +# Small launcher script for the main module. + +# Licence: GPL 3 + +set -e +set -u + +python -m colout.colout "$@" diff --git a/colout/colout.py b/colout/colout.py index 2d51fac..0ac5a39 100755 --- a/colout/colout.py +++ b/colout/colout.py @@ -1,219 +1,45 @@ #!/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 random +import os import glob import math -import pprint -import random -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 +########### +# Library # +########### # Available styles -context["styles"] = { +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 +colors = { + "black": 0, "red": 1, "green": 2, "yellow": 3, "blue": 4, + "magenta": 5, "cyan": 6, "white": 7, "none": -1 +} -# 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"] +ansi_min = 16 +ansi_max = 232 -# 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 +def rgb_rainbow( x, freq = 1.0/(256.0/math.pi) ): + scope = (ansi_max - ansi_min)/2.0 + red = ansi_min + scope * (1+math.sin( 2*freq*x + math.pi/2 )) + green = ansi_min + scope * (1+math.sin( 2*freq*x - math.pi/2 )) + blue = ansi_min + scope * (1+math.sin( freq*x - math.pi/2 )) + return ( red, green, blue ) -############################################################################### -# 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) - - Return the filename (without path and extension) and a list of ordered - colors. - Generally, the colors are RGB triplets, thus this function returns: - (name, [ [R0,G0,B0], [R1,G1,B1], ... , [RN,GN,BN] ]) - """ - - logging.debug("parse GIMP palette file: %s" % filename) - fd = open(filename) - # remove path and extension, only keep the file name itself - name = os.path.splitext( os.path.basename(filename ))[0] - - # The first .gpl line is a header - assert( fd.readline().strip() == "GIMP Palette" ) - - # Then the full name of the palette - long_name = fd.readline().strip() - - # Then the columns number. - # split on colon, take the second argument as an int - line = fd.readline() - if "Columns:" in line: - columns = int( line.strip().split(":")[1].strip() ) - lines = fd.readlines() - else: - columns=3 - lines = [line] + fd.readlines() - - # Then the colors themselves. - palette = [] - for line in lines: - # skip lines with only a comment - if re.match(r"^\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] ] - palette.append( colors ) - - logging.debug("parsed %i RGB colors from palette %s" % (len(palette), name) ) - return name,palette - - -def uniq( lst ): - """Build a list with uniques consecutive elements in the argument. - - >>> uniq([1,1,2,2,2,3]) - [1,2,3] - >>> uniq([0,1,1,2,3,3,3]) - [0,1,2,3] - """ - assert( len(lst) > 0 ) - uniq = [ lst[0] ] - for i in range(1,len(lst)): - if lst[i] != lst[i-1]: - uniq.append(lst[i]) - return uniq - - -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* - # limit RGB values to ansi_max - red,green,blue = tuple([ansi_max if c>ansi_max else c for c in (r,g,b)]) +def rgb_to_ansi( red, green, blue ): offset = 42.5 is_gray = True @@ -225,298 +51,55 @@ def rgb_to_ansi( r, g, b ): if all_gray: val = ansi_max + round( (red + green + blue)/33.0 ) - res = int(val) + return int(val) else: val = ansi_min for color,modulo in zip( [red, green, blue], [6*6, 6, 1] ): val += round(6.0 * (color / 256.0)) * modulo - res = int(val) - - return res + return int(val) -def hex_to_rgb(h): - assert( h[0] == "#" ) - h = h.lstrip('#') - lh = len(h) - return tuple( int(h[i:i+lh//3], 16) for i in range(0, lh, lh//3) ) +rainbow = ["magenta", "blue", "cyan", "green", "yellow", "red"] +colormap = rainbow # default colormap to rainbow +colormap_idx = 0 +scale = (0,100) -############################################################################### -# Load available extern resources -############################################################################### +# Escaped end markers for given color modes +endmarks = {8: ";", 256: ";38;5;"} -def load_themes( themes_dir): - global context - logging.debug("search for themes in: %s" % themes_dir) - sys.path.append( 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"]: - raise DuplicatedTheme(name) - logging.debug("load theme %s" % name) - context["themes"][name] = importlib.import_module(module) - - -def load_palettes( palettes_dir, ignore_duplicates = True ): - global context - logging.debug("search for palettes in: %s" % palettes_dir) - - # load available colormaps (GIMP palettes format) - for p in glob.iglob(os.path.join(palettes_dir, "*.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) - # 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 - - -def load_lexers(): - global context - # 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 +# load available themes +themes = {} +themes_dir=os.path.dirname(os.path.realpath(__file__)) +os.chdir( themes_dir ) +for f in glob.iglob("colout_*.py"): + module = ".".join(f.split(".")[:-1]) + name = "_".join(module.split("_")[1:]) + themes[name] = __import__(module) +# load available pygments lexers +lexers = [] +try: from pygments.lexers import get_all_lexers - try: - 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: - logging.warning("cannot load lexer: %s" % lexer[1][0]) - pass # Forget about this lexer. - 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 - - -def load_resources( themes_dir, palettes_dir ): - load_themes( themes_dir ) - load_palettes( palettes_dir ) - load_lexers() - - -############################################################################### -# 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: + from pygments.lexers import get_lexer_by_name + from pygments import highlight + from pygments.formatters import Terminal256Formatter + from pygments.formatters import TerminalFormatter +except ImportError: + pass +else: + for lexer in get_all_lexers(): 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] + "" + lexers.append(lexer[1][0]) + except IndexError: + pass + lexers.sort() -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. @@ -527,118 +110,125 @@ def colorin(text, color="red", style="normal", sep_pair=context["sep_pair"]): >>> colout.colorin("Faites chier la vache", 41, "normal") '\x1b[0;38;5;41mFaites chier la vache\x1b[0m' """ - - assert( type(color) is str ) - - global debug + global colormap_idx # 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 + return text + + 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 == "rainbow": + mode = 8 + color = colormap[colormap_idx] + color_code = str(30 + colors[color]) + + if colormap_idx < len(colormap)-1: + colormap_idx += 1 else: - return ""+text+"" + colormap_idx = 0 - elif color.lower() == "random": - color_code = color_random( color ) + elif color == "Rainbow": + mode = 256 + color_nb = rgb_to_ansi( *rgb_rainbow( colormap_idx ) ) + color_code = str( color_nb ) - elif color.lower() == "scale": # "scale" or "Scale" - color_code = color_scale( color, text ) + if colormap_idx < 255: + colormap_idx += 1 + else: + colormap_idx = 0 - # "hash" or "Hash"; useful to randomly but consistently color strings - elif color.lower() == "hash": - color_code = color_hash( color, text ) + elif color == "scale": + try: + import babel.numbers as bn + f = float(bn.parse_decimal(text)) + except ImportError: + f = float(text) + + # if out of scale, do not color + if f < scale[0] or f > scale[1]: + return text + + # normalize and scale over the nb of colors in colormap + i = int( math.ceil( (f - scale[0]) / (scale[1]-scale[0]) * (len(colormap)-1) ) ) + + mode = 8 + color = colormap[i] + color_code = str(30 + colors[color]) - # The user can change the "colormap" variable to its 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]) - - # hexadecimal color - elif color[0] == "#": - color_nb = rgb_to_ansi(*hex_to_rgb(color)) - assert(0 <= color_nb <= 255) - color_code = str(color_nb) + elif color in colors: + mode = 8 + color_code = str(30 + colors[color]) # 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. + return highlight(text, lexer, formatter)[:-1] # unrecognized else: - raise UnknownColor(color) + raise Exception('Unrecognized color %s' % 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 = "" - 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" + text + stop def colorout(text, match, prev_end, color="red", style="normal", group=0): @@ -654,7 +244,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,15 +253,22 @@ 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. + + >>> 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 context - global debug - - if not debug: - regex = re.compile(pattern) - else: - regex = re.compile(pattern, re.DEBUG) + global colormap_idx + regex = re.compile(pattern) # , re.IGNORECASE) # Prepare the colored text. colored_text = "" @@ -690,17 +287,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[), @@ -729,29 +326,20 @@ def colortheme(item, theme): Used to read themes, which can be something like: [ [ pattern, colors, styles ], [ pattern ], [ pattern, colors ] ] """ - # logging.debug("use a theme with %i arguments" % len(theme)) for args in theme: item = colorup(item, *args) return item -def write(colored, stream = sys.stdout): +def write(colored): """ Write "colored" on sys.stdout, then flush. """ - try: - stream.write(colored) - stream.flush() - - # Silently handle broken pipes - except IOError: - try: - stream.close() - except IOError: - pass + sys.stdout.write(colored) + sys.stdout.flush() -def map_write( stream_in, stream_out, function, *args ): +def map_write( stream, function, *args ): """ Read the given file-like object as a non-blocking stream and call the function on each item (line), @@ -764,17 +352,15 @@ def map_write( stream_in, stream_out, function, *args ): """ while True: try: - item = stream_in.readline() - except UnicodeDecodeError: - continue + item = stream.readline() except KeyboardInterrupt: break if not item: break - write( function(item, *args), stream_out ) + write( function(item, *args) ) -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 +376,72 @@ 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) + """ + import sys + + # 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 +452,27 @@ 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) + help="A number in [0…255], one of the available colors or a comma-separated list of values. \ + Available colors: "+", ".join(colors)+ \ + ". Available special colors: none, random, Random, rainbow, Rainbow, scale") parser.add_argument("style", metavar="STYLE", type=str, nargs='?', default="bold", - help="One of the available styles or a comma-separated list of styles.") + help="One of the available styles or a comma-separated list of styles.\ + Available styles: "+", ".join(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 \ @@ -839,257 +480,81 @@ def _args_parse(argv, usage=""): on multiple lines).") parser.add_argument("-t", "--theme", action="store_true", - 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") - - parser.add_argument("-P", "--palettes-dir", metavar="DIR", action="append", - help="Search for additional palettes (*.gpl files) in the given 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.") + help="Interpret REGEX as a theme. \ + Available themes: "+", ".join(themes.keys())) 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).") - - 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") + 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. \ + Available languages: "+", ".join(lexers)) 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.colormap, args.theme, args.source, args.all, args.scale -def write_all( as_all, stream_in, stream_out, function, *args ): +def stdin_write( as_all, function, *args ): """ If as_all, print function(*args) on the whole stream, else, print it for each line. """ if as_all: - write( function( stream_in.read(), *args ), stream_out ) + write( function( sys.stdin.read(), *args ) ) else: - map_write( stream_in, stream_out, function, *args ) - - -def main(): - global context - 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) - - if debug: - lvl = logging.DEBUG - else: - lvl = logging.ERROR - - logging.basicConfig(format='[colout] %(levelname)s: %(message)s', level=lvl) - - - ################## - # 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 - res_dir = os.path.dirname(os.path.realpath(__file__)) - - # this must be called before args parsing, because the help can list available resources - load_resources( res_dir, res_dir ) - - # try additional directories if asked - if palettes_dirs: - for adir in palettes_dirs: - if os.path.isdir(adir): - load_palettes( adir ) - else: - logging.warning("cannot read palettes directory %s, ignore it" % adir) - - if themes_dirs: - for adir in themes_dirs: - if os.path.isdir(adir): - load_themes( adir ) - else: - logging.warning("cannot read themes directory %s, ignore it" % 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"])] - - def join_sort( l ): - """ - Sort the given list in lexicographical order, - with upper-cases first, then lower cases - join the list with a comma. - - >>> join_sort(["a","B","A","b"]) - 'A, a, B, b' - """ - return ", ".join(sorted(l, key=lambda s: s.lower()+s)) - - # 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"] ) - - sys.exit(0) # not an error, we asked for help - - ############ - # Coloring # - ############ - - 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"]) - - # 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 - 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"]) ) - - # 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 ) - - # 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"]) - lexer = get_lexer_by_name(pattern.lower()) - # Python => 256 colors, python => 8 colors - ask_256 = pattern[0].isupper() - if ask_256: - logging.debug("256 colors mode") - try: - formatter = Terminal256Formatter(style=color) - except: # style not found - logging.warning("style %s not found, fallback to default style" % color) - formatter = Terminal256Formatter() - else: - logging.debug("8 colors mode") - formatter = TerminalFormatter() - - write_all( as_all, sys.stdin, sys.stdout, highlight, lexer, formatter ) - - # if color - else: - write_all( as_all, sys.stdin, sys.stdout, colorup, pattern, color, style, on_groups, context["sep_list"] ) - - 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 ) - 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"] ) + map_write( sys.stdin, function, *args ) if __name__ == "__main__": - main() + import sys + + usage = "A regular expression based formatter that color up an arbitrary text stream." + + 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 \ + = __args_parse__(sys.argv, usage) + + if myscale: + scale = map(int,myscale.split(",")) + + # 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 + + # if theme + if as_theme: + assert(pattern in themes.keys()) + stdin_write( as_all, colortheme, themes[pattern].theme() ) + + # if pygments + elif as_source: + assert(pattern.lower() in lexers) + lexer = get_lexer_by_name(pattern.lower()) + # Python => 256 colors, python => 8 colors + ask_256 = pattern[0].isupper() + if ask_256: + try: + formatter = Terminal256Formatter(style=color) + except: # style not found + formatter = Terminal256Formatter() + else: + formatter = TerminalFormatter() + + stdin_write( as_all, highlight, lexer, formatter ) + + # if color + else: + stdin_write( as_all, colorup, pattern, color, style, on_groups ) + 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..2752a22 100644 --- a/colout/colout_cmake.py +++ b/colout/colout_cmake.py @@ -1,20 +1,12 @@ -def theme(context): +def theme(): # CMake theme: # actions performing in cyan performing="cyan" # actions performed in green performed="green" - # 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 +17,23 @@ 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) (.*)$", - untimed, "normal,normal,bold" ], - # [percent] Creating something - [ r"^\[\s*[0-9/]+%?\]\s(.*Creating.*)$", - performing, "normal" ], + # Link + [ "^(Linking .* (library|executable) )(.*/)+(.+(\.[aso]+)*)$", + performing, "normal,normal,bold" ], # [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"], - # [percent] Generating - [ r"^\[\s*[0-9/]+%?\]\s(Generating)(\s+.*)$", - performing, "normal,bold"], + [ "^\[\s*[0-9]+%\]\s(Building \w* object)(\s.*/)(\w+.c.*)(.o)$", + performing, "normal,normal,bold,normal"], # 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..d10e320 100644 --- a/colout/colout_g++.py +++ b/colout/colout_g++.py @@ -3,13 +3,11 @@ def default_gettext( msg ): return msg -def theme(context): +def theme(): import os import gettext import locale - section="blue" - # get g++ version gv = os.popen("g++ -dumpversion").read().strip() @@ -26,47 +24,26 @@ def theme(context): enc = locale.getpreferredencoding() if "UTF" in enc: # gcc will use unicode quotes - qo = "[‘`]" - qc = "[’']" + qo = "‘" + qc = "’" else: # rather than ascii ones - qo = "['`]" + 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" ], + [ _("note: "), "blue", "bold" ], # [-Wflag] - [ r"\[-W.*\]", "magenta"], + [ "\[-W.*\]", "magenta"], # Highlight message start: # path file ext : line : col … [ "(/.*?)/([^/:]+): (In .*)"+qo, - section, + "green", "normal,normal,bold" ], - [ "(/.*?)/([^/:]+): (At .*)", - section, - "normal,normal,bold" ], - - [ _("In file included from"), section ], - # Highlight locations: # path file ext : line : col … [ "(/.*?)/([^/:]+):([0-9]+):*([0-9]*)(.*)", @@ -74,12 +51,6 @@ def theme(context): "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" ] + [ qo+"(.*?)"+qc, "Cpp", "monokai" ] ] 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..724362f 100644 --- a/colout/colout_json.py +++ b/colout/colout_json.py @@ -1,13 +1,8 @@ -def theme(context): - # 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' ], - [ '" (:) ', "yellow" ], - [ r'[\]}"](,)', "yellow" ], - [ r"\"(-*[0-9]+\.*[0-9]*e*-*[0-9]*)\"", "blue" ], - [ '"(.*)"', "green" ], - [ """["']""", "cyan" ] +def theme(): + return [ + [ '[][{}]' ], + [ '[:,]', "blue" ], + [ '".*"', "green" ] ] 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/jet72.gpl b/colout/jet72.gpl deleted file mode 100644 index ac69f16..0000000 --- a/colout/jet72.gpl +++ /dev/null @@ -1,77 +0,0 @@ -GIMP Palette -Name: MATLAB Jet (72) -Columns: 3 -# - 0 0 127 0 - 0 0 127 #1 - 0 0 141 #2 - 0 0 155 #3 - 0 0 169 #4 - 0 0 183 #5 - 0 0 198 #6 - 0 0 212 #7 - 0 0 226 #8 - 0 0 240 #9 - 0 0 255 #10 - 0 14 255 #11 - 0 28 255 #12 - 0 42 255 #13 - 0 56 255 #14 - 0 70 255 #15 - 0 84 255 #16 - 0 98 255 #17 - 0 112 255 #18 - 0 127 255 #19 - 0 141 255 #20 - 0 155 255 #21 - 0 169 255 #22 - 0 183 255 #23 - 0 198 255 #24 - 0 212 255 #25 - 0 226 255 #26 - 0 240 255 #27 - 0 255 255 #28 - 14 255 240 #29 - 28 255 226 #30 - 42 255 212 #31 - 56 255 198 #32 - 70 255 183 #33 - 84 255 169 #34 - 98 255 155 #35 -112 255 141 #36 -127 255 127 #37 -141 255 112 #38 -155 255 98 #39 -169 255 84 #40 -183 255 70 #41 -198 255 56 #42 -212 255 42 #43 -226 255 28 #44 -240 255 14 #45 -255 255 0 #46 -255 240 0 #47 -255 226 0 #48 -255 212 0 #49 -255 198 0 #50 -255 183 0 #51 -255 169 0 #52 -255 155 0 #53 -255 141 0 #54 -255 127 0 #55 -255 112 0 #56 -255 98 0 #57 -255 84 0 #58 -255 70 0 #59 -255 56 0 #60 -255 42 0 #61 -255 28 0 #62 -255 14 0 #63 -255 0 0 #64 -240 0 0 #65 -226 0 0 #66 -212 0 0 #67 -198 0 0 #68 -183 0 0 #69 -169 0 0 #70 -155 0 0 #71 -141 0 0 #72 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/run-tests.py b/run-tests.py new file mode 100644 index 0000000..e69de29 diff --git a/setup.py b/setup.py index 6bf5211..cd9b398 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python +#coding=utf-8 import os import sys @@ -9,51 +10,45 @@ 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'] +requires = ['argparse', 'pygments', 'babel'] -setup_requires = ['setuptools_scm'] - -classifiers = """ +classifiers = """\ +Development Status :: 4 - Beta Environment :: Console -Development Status :: 5 - Production/Stable +Intended Audience :: End Users/Desktop License :: OSI Approved :: GNU General Public License v3 (GPLv3) -Operating System :: POSIX -Operating System :: POSIX :: Linux +Operating System :: OS Independent +Programming Language :: Python +Programming Language :: Python :: 2.5 +Programming Language :: Python :: 2.6 +Programming Language :: Python :: 2.7 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') +Topic :: Utilities +Topic :: Software Development :: Libraries :: Python Modules +""" 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', - author='nojhan', + version='0.1', + description='Color Up Arbitrary Command Ouput.', + long_description=open('README').read(), + author='Nojhan', author_email='nojhan@nojhan.net', url='http://nojhan.github.com/colout/', + download_url = 'https://pypi.python.org/packages/source/c/colout/colout-0.1.tar.gz', 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="GPL-3", + classifiers = filter(None, classifiers.split("\n")), 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