Hi Ihor, At 2025-01-19T14:04:21+0000, Ihor Radchenko wrote: > "onf" writes: > > >> I am wondering if the situations like the above should be caught by > >> groff linter. Currently, they seem not. > > > > They actually are: > > ... > > troff::2: warning: cannot select font 'C' > > One two three four. > > Sorry, I was not clear. > What I meant is > > \fBbold \fIitalic\fP\fP \fP\fP is effectively a no-op. It switches from the previous font, and then to the previous font, with a sequence point (so to speak) in between that changes the identity of the previous font. Thought of differently, font selection escape sequences, if valid, have immediate effect. The parser doesn't keep scanning ahead to see if the input "really meant it". There's not really any such thing as "the groff linter". There are two systems in place: diagnostic messages at (in practice) two levels: warnings and errors, implemented in the formatter. The other? A macro package can, and in groff man(7)'s case, does, implement checks for idiomatic macro usage. (Actually, all of groff's full-service macro packages do this to some extent.) A macro package has little or no insight into when escape sequences are used, beyond the instant context in which its input tokens are encountered. And to the formatter, the sequence `\fP\fP` is _valid_. It's simply not useful. We don't, at present, have a warning category for valid-but-not-useful constructs. One is hoped for in a future groff release. https://savannah.gnu.org/bugs/?62776 However, I don't see good odds for this becoming such a style warning, because the way GNU troff's recursive-descent parser is written currently doesn't offer any support for recognizing this situation. We _could_ compare the actual current and previous font selections for identity and complain then, but I predict with some confidence that doing so would be a non-starter. A lot of macro packages are designed to "reset" various formatting parameters, when a new paragraph starts for instance. Such a mechanism could not distinguish between: .ft R blah blah blah blah .if \n[some-register] .do-something .sp .ft R ...and your \fP\fP example. By the time the formatter reads the second the `\fP` it has long forgotten that it just saw an `\fP`. And in the example above, whether the font selection changed or not depends entirely on what the "do-something" macro did, _and_ on whether "some-register" was assigned a true value. That's a lot of state to track. GNU troff does not keep a history of input tokens it has seen except on very limited, ad-hoc bases to derive semantics from interpretation of the _current_ input token(s). As far as I know, no other *roff keeps such a history either. That's why this is hard and unlikely to happen. Regards, Branden