groff
[Top][All Lists]
Advanced

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

[Groff] The lowest level of my paragraph processing macros


From: Thomas Baruchel
Subject: [Groff] The lowest level of my paragraph processing macros
Date: Sat, 12 May 2001 00:17:05 +0200
User-agent: Mutt/1.2.5i

Brest, le vendredi 11 mai

Hi everybody,

do you remember that I am writing a .PP macro which would do A LITTLE like
TeX while formatting the paragraph (try several dispositions and choose
the best ont in an esthetical point of view). There were several problems.
  - groff isn't intended to keep in memory an unformatted paragraph.
    I managed to do it.
  - groff hasn't registers that tell the size of the space in a line, or
    the number of spaces. I managed to build these registers.
What I show to you today is that:

two macros .mmm*P1 and .mmm*P2 which should encapsulate a paragraph in the
input (in the final version, a high-level macro .PP will call them), like
this:

  .P1
  piece of text
  .P2

The piece of text can really be whatever you want (the single bug for the
moment is for the \~ escape sequence). The piece of text isn't read in copy
mode. Really, you shouldn't put something different that what you are used to.
What do they do ? The create an UNFORMATTED diversion (believe me!) with
following features (it's called .mmm*P) :
  - ability of printing the stuff several times, without interpreting
    several times the escape sequences;
  - unformatted stuff; you can print it with .ad b or .ad l or whatever,
    with .ll 15c or .ll 400p or whatever, several times with several formats;
  - I chose to put the initial indentation in the diversion (it is a choice)
    end the size of the characters also (I had'n the choice). The initial
    indentation is in a user-defined register called: mmm*PI (default: 12p)
    The size of characters is in mmm*PS (default: 12);
  - user-defined macros which are automatically launched in the following
    conditions:
    if .mmm*word exist, it is launched after each word is processed (even if
    not printed)
    if .mmm*line exist, it is launched after each line is printed
    In these two macro, you can use the following registers:
    mmm*lines (the number of the last line which has been printed)
    mmm*value (NOT in .ad b mode, but correct in .ad l or r or c mode):
      the size of the space between two words if the paragraph would be
      printed in the same conditions with both justification.
      In other words. You have a paragraph and want to know which size will
      have the space in line 3 when you will print it with .ad b
      Just include this in your document:
        .mmm*P1
        My beautiful paragraph with at least 3 lines
        .mmm*P2
        .de mmm*line
        .if \n[mmm*lines]=3 .tm size will be \n[mmm*value]u
        ..
        .di x
        .ad l
        .mmm*P
        .br
        .di
        .ad b
        .mmm*P
      will print your paragraph justified and print on stderr size of space
      in line 3.

Something like:
  .mmm*P1
  A little cat
  .mmm*P2
  .de mmm*word
  x
  ..
  .mmm*P
will produce:
  A x little x cat

Something like:
  .mmm*P1
  A very long paragraph
  .mmm*P2
  .ll 17c
  .mmm*P
  .br
  .ll -2c
  .mmm*P
will print the same text twice with two different formats.

The user-defined strings mmm*H1, mmm*H2 and mmm*H3 have the following
meanings. At the beginning, groff needs to remove the characters: -, \(hy, \(em
It uses .tr to put something useless instead. I chose the characters:
  ß, ð and ø, but I'm going to put something better soon
mmm*H1 does the replacement
mmm*H2 puts back the initial characters
mmm*H3 switch off the translation mechanism:
  .ds mmm*H1 -ß\\(hyø\\(emð
  .ds mmm*H2 ø\\(hyð\\(emß-
  .ds mmm*H3 \\(hy\\(hy\\(em\\(emøøððßß--
  (these three lines are at the beginning of the file)

I'd be glad to have your comments ;-)

=============================================================================
.\" user-defined registers and strings
.nr mmm*PI 12p \" indentation
.nr mmm*PS 14  \" taille des caractères
.nr mmm*Wa 0   \" warning
.ds mmm*H1 -ß\\(hyø\\(emð
.ds mmm*H2 ø\\(hyð\\(emß-
.ds mmm*H3 \\(hy\\(hy\\(em\\(emøøððßß--
.\"
.\"
.\"
.de mmm*compute*init
.nr mmm*spaces -1
.nr mmm*lines 0
.nr mmm*value 0
.nr mmm*previous \\n(.du
.tr \\*[mmm*H2]
..
.de mmm*compute
.tr \\*[mmm*H3]
.nr mmm*spaces +1
.if dmmm*word .mmm*word
.if \\n(.du-\\n[mmm*previous] \{\
.  nr mmm*lines +1
.  nr mmm*spaces -1
.  if \\n[.hlc] .nr mmm*spaces +1
.  nr mmm*value \
        (\\n[mmm*spaces]*\\w'\\ '+\\n(.l-\\n(.n)/\\n[mmm*spaces]
.  nr mmm*previous \\n(.du
.  if dmmm*line .mmm*line
.  nr mmm*spaces 0
.\} \"fin du changement de ligne
.tr \\*[mmm*H2]
..
.de mmm*compute*end
.tr \\*[mmm*H3]
.rm mmm*spaces
.rm mmm*lines
.rm mmm*value
.rm mmm*previous
..
.de mmm*write
.tr @.
@mmm*compute
.br
.tr @@
.dt \\n(.du+\\n(.vu mmm*write
..
.de mmm*P1
.nr mmm*place \\n(.c \" ligne du début du paragraphe
.nr mmm*warn*old \\n[.warn]
.warn \\n[mmm*Wa]
.br \" ### est-ce bien utile ?
.di mmm*P
.tr @.
@mmm*compute*init
.br
.tr @@
.ev mmm*env
.in 0
.ti \\n[mmm*PI]u
.ps \\n[mmm*PS]
.ll 1u
.nh
.tr \\*[mmm*H1]
.dt \\n(.du+\\n(.vu mmm*write
..
.de mmm*P2
.dt
.tr \\*[mmm*H3]
.br
.ev
.tr @.
@mmm*compute*end
.br
.tr @@
.di
.warn \\n[mmm*warn*old]
.rm mmm*warn*old
.asciify mmm*P
.rm mmm*place
..
.\"
.\"
.\"
.mmm*P1
A little cat
.mmm*P2
.ad b
.mmm*P

reply via email to

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