Can I push/pop attributes with tput? - terminfo

In the answer to this question, it uses the following (simplified):
echo "this is $(tput bold)bold$(tput sgr0) but this isn't"
But that tput sgr0 resets all of the text attributes.
I'd like to output coloured text, with only some of it in bold. So I want something like this:
echo "$(tput setaf 1)this is red; $(tput bold)this is bold; $(tput unbold)this is red, but not bold"
But tput unbold isn't a thing.
Is there any way to push/pop the terminal attributes so that I could do something like the following?
echo "$(tput setaf 1)this is red; $(tput push; tput bold)this is bold; $(tput pop)this is red, but not bold"

No - tput has no notion of push/pop. Just set: like a pun, tput is a more general tool than tset, as noted in the manual page:
SVr3 replaced that, a year later, by a more extensive program whose
init and reset subcommands (more than half the program) were
incorporated from the reset feature of BSD tset written by Eric
Allman.
tput does nothing like push/pop, because it would have to rely upon asking the terminal what the current video attributes are (something that only a minority of the terminals could do).
Some terminals could/can do this, e.g., the DEC VT420's DECRQSS control mentioned in XTerm Control Sequences. Most do not (even limiting this to xterm-imitators).
tput works with terminal capabilities; none of the predefined ones in terminfo(5) deal with stacks.
That's not to say that someone might develop an application like tput which could work with a terminal that supports stacking, either by supporting push/pop or set/get controls. (xterm does both).

Related

zsh completion: Disable ssh username completion

I am using the completion scripts that ship with ZSH (5.7.1) and I would like to turn off the autocompletion for usernames, but keep the completion for hostnames.
How can I do this?
Currently, there's an erroneous user that I can't figure out why it's being included (not in ~/.ssh/config, any identities, /etc/ssh, or any other location) and I figure it's probably easier to just disable username completion.
Example output is below; I want to remove the entire "login name" section rather than try and hunt down where unwanted-username is coming from.
$ ssh <tab>
-- login name --
unwanted-username
-- host --
example-host-1 example-host-1
I expect there is a zstyle command which can disable it, but I'm not sure the correct incantation. I expect this is the relevant configuration that needs to be changed:
$ zstyle | grep completion | grep ssh
:completion:*:ssh:* users hosts-domain hosts-host users hosts-ipaddr
However, I can't seem to get the correct incantation to remove the login name section.
To disable completion of login names, in that context, try:
zstyle ':completion:*:ssh:argument-1:*' tag-order hosts
or to merely hide them, try:
zstyle ':completion:*:ssh:*:users' hidden true
Pressing Ctrl-X h instead of tab is a good way to determine the relevant tags and context strings.
Seems odd that you have an erroneous user being completed. Check for a users-hosts style being set, possibly without mention of ssh in the context. The ignored-patterns style could be another way to deal with an erroneous match in the general case, for example:
zstyle ':completion:*:ssh:*:users' ignored-patterns erroneous-username
As you might discern from the name of the style, the last argument here can be a shell pattern with *, ? etc.

Can man pass an option to the roff formatter?

SYNOPSIS
From man(1):
-l
Format and display local manual files instead of
searching through the system's manual collection.
-t
Use groff -mandoc to format the manual page to stdout.
From groff_tmac(5):
papersize
This macro file is already loaded at start-up by troff so it
isn't necessary to call it explicitly. It provides an interface
to set the paper size on the command line with the option
-dpaper=size. Possible values for size are the same as
the predefined papersize values in the DESC file (only
lowercase; see groff_font(5) for more) except a7–d7.
An appended l (ell) character denotes landscape orientation.
Examples: a4, c3l, letterl.
Most output drivers need additional command-line switches -p
and -l to override the default paper length and orientation
as set in the driver-specific DESC file. For example, use the
following for PS output on A4 paper in landscape orientation:
sh# groff -Tps -dpaper=a4l -P-pa4 -P-l -ms foo.ms > foo.ps
THE PROBLEM
I would like to use these to format local and system man pages to print out, but want to switch the paper size from letter to A4. Unfortunately I couldn't find anything in man(1) about passing options to the underlying roff formatter.
Right now I can use
zcat `man -w man` | groff -tman -dpaper=a4 -P-pa4
to format man(1) on stdout, but that's kind of long and I'd rather have man build the pipeline for me if I can. In addition the above pipeline might need changing for more complicated man pages, and while I could use grog, even it doesn't detect things like accented characters (for groff's -k option), while man does (perhaps using locale settings).
The man command is typically intended only for searching for and displaying manual pages on a TTY device, not for producing typeset and paper printed output.
Depending on the host system, and/or the programs of interest, the a fully typeset printable form of a manual page can sometimes be generated when a program (or the whole system) is compiled. This is more common for system documents and less common for manual pages though.
Note that depending on which manual pages you are trying to print there may be additional steps required. Traditionally the following pipeline would be used to cover all the bases:
grap $MANFILE | pic | tbl | eqn /usr/pub/eqnchar | troff -tman -Tps | lpr -Pps
Your best solution for simplifying your command line would probably be to write a little tiny script which encapsulates what you're doing. Note that man -w might find several different filenames, so you would probably want to print each separately (or maybe only print the first one).

Rename ttf/woff/woff2 file to PostScript Font Name with Script

I am a typographer working with many fonts that have incorrect or incomplete filenames. I am on a Mac and have been using Hazel, AppleScript, and Automator workflows, attempting to automate renaming these files*. I require a script to replace the existing filename of ttf, woff, or woff2 files in Finder with the font's postscriptName. I know of tools (fc-scan/fontconfig, TTX, etc) which can retrieve the PostScript name-values I require, but lack the programming knowhow to code a script for my purposes. I've only managed to setup a watched directory that can run a script when any files matching certain parameters are added.
*To clarify, I am talking about changing the filename only, not the actual names stored within the font. Also I am open to a script of any compatible language or workflow of scripts if possible, e.g. this post references embedding AppleScript within Shell scripts via osascript.
StackExchange Posts I've Consulted:
How to get Fontname from OTF or TTF File?
How to get PostScript name of TTF font in OS X?
How to Change Name of Font?
Automate Renaming Files in macOS
Others:
https://github.com/dtinth/JXA-Cookbook/wiki/Using-JavaScript-for-Automation
https://github.com/fonttools/fonttools
https://github.com/devongovett/fontkit
https://www.npmjs.com/package/rename-js
https://opentype.js.org/font-inspector.html
http://www.fontgeek.net/blog/?p=343
https://www.lantean.co/osx-renaming-fonts-for-free
Edit: Added the following by request.
1) Screenshot of a somewhat typical webfont, illustrating how the form fields for font family and style names are often incomplete, blank, or contain illegal characters.
2) The woff file depicted (also, as base64).
Thank you all in advance!
Since you mentioned Automator in your question, I thought I'd try and solve this while using that to rename the file, along with standard Mac bash to get the font name. Hopefully, it beats learning a whole programming language.
I don't know what your workflow is so I'll leave any deviations to you but here is a method to select a font file and from Services, rename the file to the font's postscript name… based on Apple's metadata, specifically "com_apple_ats_name_postscript". This is one of the pieces of data retrieved using 'mdls' from the Terminal on the font file. To focus on the postscript name, grep the output for name_postscript. For simplicity here, I'll exclude the path to the selected file.
Font Name Aquisition
So… running this command…
mdls GenBkBasBI.ttf | grep -A1 name_postscript
… generates this output, which contains FontBook's Postscript name. The 'A1' in grep returns the found line and the first line after, which is the one containing the actual font name.
com_apple_ats_name_postscript = (
"GentiumBookBasic-BoldItalic"
Clean this up with some more bash (tr, tail)…
tr -d \ | tail -n 1 | tr -d \"
In order, these strip spaces, all lines excepting the last, and quotation marks. So for the first 'tr' instance, there is an extra space after the backslash.
In a single line, it looks like this…
mdls GenBkBasBI.ttf | grep -A1 name_postscript | tr -d \ | tail -n 1 | tr -d \"
…and produces this…
GentiumBookBasic-BoldItalic
Now, here is the workflow that includes the above bash command. I got the idea for variable usage from the answer to this question…
Apple Automator “New PDF from Images” maintaining same filename
Automator Workflow
Automator Workflow screenshot
At the top; Service receives selected 'files or folders' in 'Finder'.
Get Selected Finder Items
This (or Get Specified…) is there to allow testing. It is obviated by using this as a Service.
Set Value of Variable (File)
This is to remember which file you want to rename
Run Shell Script
This is where we use the bash stuff. The $f is the selected/specified file. I'm running 'zsh' for whatever reason. You can set it to whatever you're running, presumably 'bash'.
Set Value of Variable (Text)
Assign the bash output to a variable. This will be used by the last action for the new filename.
Get Value of Variable (File)
Recall the specified/selected file to rename.
Rename Finder Items: Name Single Item
I have it set to 'Basename only' so it will leave the extension alone. Enter the 'Text' variable from action 4 in here.

Zsh trouble when using echo with color/formatting characters

I'm just switch to zsh and now adapting the alias in which was printing some text (in color) along with a command.
I have been trying to use the $fg array var, but there is a side effect, all the command is printed before being executed.
The same occur if i'm just testing a echo with a color code in the terminal:
echo $fg_bold[blue] "test"
]2;echo "test" test #the test is in the right color
Why the command print itself before to do what it's supposed to do ? (I precise this doesn't happen when just printing whithout any wariable command)
Have I to set a specific option to zsh, use echo with a special parameter to get ride of that?
Execute the command first (keep its output somewhere), and then issue echo. The easiest way I can think of doing that would be:
echo $fg[red] `ls`
Edit: Ok, so your trouble is some trash before the actual output of echo. You have some funny configuration that is causing you trouble.
What to do (other than inspecting your configuration):
start a shell with zsh -f (it will skip any configuration), and then re-try the echo command: autoload colors; colors; echo $fg_bold[red] foo (this should show you that the problem is in your configuration).
Most likely your configuration defines a precmd function that gets executed before every command (which is failing in some way). Try which precmd. If that is not defined, try echo $precmd_functions (precmd_functions is an array of functions that get executed before every command). Knowing which is the code being executed would help you search for it in your configuration (which I assume you just took from someone else).
If I had to guess, I'd say you are using oh-my-zsh without knowing exactly what you turned on (which is an endless source of troubles like this).
I don't replicate your issue, which I think indicates that it's either an option (that I've set), or it's a zsh version issue:
$ echo $fg_bold[red] test
test
Because I can't replicate it, I'm sure there's an option to stop it happening for you. I do not know what that option is (I'm using heavily modified oh-my-zsh, and still haven't finished learning what all the zsh options do or are).
My suggestions:
You could try using print:
$ print $fg_bold[red] test
test
The print builtin has many more options than echo (see man zshbuiltins).
You should also:
Check what version zsh you're using.
Check what options (setopt) are enabled.
Check your ~/.zshrc (and other loaded files) to see what, if any, options and functions are being run.
This question may suggest checking what TERM you're using, but reading your question it sounds like you're only seeing this behaviour (echoing of the command after entry) when you're using aliases...?

Is it possible to prevent MSBuild printing colourized output

I've got my windows shell configured as displaying black text on a white background. This makes it almost impossible to read the default msbuild output due to the very pale colours (especially the yellow warnings).
Therefore I'd like to try one of the following, but I can't work out if it is possible.
I'd like to set a global setting to permanently turn off colourized output in msbuild; or
If (1) isn't possible is it possible to turn this output per-invocation (e.g. with command line arguments).
Does anyone know how to do one of the above?
In MSBuild 4.0 this is possible using the /consoleloggerparameters or /clp switch:
msbuild C:\some_path\your.sln /clp:disableconsolecolor
Alternatively, for previous MSBuild engines, this is possible using PowerShell:
Out-Host will display the default color:
Powershell -Command "msbuild C:\some_path\your.sln | out-host"
Write-Host will let you customize the colors:
Powershell -Command "msbuild C:\some_path\your.sln | write-host -foreground "white""
To completely disable colors use the /clp:disableconsolecolor option when invoking MSBuild.exe (for more information on the /clp option run MSBuild.exe /?).
Update as #KMoraz has commented, and updated his answer to, this only works with MSBuild 4.0 onwards.
If you want to disable color output you can also use the following (which will not work with MSBuild 4.0):
MSBuild.exe arguments > CON 2>&1
This got me curious ;-) so here is one more option that should work with all versions of MSBuild.exe and doesn't rely on CON redirection:
MSBuild.exe arguments 2>&1| findstr /r ".*"
Basically, what happens is that all lines of output are piped through findstr.exe since that uses a pattern to match "everything", all lines are simply output again, but loosing their attributes (color) information. In my tests the 2>&1 (redirect stderr to stdout) was not really necessary, as it looks MSBuild doesn't output any (colored) messages to stderr, but I added it for good measure.