[Top][All Lists]
[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
- [Groff] The lowest level of my paragraph processing macros,
Thomas Baruchel <=