Generic Coloriser
Project description
Generic Colorizer
grc allows you to colorize (even transform) shell output.
WARNING - Pending Project Rename
In order to make roon on pypi for the original grc project, this project will be renamed to strec soon. The new name was chosen to be very different from grc to show that it’s a different project. While both do the same, they do it in a very different manner, and more importantly, the config format is different.
Alternatives
The original grc
Available at http://kassiopeia.juls.savba.sk/~garabik/software/grc.html
While the original grc is a bit smarter with subprocesses, this rewrite focuses on ease of use (including Installation, Configuration and source-code access).
Installation should also honour the Linux FHS
sed or awk
sed and awk are extremely powerful tools, and can certainly do what grc does. They will certainly perform better on large streams. It’s their intended use afterall. However, they both use an archaic and arcane syntax for their scripts. Additionally, if you would like to colorize your output with these, you need to work with ANSI escape sequences. grc aims to simplify this by having a more readable Configuration syntax, and by hiding the ANSI escape sequences.
See the installation document for more information.
Usage
Read lines from stdin and emit modified/colorized lines on stdout
Synopsis
<some_process> | grc -c <config>
Example
tail -f /var/log/apache2/access.log | grc -c apache_access
- Advantages
Only the stream you are sending to grc is affected.
No known side-effects
- Disadvantages
As grc only sees a stream, it cannot determine what application is emitting the stream. You have to specify the config manually.
Spawn a subprocess, capture it’s output
Synopsis
grc <some_procss>
Example
grc aptitude search python
- Advantages
Much less to type
Can auto-detect the config by using the sub-process application name.
- Disadvantages
Spawning a subprocess and interacting with it’s IO is non-trivial on a TTY/PTY. To simplify the code, grc uses pexpect to do the IO magic.
stdout and stderr of the subprocess are combined into one stream, which is then emitten on grc’s stdout. [1]
The output may not use all of the available terminal width. [1]
Configuration
grc searches three locations for configuration files in order:
~/.grc/conf.d/<confname>.yml
/etc/grc/conf.d/<confname>.yml
/usr/share/grc/conf.d/<confname>.yml
The first matching config file wins. This means, you can override any system-wide configs with your own concoctions.
Syntax
grc uses YAML as config syntax. Comparing to .ini and json files (both included in the Python stdlib), this syntax lends itself much better to the requirements of this application.
Basic structure
The config file is separated into sections (contexts). It has to have at least the root context.
Each context has a list of rules. These rules fire if a line contains a given regular expresssion. The first matching rule wins.
The line will then be replaced with the string contained in the replace value. You can use back-refs if you used capture groups in your regular expressions. Colours can be insterted using ${t.color_name}. You should always insert a ${t.normal} after using a color, to reset to the terminal default. The colors are provided by the package blessings. The t variable is a reference to a blessings terminal instance so you should be able to use it as it is documented on the blessings homepage.
Rules may define, that processing should not stop using the continue: yes flag. In that case, the same line will be matched with the following rule as well.
Additionally, rules may “push” another context onto the stack. If that’s the case, the rule will be processed, and all following lines will be matched against rules contained in the context named by the push value.
If in a non-root context, a rule may “pop” the current context from the stack using the pop: yes action.
See Config Reference for more details.
Annotated Example
# the primary context. This section must exist! root: - match: '^(running)(.*)' # demonstrating replacements /and/ colorizing replace: '*** ${t.green}\1${t.normal}\2' - match: '^(writing)(.*)' replace: '>>> ${t.yellow}\1${t.normal}\2' - match: '^(reading)(.*)' replace: '<<< ${t.blue}\1${t.normal}\2' - match: '^(Processing dependencies for)(.*)' replace: '${t.green}\1${t.normal}\2' # switch to the "dependencies" context push: dependencies - match: '^(Installing.*)' replace: '>>> ${t.green}\1${t.normal}' # the "dependencies" context dependencies: - match: '^(Finished processing dependencies for)(.*)' replace: '${t.green}\1${t.normal}\2' # Revert back to the "root" context pop: yes - match: '^(Searching for )(.*)$' replace: '\1${t.blue}\2${t.normal}' # switch to the "dependency" context push: dependency # the "dependency" context dependency: # Let's prepend all lines with a small indent and pipe. # To do this, we specify a "match-all" regex, replace the line, and # specify that we will continue with the next matching rule using # "continue" - match: '(.*)' replace: ' | \1' continue: yes # Note that after the above rule, all lines are prepended with # additional text. We need to include this in the regex! - match: '^ \| (Installing.*)' replace: ' | >>> ${t.green}\1${t.normal}' - match: '^ \| (Running.*)' replace: ' | ${t.green}\1${t.normal}' - match: '^ \| (Best match.*)' replace: ' | ${t.green}\1${t.normal}' - match: '^ \| (WARNING|warning)' replace: ' | ${t.yellow}\1${t.normal}' - match: '^ \| Installed(.*)' replace: ' | Installed\1\n' pop: yes
Config Reference
Main Level
- root
Specifies the primary context
All other keys represent a context you pushed somewhere.
Contexts
A context is simply a list of rules
Rules
- match
Type: string
A python regular expression. If this matches somewhere in the input line, all occurrences will be replaced with the string specified in replace.
- replace
Type: string
If continue is false (the default), this string will be emitted to stdout. Otherwise, this string will be passed to the next matching rule. Not that the following rule sees the modified string!
- continue
Type: boolean
If true, don’t write the string yet to stdout. Instead, pass it on to the next matching rule.
- push
Type: string
Pushes a new context onto the stack. All following lines from stdin will be matched agains rules in the new context.
- pop
Type: boolean
If this is set to true, then return to the previous context after this rule has been processed. If in the root context, this is a no-op.
Screenshots
A python setup session |
|
---|---|
Before |
After |
Simple aptitude search |
|
---|---|
Before |
After |
Apache access_log |
|
---|---|
Before |
After |
Footnotes
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file grc-1.0.0.post3.tar.gz
.
File metadata
- Download URL: grc-1.0.0.post3.tar.gz
- Upload date:
- Size: 273.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/57.4.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.9.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0f3aac49e122b8fc4e2ac98f521daf5680f4543d89fa52bf89e0d52ffb02a741 |
|
MD5 | b3f587f94fb2eae2dc5bda31244f37e7 |
|
BLAKE2b-256 | 11a5135b27b00eb1bcc6a637807bb37d7507c49779cbc483cc7f9346d618465d |
File details
Details for the file grc-1.0.0.post3-py3-none-any.whl
.
File metadata
- Download URL: grc-1.0.0.post3-py3-none-any.whl
- Upload date:
- Size: 8.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/57.4.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.9.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a62202ef2bf38e703ff475f1f0d912e9f7f0cc8c336a8e936fb9337796827020 |
|
MD5 | e9616ec8b8334e0bc6f5b3178f51b33f |
|
BLAKE2b-256 | 9d2e93e250ea74f2eeef15f0e9efa9d4889dff362d5e80ba2f5c2d50347b6df8 |