groff
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Groff] condition: OR of two string comparisons


From: hohe72
Subject: Re: [Groff] condition: OR of two string comparisons
Date: Sun, 23 Nov 2014 13:44:26 +0100

Hi, since I sparked an issue, I might explain my:

I coded a macro, that does a defined vertical space
(.sp //n[distance]u). The value can be set if the
switch '--define' is used. The macro should make a
temporary vertical move, when a number was provided.

Therefore I met a condition that if no parameters are
provided or the vertical space for the move was just
defined, the value of global variable should be used,
the $1 parameter otherwise.

It shouldn't be a hack, so I sought to not redouble
code, that happened in getting two else branches.
That leads to the implementation using a temporary
variable.

.if '\*c'foo' .ds d "bar
.ie '\*d'bar' .tm *1> true
.el           .tm *1> false

What worried me was, that the use of the temporary
variable was not motivated by the problem to solve,
so being "hard" to grasp. That leads to the thread.

It's important to understand that my point of view
at this discussion is, to improve that design. I'm
therefore critical at suggestions provided here,
being more complicated (or suspected to become so)
than the original problem. It matters that "People
rather live with a problem they cannot solve, than
with a solution they cannot understand."
Woolsey & Swanson.

However, I didn't want to be aided in macro development
and guessing it shouldn't be that impact to extend the
conditions of if-branching, I put the question at the
list.

Positively, I got some of a good new understanding.
Unfortunately, the topic becomes obscured due to the
thread provided solutions, but missed goals. You
know, it's important to know what you want to
achieve, in order to make decisions.

BTW, I call expressions evaluating to a value
interpreted as boolean a "condition". A "branch" in
program flow occurs when it hits an if-statement or
a loop.  A "groff-literal" is what is used at groffs
string comparison facility, what is not really a string.

So I think here are three goals:
1) Compare against Regular Expressions.
2) Integrate groff-literal comparison into existing
   number expressions.
3) Introduce new requests to reinvent branching.

The first two only deal with conditions. The last
have branching as subject.

That are different approaches.

I think, it's clear that the introduction of an
additional new set of requests that, in order to
extend a missed capability at condition testing,
is overambitious. BTW, it would lead to a situation
where groff syntax has two kinds of branching,
uninterchangeable. Users would lose their trust in
Groff. (In C, I often wished, the developers hadn't
invented the wheel thrice and called a loop just
loop(). :)

However, IMHO a request achieving "elseif" is an
option. Is is the same a separate task to condition
improvement. If done then:

Why should a request newly introduced have a two
character format. Well, generally I think it is
good style, or call it a clear concept easy to
grasp, to use long formats for new requests. That
is, one see it's new, and as mostly it covers
special cases (seldom used) it should be more
expressive. However, elseif is dedicated to
integrate into the existing old .if/.ie/.el concept.
So I favour a two character request. It's also
better to indent.

Why do I tend to improve old structures used by
Groff instead of scramble in other ideas. It's
Groffs core concept that distinguishes Groff. I
know, that it is easy to bloat a system, but
hard to dense a concept. You not only have to
invent solutions but reject it as well. This
assumes a kind of discipline rarely found. Even
Linus Torvalds capitulates in front of complexity
(Linux Magazin, Germany). I therefore respect the
once developers at AT&T. I don't want to destroy
their work. It's valuable.

I'm generally not susceptive to arguments of speed.
Sorry, ego trips doesn't relate to typesetters.


So, coming back, I think the issue can be focused
on condition improvement. And I gathered a few:

[Always the same check: \$1 is '' (empty) or
 '--define'.]


.\" Regular Expression
.ie r '\\$1'|--define' .tm true
.el                    .tm false
* This is an _extended_ Regular Expression. I vote for it.
* The Regular Expression (right side) don't need to
  recognize Groff-variables. It might be raw.
* The pattern (left side) have to be converted in
  a certain way (arbitrary but fixed) to a string.

Why not using a different delimiter as "$(" for
instance? Because the prefix indicator already
exists. The kind of expression after a selection
by 'r' is not restricted (input.cpp, do_if_request()).


.\" extending Groffs number expression
.ie ('\\$1'':'\\$1'--define') .tm true
.el                           .tm false
* It's my ongoing duty to take a look into the
  sources here. My first guess is that the existing
  groff-literal comparison can be used.
* Otherwise no alternations to existing behavior.

A note about the introduction of new delimiters here.
do_if_request() consists of a long ifelse structure.
These structure consumes the prefixed cases and
leaves only number expressions and Groff-literal
comparison to be processed. The distinction happens
by recognizing the groff-literal delimiter. At no
match the expression is taken to be a number expression.
At the sources the recognizing either of delimiters
or prefixes happens in the same code structure.
However, to accommodate the delimiter recognizer,
(at the token class or its friends) is more
expensive to code, than just using a prefix.

The "ifelse"-structure then can become a switch().
Also note that the groff-literal comparison there
is spaghetti-coded and have to become its own function,
in order to be used at number expression parsing.


.\" multiple OR
.ie '\\$1''--define' .tm true
.el                  .tm false
* This extends existing groff-literal comparison
  by comparing the pattern (left) with all
  remaining groff-literals (to the right).
  It suffices if one matches.

I tried to implement that. It turns out, that
either a terminating delimiter for the expression
is needed, or the line have to be parsed altogether
(EOL), just to rewind the parser to the last
delimter, leaving the then-part unprocessed
for the typesetter. However the utility for that
limited feature is questionable.


.\" define a number register by a condition
.cond N '\\$1'=='' or '\\$1'=='--define'
.ie \\n[N] .tm true
.el        .tm false
* The request .cond defines a number register N,
  according to its boolean expression.
* That might be used by .if and .while.

Since this is a new request, not integrating into
Groff, I tend to call it by a long name (arbitrary
but fixed). No byeffects. Just a request that
doesn't jostle into the two character namespace of
traditional Groff requests.


Again, initially I hoped if -- then just
selectively, to touch groff. Not altering
much.

<skip>

Thanks for the patience (this is line 190),

Holger


ps: please don't write that long mails.  ,,,^..^,,,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]