Re: An extremely lazy proposal
I solved this problem for me by having a pseudo comment in the first line of my documents which indicates how this individual document is to be handled. In my bash-script, that eventally calls groff with appropriate options and preprocessors I have FILE="$1" # check for .\" eqn tbl add lnd eng mom for i in `read x < $1; echo $x` do case $i in eqn) OPTS="$OPTS -e" ;; lnd) FORM=lnd ;; tbl) OPTS="$OPTS -t" PIPE="$PIPE | squezetbl " ;; add) PIPE="$PIPE | addtbl.pl " ;; eng) longdash="\40-\40 (em" ;; mom) MAC=mom ;; *) : esac done Best, ulrich On Fri, Mar 22, 2024 at 09:01:27PM +0100, Oliver Corff via wrote: > Dear All, > > recently I compiled, and re-compiled, and again recompiled a set of > various documents with different tables, equations etc.. For each of the > documents, the precise requirements of preprocessors were different, and > more often than not, I forgot to set the appropriate groff option when > running the compilation to the effect that I had to redo my edit - check > cycle. Since there is no groffer script anymore, may I humbly propose a --
Re: [Groff] What does the "-u" in ".tmac-u" mean?
On Sun, Nov 05, 2017 at 11:32:10AM +0100, oe wrote: > Am 05.11.2017 um 11:11 schrieb Ralph Corderoy: > > Hi, > > > > Werner wrote: > > > Branden wrote: > > > > I move that we stop stripping the files. Stripping them is saving > > > > us only a few hundred kB out of 25 megs. > > > It's not about saving disk space. Remember that groff is an > > > interpreted language *without* a translation to an internal > > > representation.[*] This means, for example, that a comment within a > > > loop with 1000 repeats gets parsed a thousand times, again and again. Couldn't this be avoided, if groff used in a preprocess one or two sed commands to get rid of comments and indentation? ulrich
[groff] infinite loop with groff + mom
Hi all, I process the file below with groff -Tps -k -mom -P-pa4 test.mom > /tmp/out.ps and get test.mom:74: fatal error: input stack limit exceeded (probable infinite loop) I get one page of output with center and right part of the footer at the top(!) and left part at the bottom. I use groff 1.22.3 and mom 2.2 Do I something totally wrong, or is this a bug in mom? Here is the input: .PRINTSTYLE TYPESET .PAPER A4 .L_MARGIN 1i .FAMILY N .FONT R .HEADERS OFF .FOOTERS .PAGINATIONOFF .T_MARGIN 0.25i .B_MARGIN 1.25i .FOOTER_MARGIN 0.5i .FOOTER_ON_FIRST_PAGE .FOOTER_LEFT "left" .FOOTER_CENTER "center" .FOOTER_RIGHT "page \*[PAGE#] of 10" .PT_SIZE 12 .AUTOLEAD 2 .HEADING_STYLE 1 NUMBER SIZE +0 BASELINE_ADJUST 0.2v .HEADING_STYLE 2 NUMBER SIZE +0 BASELINE_ADJUST 0.2v .HEADING_STYLE 3 NUMBER SIZE +0 FONT I BASELINE_ADJUST 0.1v .PARA_INDENT 0 .START .LEFT test [ the test-line is repeated 60 times ] Thanks for any help, ulrich
Re: [groff] infinite loop with groff + mom
On Thu, Nov 23, 2017 at 12:10:14PM -0500, Peter Schaffter wrote: > Ulrich -- > > > I'm not seeing this behaviour in your file with version 2.2-a, which > I just patched to fix this very problem (missing .mk request in > PRINT_FOOTER). Have you updated? The patched version is in the > repo and in the tarball on mom's homepage. > Sorry, but I can't find that tarball. On http://www.schaffter.ca/mom/mom-05.html I see Downloads The current release: version 2.2 The current release: version 2.1-b Final release in the 1.x series The install-font.sh script google didn´t help to find another mom-homepage. And when I download mom-2.2.tar.gz I get a file which is smaller than my previous mom-2.2.tar.gz. New: 2007040 bytes Old: 2314240 bytes gunzip says: gzip: mom-2.2_(1).tar.gz: not in gzip format So, where is the 2.2-a tarball? > Cheers. > ulrich
Re: [groff] infinite loop with groff + mom
On Thu, Nov 23, 2017 at 10:00:22PM -0500, Peter Schaffter wrote: > On Thu, Nov 23, 2017, Ulrich Lauther wrote: > > Sorry, but I can't find that tarball. On > > http://www.schaffter.ca/mom/mom-05.html I see > > My apologies. The tarball has been uploaded and the links fixed. > Thanks a lot, that solves my problem. However, the file mom-2.2-a.tar.gz is NOT a gzipped tar file. It is just plain tar: file mom-2.2-a.tar.gz gives: mom-2.2-a.tar.gz: POSIX tar archive (GNU) Kind regards, ulrich
Re: [groff] infinite loop with groff + mom
On Fri, Nov 24, 2017 at 11:49:51AM -0500, Peter Schaffter wrote: > On Fri, Nov 24, 2017, Ulrich Lauther wrote: > > However, the file mom-2.2-a.tar.gz is NOT a gzipped tar file. It is just > > plain tar: > > > > file mom-2.2-a.tar.gz gives: > > > > mom-2.2-a.tar.gz: POSIX tar archive (GNU) > > Interesting. I checked that my ftp client (lftp) wasn't deflating > the archive and re-uploaded. I then downloaded the file via ftp, > first at the command line and then using KDE Dolphin. In both > cases, file(1) reported > > mom-2.2-a.tar.gz: gzip compressed data > > Next, I downloaded the file using wget(1) and KDE's Konqueror. > Again, file(1) reported > > mom-2.2-a.tar.gz: gzip compressed data > > Lastly, I downloaded the file from the Opera browser, and hey, > presto!, file(1) reported > > mom-2.2-a (1).tar.gz: POSIX tar archive (GNU) > > If anyone knows why this is, I'll be glad of the knowledge. > I don't no either, but, yes, I downloaded using Opera. Cheers, ulrich
[groff] A few issues with mom's LIST macros
Hi all, working with the LIST macros I came across these issues: 1) besides BULLET, DASH, USER, etc. also "PLAIN" can be used. However, this is not mentioned in the documentation. 2) if ROMAN or roman is used without a trailing number, e.g., ROMAN instead of ROMAN7, the command ".tm1 "[mom]: You must append a number to the \\$1 argument to \\$0." should be invoced, but is not. 3) Having used the mm-macros for long time in the past, I was missing the variable-item list (VL in mm) where each item gets its own enumerator. The small patch appended introduces LIST VARIABLE and ITEM The patch fixes also issue 2. If the patch should be accepted, the documentation needs some update too. Kind regards, ulrich start of patch 26-Nov-2017 (suggested archive name: pch26Nov17.Z) It should be applied by changing directory to the root of the source tree and using the command: patch -p0 < this_file *** om.tmac-2017-11-25 23:23:57.953039541 +0100 --- om.tmac 2017-11-26 03:40:36.340135569 +0100 *** *** 15665,15678 . ds $LAST_CHAR \\$1 . substring $LAST_CHAR -1 . if !\B'\\*[$LAST_CHAR]' \{\ - . if !'\\$1'ROMAN' \{\ - . LIST OFF - . return - . \} - . if !'\\$1'roman' \{\ - . LIST OFF - . return - . \} . tm1 "[mom]: You must append a number to the \\$1 argument to \\$0. . tm1 " The number should be the total number of items in this list. . tm1 " See the documentation. --- 15665,15670 *** *** 15807,15812 --- 15799,15818 . ds $SEPARATOR\\n[#DEPTH] . ds $PREFIX\\n[#DEPTH] . \} + . if '\\*[$LIST_ARG_1]'VARIABLE' \{\ + . if \\n[#NUM_ARGS]<2 \{\ + . tm1 "[mom]: You must append a value to the \\$1 argument of \\$0. + . tm1 " The value should be the width of the largest enumerator of items in this list. + . tm1 " See the documentation. + . ab [mom]: Aborting '\\n[.F]' at \\$0, line \\n[.c]. + . \} + . nr #ARGS_TO_LIST 1 + . ds $ENUMERATOR\\n+[#DEPTH] + . ds $ENUMERATOR_TYPE\\n[#DEPTH] variable + . ds $ENUMERATOR_WIDTH\\n[#DEPTH] \\$2 + . ds $SEPARATOR\\n[#DEPTH] + . ds $PREFIX\\n[#DEPTH] + . \} . if '\\*[$LIST_ARG_1]'PLAIN' \{\ . nr #ARGS_TO_LIST 1 . ds $ENUMERATOR\\n+[#DEPTH] *** *** 15848,15853 --- 15854,15861 . GET_ROMAN_INDENT .if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'other' \ . nr #LIST_INDENT\\n[#DEPTH] \w'\\*[$ENUMERATOR\\n[#DEPTH]]\ ' + .if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'variable' \ + . nr #LIST_INDENT\\n[#DEPTH] \\*[$ENUMERATOR_WIDTH\\n[#DEPTH]] .ll \\n[#CURRENT_L_LENGTH]u .ie \\n[#DEPTH]=1 \{\ . ie \\n[#INDENT_ACTIVE]=1 \{\ *** *** 16007,16012 --- 16015,16022 . \} . if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'other' \ . PRINT \\*[$ENUMERATOR\\n[#DEPTH]]\\*[$SEPARATOR\\n[#DEPTH]] + . if '\\*[$ENUMERATOR_TYPE\\n[#DEPTH]]'variable' \ + . PRINT \\$1 .\} .rr #SEP_TYPE .EOL
Re: [groff] A few issues with mom's LIST macros
On Sun, Nov 26, 2017 at 03:04:29PM -0500, Peter Schaffter wrote: > Ulrich -- > > On Sun, Nov 26, 2017, Ulrich Lauther wrote: > > 2) if ROMAN or roman is used without a trailing number, e.g., ROMAN instead > > of ROMAN7, > >the command ".tm1 "[mom]: You must append a number to the \\$1 argument > > to \\$0." > >should be invoced, but is not. > > > > The small patch appended introduces > >LIST VARIABLE > > and > >ITEM > > Entering the widest glyph literally rather than its width, which > would have to be calculated, makes things simpler. Furthermore, if > the glyph is in double-quotes, users can add space to or subtract > it from the gutter between the enumerators and the text with \*[FWD dist]. in my tests I used \w'', but yes, your solution is much more convenient and elegant. As I am not a versatile groff programmer, I was expecting that some polishing of my code was called for. > > Apply the attached, revised patch and test. Yes, my tests, both VARIABLE list and error message related to ROMAN, work nicely now. Thanks a lot, ulrich PS: why do we have to use "ROMAN" and not "ROMAN ", which would be easier to process? Historical reasons?
Re: [groff] A few issues with mom's LIST macros
On Sun, Nov 26, 2017 at 06:31:42PM -0500, Peter Schaffter wrote: > On Sun, Nov 26, 2017, Ulrich Lauther wrote: > > why do we have to use "ROMAN" and not "ROMAN ", which would be easier > > to process? > > Historical reasons? > > Yep. :) > > Truth is, I wrote the macro so long ago that I can't recall what > advantage I saw in postfixing the digit. As a user, do you see an > advantage to making the second form available, too? If so, it's a > no-brainer to implement. I can take care of it before pushing your > patch. > No, as a user not really. It is just against the principle of least astonishment. Keeping both forms would make the code even more complicated and abolishing the current form would hurt users who used it in the past. Reminds me of a story about the make-program where supposedly the necessity to use a tab instead of blanks for indentation could not be abolished because there were allready three users. Probably an urban legend. Best ulrich
[groff] problem with umlaut in string
I use .ds BLD \f3\\$*\fP and this text is partly \*[BLD in bold face] to switch to bold face and back within a line of text. This works fine as long as there is no german umlaut in the argument to BLD. With an umlaut, I get groff -Tps -k -t -mom -P-pa4 - > /tmp/4451out.ps :219: missing `]' :219: invalid base glyph `u00F6\fPr]' in composite glyph name :219: warning: can't find special character `' Seems, groff is confused by the '[' produced by preconv. Is this a groff bug, or my fault? Kind regards, ulrich
Re: [groff] mom manpage
Peter, I couldn't agree more to what you are saying. In my opinion, a man page should contain (at most) NAME, SYNOPSIS, COPYRIGHT, DESCRIPTION, OPTIONS, ARGUMENTS, INVOCATION, but not LANGUAGE. A bad example is bash: NAME to INVOCATION take 210 lines, o.k.. The whole man-page is 5869 lines. A horror to search for some feature you need, even if you vaguely remember to have it seen before. And on the other hand, how happily I browse through the html mom documentation! (38472 lines, more than 6.5 times the bash lines) Cheers and thanks to Peter, ulrich
Re: [groff] mom manpage
On Wed, Dec 05, 2018 at 03:29:36PM +0100, Tadziu Hoffmann wrote: > > Quite the contrary. Less allows searching the page using > regular expressions, which actually helps a lot. Many html > A real life example: I want to read an answer from stdin into a variable, but - as I do not shell programming every day - do not remember how. Searching for "read" in the man page leads me to the wanted position after about 200 times hitting the "n" key. Next I try " read ". Still about 50 key hits. Try man bash | grep read | wc Kind reagrds, ulrich
Re: [groff] a5 paper size?
On Fri, Dec 21, 2018 at 09:47:46PM -0500, Richard Morse wrote: > Thanks for the suggestion. I’ve done a bit more research, and it looks like > gropdf doesn’t implement the “\X” command according to the documentation, > which is the problem. > > I’m trying to keep things off the command line, because that makes the file > less self-contained (I would actually like to take the “-Tpdf” into the file > as well, to tell the truth). > As I reported earlier, I use the first line of a file to store hints about (pre)processng. Example: .\" mom tbl pdf and use a shell script to interpret this line and to control appropriate processing. Best, ulrich
[groff] A poor mans Excel
Hi all, I have written a small perlscript, that preprocesses tables and allows to - add the values in selected collums - to replace a table entry by the result of an expression Lines between .( and .) are processed. The ".(" line may contain the numbers of collums in which addition is requested, e.g.: .( add 2 5 7 or just .( 2 5 7 ".(" ".)" blocks my be nested; sums calculated at a lower level are propagated up. Table entries of the form E. are repaced by the result of the expression rounded to n digits after the decimal point. "expression" is any valid perl expression. Variables used in the expression are - any valid perl variable (starting with "$") - $, the value in column n in the current line - $S, sum of values in the column (where $S is placed) seen so far If $S or E. is precedet by an "!", addition is suppressed for this table entry. As all tables of a document are processed by one perl-instance and perl variables can be created on the fly, values can be tranported from one table line to a later one or even to another table. Code size: 130 lines of perl Limitations: Multiline table enties are not supported. If there is interest, I'll post the script and an example. Kind regards, ulrich lauther
Re: [groff] A poor mans Excel
On Thu, Oct 10, 2019 at 03:45:54PM +0100, Ralph Corderoy wrote: > Hi Ulrich, > > > I have written a small perlscript, that preprocesses tables and allows > > to > > > > - add the values in selected collums > > - to replace a table entry by the result of an expression > > Thanks for letting us know. As Mike said, please show us the code; > the list's archive will hopefully capture it for others that Google later. > Should I place the code under GPL, if so, which version? > On the general topic, to be more spreadsheet like it would need to allow > forward references too, e.g. y=x+z where x was earlier, and already known, > but z is yet to be seen. And also in-line evaluation, similar to eqn's > `delim @@'. > I tried to keep it as simple as possible, but useful for my needs, e.g. - keeping track of costs, payments and profit from a couple of rented flats - keeping track of repayments and interest payments for some capital loaned to some people - keping track of my monthly income and spending; the rented flats go into nested subtables - preparing the annual tax return However, in-line evaluation could easily be added when I drop the syntactical requirement to have E. at the beginning of a table entry; probably one would then need some brackets around E. > As with all these little languages, much of the insight comes from > trying to apply it to one real task after another. But the problem > seems tractable. > that's, what I did, see above. Btw, the first version was written in awk, but I missed an evaluate-statement there. Hopefully I will post tomorrow, when I know abou GPL. Cheers, ulrich
Re: [groff] A poor mans Excel
On Thu, Oct 10, 2019 at 08:55:02AM -0400, Mike Bianchi wrote: > > If there is interest, I'll post the script and an example. > > Yes please. > Mike > Please find attached addtbl.pl (the code) addtbl.exp (an example) addtbl.exp.ps (corresponding output) Cheers, ulrich : # Copyright 2019 Ulrich Lauther # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. eval 'exec perl -w -S $0 ${1+"$@"}' if 0; my $tab = "\t"; my $BLANK = ' '; my $in_table = 0; my $stack_ind = -1; my $cols = 0; while ($line = <>) { chomp $line; if ($line eq ".TS") { # table starts print "$line\n"; $in_table = 1; do { # skip table header chomp($line = <>); print "$line\n"; if ($line =~ /tab/) { $tab = $line; $tab =~ s/.*tab\((.)\).*/$1/; } } while ($line !~ /\.$/); # last table header line ends with "." $line =~ s/\|/ /g; # eliminate "|", so we can count columns $cols = split $BLANK, $line; next; } # table start if ($in_table == 0) { # outside table, just copy print "$line\n"; next; } if ($line eq ".TE") { # table ends print "$line\n"; $in_table = 0; next; } # table end # .( if (substr($line,0,2) eq ".(") { # start summation # .( [add cols] col col ... collmn(s) to be added $stack_ind++; # stack index #initialize signs and sums: for ($i = 0; $i < $cols; $i++) { # all cols $sign[$i][$stack_ind] = 0; # sign $s[$i][$stack_ind]= 0; # sum } #store signs and cols: @fields = split $BLANK, $line; shift @fields; # skip ".(" shift @fields if ($fields[0] eq "add"); shift @fields if ($fields[0] eq "cols"); # store signs of cols to be added: foreach $col (@fields) { if ($col < 0) { $col = -$col-1; $sign[$col][$stack_ind] = -1; } else { $col = $col-1; $sign[$col][$stack_ind] = 1; } } next; } # end .( # .) if (substr($line,0,2) eq ".)") { # end summation # .) text S.d col col ... output sum of sums with precision d if ($stack_ind > 0) { for ($i = 0; $i < $cols; $i++) { $s[$i][$stack_ind - 1] += $s[$i][$stack_ind]; } } if (length($line) > 3) { # output sum of sums ($foo,$text,$p,$rest) = split $BLANK, $line, 4; ($foo,$p) = split /\./,$p; # split S.d if ($rest) { # col col ... $sum = 0; @cols = split $BLANK, $rest; foreach $col (@cols) { $sum += $s[$col-1][$stack_ind]; } printf("%s %.${p}f\n",$text,$sum); } } $stack_ind--; next; } # end .) if ($line =~ /$tab/) { # normal table line $sep = ($tab eq '|') ? '\|' : $tab; $n = @fields = split(/$sep/,$line); for ($i = 0; $i < $n; $i++) { # all fields $add = 1; $f = $fields[$i]; if ($f =~ /^!?E\.\d /) { # evaluate expression $add = 0 if (substr($f,0,1) eq "!"); ($form,$expr) = split $BLANK,$f; # E.d expr or !E.d expr ($foo,$p) = split /\./,$form; $expr =~ s/\$(\d+)/$fields[$1-1]/g; # $col -> $fields[col-1] $expr =~ s/\$S(\d+)/$s[$1-1][$stack_ind]/g; # $Sx -> sum of col x $expr =~ s/\$S/$s[$i][$stack_ind]/g;# $S -> sum of current col $res = eval($expr); $f= sprintf("%.${p}f",$res); $fields[$i] = $f; } print $f; # possibly add per collumn: # printf("stack_ind: %d\n",$stack_ind); if ($add == 1 && $stack_ind >= 0 && $sign[$i][$stack_ind] != 0) { $f = 0 if ($f =~ /^ *$/); # empty field $s[$i][$stack_ind] += $f*$sign[$i][$stack_ind]; } print $tab unless ($i == $n-1); } print "\n"; next; } print "$line\n"; } # while input .\" tbl add mom .IR 0.9c .SPACE |2c .AUTOLEAD 2 .PT_SIZE 12 .JUSTIFY .TS tab(@); L R N N. .( 4 \*[BD]Einnahmen:\*[PREV] .( 4 Miete Wohnung 1 - 12 @514.20
weird behaviour of groff / preconv
Hi, I process this input .ps 20 This is a partly \f3bold\fP text. This is a partly \f3böld\fP text. .ds MyBLD \f3\\$*\fP This is a partly \*[MyBLD bold] text. This is a partly \*[MyBLD "böld"] text. This is a partly \*[MyBLD böld] text. with groff -Tps -k test > test.ps For all but the last line I get the expected output. But the last line gives me test:12: missing `]' test:12: invalid base glyph `u00F6\fPld]' in composite glyph name test:12: warning: can't find special character `' The output of preconf test is (I show only the last lines): This is a partly \*[MyBLD "b\[u00F6]ld"] text. This is a partly \*[MyBLD b\[u00F6]ld] text. It seems groff expands to b\[u00F6]\fPld instead of b\[u00F6]ld\fP. Is this behaviour to be expected, or is it a bug in groff? Kind regards, ulrich
Re: weird behaviour of groff / preconv
On Mon, Nov 25, 2019 at 02:05:39AM +0100, Tadziu Hoffmann wrote: > > > > It seems groff expands to b\[u00F6]\fPld instead of b\[u00F6]ld\fP. > > If I print out the text using .tm, I get > > \f3b\[u00f6\fPld] > > so it seems that the string argument scanner stops at the first "]", > passing "b\[u00f6" to MyBLD as argument, which then results in the > "missing ']'" error. If you quote the argument, the scanner correctly > collects all text until the ending quote, and then terminates with > the following "]", giving the correct argument "b\[u00f6]ld". > > Yes. But is this to be considered a bug, or a feature?
Re: [groff] An alternative to info(1) ?
On Mon, Feb 17, 2020 at 08:58:04AM -0500, Mike Bianchi wrote: > On Sun, Feb 16, 2020 at 07:55:31PM -0800, Larry McVoy wrote: > > I *hate* info. It has made Linux less available to a lot of people. > What about tkinfo? ulrich lauther
Re: Proposed: drop groffer (was: contrib/groffer/roff2.1.man)
Maybe I am not qualified to contribute my opinion, as I never used groffer. I use groff a lot, wrote a shell wrapper tailored to my needs many years ago. So I wouldn't miss groffer. Best, ulrich
bug or my ignorance?
With this input .di text test 1 test 2 test 3 . . . test 27 test 28 test 29 .di .text .text and groff -T ascii I get: test 26 test 27 test 28 test 29 test 1 test 2 test 3 test 4 test 5 test 6 test 7 test 8 test 9 test 10 test 11 test 12 test 13 test 14 test 15 test 16 test 17test 18 test 19 test 20 test 21 test 22 test 23 test 24 test 25 test 1 test 2 test 3 test 4 test 5 test 6 test 7 test 8 test 9 test 10 test 11 test 12 test 13 test 14 test 15 test 16 test 17 test 18 test 19 test 20 test 21 test 22 test 23 test 24 test 25 However, when I use a macro instead of a diversion, I get: test 1 test 2 test 3 test 4 test 5 test 6 test 7 test 8 test 9 test 10 test 11 test 12 test 13 test 14 test 15 test 16 test 17 test 18 test 19 test 20 test 21 test 22 test 23 test 24 test 25 test 26 test 27 test 28 test 29 test 1 test 2 test 3 test 4 test 5 test 6 test 7 test 8 test 9 test 10 test 11 test 12 test 13 test 14 test 15 test 16 test 17 test 18 test 19 test 20 test 21 test 22 test 23 test 24 test 25 test 26 test 27 test 28 test 29 as expected. So, why behaves the diversion (for me) unexpected, or what am I doing wrong? Best, ulrich lauther -- -lauther
Re: bug or my ignorance?
On Tue, Aug 11, 2020 at 10:31:56AM +0200, Tadziu Hoffmann wrote: > > > So, why behaves the diversion (for me) unexpected, or what > > am I doing wrong? > > Diversions contain text that has been formatted and output. > The partially collected line that exists when you terminate the > diversion has not been output, so it does not become part of > the diversion. To achieve what you (probably) want, insert a > ".br" before you end the diversion, this flushes the partially > collected line to the output (and thus into the diversion). > Thanks a lot, the ".br" does it. When I use a macro instead of a diversion, the formatting seems to take place not until the macro is called. Right? ulrich lauther
Re: End-of-sentence spacing
On Sat, Dec 19, 2020 at 10:27:01AM +, Dorai Sitaram wrote: > groff pretty much forces one to use two spaces after sentence-ending > punctuation, unless it's at the end of a source line. In my opinion it is good style to start every sentence on a new source line. This is helpful for editing the text. Best, ulrich
Re: End-of-sentence spacing, for our German readers
On Thu, Jan 14, 2021 at 06:01:33AM +, Dorai Sitaram via wrote: > I'm used to single-spacing by now, given its ubiquity, but surely the > Germans carry their disdain for typographic breathing space a little too far? > As in the posted article, paragraphs are difficult to visually separate, > lacking as they do both leading horizontal indentation and vertical > separation. Did you realize that the posted article was a joke, a piece of humor? Best, ulrich
Re: Interesting articles
On Thu, Mar 25, 2021 at 10:30:57PM -0400, Larry Kollar wrote: > Sometimes, my Twitter feed coughs up some cool articles, like > this one: "Performance comparison: counting words in Python, > Go, C++, C, AWK, Forth, and Rust” > > https://benhoyt.com/writings/count-words/ > > The Awk solution was by far the shortest by line count. Since > the runtime for all the different solutions was a few seconds or > less, Awk was probably the fastest because it took the least time > to code. :D > What about "wc -w" ? ulrich lauther
Re: man-intro
On Sat, May 22, 2021 at 08:18:41PM +0200, Oliver Corff wrote: > > "man cd", on the other hand, opens the bash built-in command *man page*, > which, at least on my system is a plethora of text to read (and digest). > on my sytem (ubunto mate) "man cd" results in "No manual entry for cd". > Just my 2cents, > ulrich
[Groff] mm-macros, page break too early
(I tried to post this via the forum page, but got http error 500) A short question about the mm-macros (1.20.1): I have sometimes the problem, that a list triggers a page break too early, e.g. when a list or a picture would easily fit onto the page. I circumvent this in this way: .ch pg@footer .BL [any stuff here] .LE .wh \n[pg*foot-trap]u pg@footer .BP Is there a better way to do this or to avoid the problem in the first place? (The problem occurs just with lists and with .PSPIC, not with plain text; so their vertical space demand seems to be overestimated). -- -ulrich lauther
[Groff] Explanation for .BP ?
(I tried to send this via the nabble forum interface, but got HTTP error 500) To generate a page break within a table, one is supposed to use .de BP . ie ’\\n(.z’’ .bp \\$1 . el \!.BP \\$1 .. Could some kind soul explain the working of this macro? The else branch looks like a recursive call. And why does plain .bp not work? Thanks for enlightenment, ulrich
[Groff] Explanation for .BP ?
(I tried to send this via the forum interface, but got HTTP error 550) To generate a page break within a table, one is supposed to use .de BP . ie ’\\n(.z’’ .bp \\$1 . el \!.BP \\$1 .. Could some kind soul explain the working of this macro? The else branch looks like a recursve call. And why does plain .bp not work? Thanks for enlightenment, ulrich
[Groff] Problem with mom and multipage table
When I use the mom macros, in a multi page table, the first two lines on each output page are printed without vertical spacing, i.e. on top of each other. Is the a fix for this behaviour? (I also get warnings like these: warning: page 45: table text block will not fit on one page warning: page 46: table text block will not fit on one page warning: page 47: table text block will not fit on one page warning: page 48: table text block will not fit on one page ) Best, ulrich lauther
Re: [Groff] Problem with mom and multipage table
On Fri, Aug 23, 2013 at 01:22:58PM +0200, Werner LEMBERG wrote: > > When I use the mom macros, in a multi page table, the first two > > lines on each output page are printed without vertical spacing, > > i.e. on top of each other. > > Example, please. > > I attach a small example and the output generated by groff -t -P-l -P-pa4 -mom test.mom > test.ps Using groff version 1.21 and om.tmac Version 2.0-a_1 ulrich .PRINTSTYLE TYPESET .FAMILY N .FONT R .START .PT_SIZE 12 .TS tab(@); ln. 100@1000 101@1001 102@1002 103@1003 104@1004 105@1005 106@1006 107@1007 108@1008 109@1009 110@1010 111@1011 112@1012 113@1013 114@1014 115@1015 116@1016 117@1017 118@1018 119@1019 120@1020 121@1021 122@1022 123@1023 124@1024 125@1025 126@1026 127@1027 128@1028 129@1029 130@1030 131@1031 132@1032 133@1033 134@1034 135@1035 136@1036 137@1037 138@1038 139@1039 140@1040 .TE test.ps.gz Description: Binary data
[Groff] mom and .AUTOLEAD
Hi all, .AUTOLEAD seems to work only if given AFTER .START Proof: .PRINTSTYLE TYPESET .FAMILY N .FONT R .PT_SIZE 12 .AUTOLEAD 3 .START .LEFT pt_size set to 12 pt_size = \n[#PT_SIZE], lead = \n[#LEAD] .PT_SIZE 24 pt_size set to 24 pt_size = \n[#PT_SIZE], lead = \n[#LEAD] .AUTOLEAD 3 .PT_SIZE 12 pt_size set to 12 pt_size = \n[#PT_SIZE], lead = \n[#LEAD] .PT_SIZE 24 pt_size set to 24 pt_size = \n[#PT_SIZE], lead = \n[#LEAD] However, in http://www.schaffter.ca/mom/mom-04.html#examples it is given BEFORE .START .AUTOLEAD 1.5 \# \# Additional style macros--change mom's default behaviour \# .RECTO_VERSO \" Flip margins & headers on odd and even pages \# .HEADER_LEFT "Chang, Connors" .COLUMNS 2 1P+6p .SUBTITLE_SIZE +1.5 .AUTHOR_SIZE +.5 .DOCHEADER_LEAD+2p .HEADER_SIZE +1 .PARA_INDENT 1P .QUOTE_INDENT 2 .SUBHEAD_SIZE +0 .BLOCKQUOTE_FAMILY H .BLOCKQUOTE_SIZE -2 \# .COVER TITLE AUTHOR COPYRIGHT MISC \# .START Kind regards, ulrich
[Groff] question about .rs and .nop
The groff manual says: .rs Restore spacing; turn no-space mode off. However, .rs .sp 3 does not work; one has to output some text first, to get .sp to work. Is this a bug in groff, or in its documentation? What is the rationale for this behaviour? About the .nop request: .nop anything Always process anything. What is this request good for? Kind regards ulrich
Re: [Groff] question about .rs and .nop
On Sun, Aug 25, 2013 at 02:00:08PM -0400, Peter Schaffter wrote: > > > > Is this a bug in groff, or in its documentation? > > I wonder about that, too. The info manual says very clearly > > "This mode [.ns] ends when actual text is output or the `rs' > request is encountered..." > > Logically, therefore, .rs/.sp 3 should restore spacing and advance > 3v. > So, somebody more groff expert than me should file a bug report. > > About the .nop request: > > > > .nop anything > > Always process anything. > > > > What is this request good for? > > It's good for things like > > .rs > .nop \& > .sp 3 > > which is offers a solution to the .rs/.sp problem when you don't > want "actual text" to be output before the sp request. > and what´s the difference to .rs \& .sp 3 ? Cheers, ulrich lauther
Re: [Groff] question about .rs and .nop
On Mon, Aug 26, 2013 at 01:21:34AM +0200, Werner LEMBERG wrote: > > >> The groff manual says: > >> > >> .rs Restore spacing; turn no-space mode off. > >> > >> However, > >> .rs > >> .sp 3 > >> does not work; one has to output some text first, to get .sp to > >> work. > > I don't understand the problem. Can you please give a complete > example which I can directly compile with `groff -Tutf8'? > I cannot reproduce the problem with plain groff, but came across it when using macro packages like mm or mom. This demonstrates the problem: .PRINTSTYLE TYPESET .HEADER_LEFT "top" .START text1 .NEWPAGE .br .rs .br .sp 5 text2 .NEWPAGE text3 .NEWPAGE foo .br .sp 5 text4 Put above into file "test" and process with groff -mom -Tps test > test.ps; gv test.ps and see, how text2 and text3 are placed with the same distance to the header rule. For text4, groff finally honors the preceeding .sp 5 Cheers, ulrich
Re: [Groff] question about .rs and .nop
On Mon, Aug 26, 2013 at 12:41:53PM -0400, Peter Schaffter wrote: > > I don't know how ms handles this, but with mom, use the ADD_SPACE > macro after NEWPAGE. > > .NEWPAGE > .ADD_SPACE 5v > text2 > > ADD_SPACE exists precisely to solve the problem you're encountering. > It's documented in section 5.3.8 of the docs, > Yes, I had seen this. But I wanted to write a macro MyNewPage, that does exactly the same as NEWPAGE but does not leave me in nospace mode. When I call ADD_SPACE for this purpose, I need to give an amount of spacing. .ADD_SPACE 0v does'nt work .ADD_SPACE 1v works, but is different from NEWSPACE without nospace mode (one more blank line). .ADD_SPACE 1u works, but might be considered ugly. Instead I use now: .MAC MyNewPage END .NEWPAGE \& .br .sp -1v+1u .END which also is a bit ugly. Any suggestion for a clean solution? Nice would be a parameter to NEWPAGE that suppresses the nospace behaviour. BTW, I never understood why the formatting macro packages don´t like the user to put space at the top of their pages. Cheers, ulrich lauther
Re: [Groff] question about .rs and .nop
On Tue, Sep 03, 2013 at 01:40:31PM -0400, Peter Schaffter wrote: > On Tue, Aug 27, 2013, Ulrich Lauther wrote: > > However, when the user explicitely requests a new page, this seems > > not to be needed: he/she knows that following text goes to a new page > > and should be free to position it where he/she wants. > > In my case, I use groff/mom (in the past groff/mm) to generate slides. > > If a slide contains not much text, I want to start not at the very top. > > I'm not sure why > > .NEWPAGE > .ADD_SPACE > Slide text > > isn't satisfactory. It breaks to a new page and lets you place the > text where you want, which sounds like what you're after, though > apparently it's not. This works perfectly fine. My only problem is that the principle of least astonishment is violated: why have I to use ADD_SPACE instead of SP just because I am at the top of the page? Seems to me an unneeded complication. Is there a deeper reason to make SP disfunctional after an *explicit* page break? -ulrich
[Groff] mom: line spacing within a list ITEM
When the text of an ITEM needs more than one line, the spacing beetween these lines is larger than that of running text outside the list. (I am not talking about line space between items, but inside an item). Is this behaviour intended? If so, why? Can I change it? (This is a difference to lists of the mm-package). Kind regards, ulrich
Re: [Groff] Letterspacing
On Sun, Mar 30, 2014 at 03:15:13PM +0200, hoh...@arcor.de wrote: > > Peter Schaffter wrote (Thu, 27 Mar 2014 19:29:13 > -0400): > > On Thu, Mar 27, 2014, Tadziu Hoffmann wrote: > > > > > > KP posits that the solution to getting it right is to scan the > > whole paragraph. The number of words on each line is determined by > > choosing a line arrangment for the whole paragraph that minimizes > > the sum of the squares of the spaces at the ends of lines. IOW, > > an arrangement that strives to equalize wordspacing throughout the > > whole paragraph. > > It might be useful to investigate if not minimizing the maximum demerits would give even better results than minimizing their (squared) sum. This should easily fit into the dynamic programming framework. ulrich lauther
Re: [Groff] mission statement 3
On Wed, Mar 26, 2014 at 03:34:27AM -0500, Dave Kemper wrote: > > > But my fundamental complaint about Knuthian line-breaking is > > that anything that takes 66 journal pages to describe can't be > > right. > Most of the 66 pages are motivation, examples, and results. The description of the algorithm takes only about 5 pages and is not hard to understand for someone familiar with dynamic programming. ulrich lauther
Re: [Groff] Formatting algorithm
On Mon, Mar 31, 2014 at 07:44:07PM -0400, Peter Schaffter wrote: > Here's the bare bones version of the algorithm I was thinking of > when I proposed improving line formatting by getting groff to > shoulder the burden for some of the work we do manually. It's > written out in brute-force pseudo-code; should be pretty clear. > > The aim is not to find optimal breaks in Knuthian fashion, but to > improve the uniformity of grey from line to line using a greedy > algorithm. Key features are that letterspacing and wordspacing are > orthogonal, and that NextWord can be read during optimization. > Even if a greedy algorithm will be implemented, it should have the whole paragraph available as input. That way, one could easily switch over to a KP-implementation and compare the two appraoches in terms of quality, running time, and code complexity. Provided a clean interface and input/output specifications are available I would volunteer to implement the dynamic programming (KP) variant. Kind regards, ulrich lauther
Re: [Groff] Formatting algorithm
On Mon, Apr 14, 2014 at 12:41:56PM +0100, Ralph Corderoy wrote: > Hi Ulrich, > > > Even if a greedy algorithm will be implemented, it should have the > > whole paragraph available as input. That way, one could easily switch > > over to a KP-implementation and compare the two appraoches in terms of > > quality, running time, and code complexity. Provided a clean > > interface and input/output specifications are available I would > > volunteer to implement the dynamic programming (KP) variant. > > Perhaps it's gathering a whole paragraph together where the large amount > of change to groff lies, and not implementing KP itself. > > Cheers, Ralph. The proposed algorithm assumes # Assumptions # === [skipped] # NextWord: # - can be read from a buffer # and later on uses read NextWord If this function is available, it's easy to collect the paragraph: while (! paragraph ends) { read NextWord; store NextWord in paragraph_buffer; } But maybe just implementing "read NextWord" is the difficulty? ulrich -- -lauther
Re: [Groff] Formatting algorithm
On Tue, Apr 22, 2014 at 12:04:27PM -0400, Peter Schaffter wrote: > Ulrich -- > > But maybe just implementing "read NextWord" is the difficulty? > > After adjusting and breaking a line, groff holds remaining > input-line text as a partially-filled line, so reading NextWord is > at least theoretically possible. However, that's not the same thing > as gathering an entire paragraph, which, moreover, would have to be > delimited in some manner in the input file itself. And *not*, as > Clarke pleads, by assuming a block of text in one line is a > paragraph! > Well of course not. A paragraph ends, e.g. when an empty line is seen. Probably there are a whole lot of other conditions. My understanding is that formatting takes place after macros have been expanded; at the macro level it would be easier. So could the macros issue some hint (in form of a pseudo comment) when they realize that a paragraph has ended? > -- ulrich
Re: [Groff] Formatting algorithm
On Wed, Apr 23, 2014 at 07:30:34PM -0400, Peter Schaffter wrote: > On Wed, Apr 23, 2014, Ted Harding wrote: > > I think some confusion is possibly arising here. See in-line below. > > > > > Doesn't a paragraph logically conclude at any request which introduces a > > > break? Or invocation of any macro which itself invokes such a request? > > > (In addition to an empty input line, or one with leading white space, > > > which implies a break?) All of these exhibit one common feature: the > > > introduction of the break. > > > > I think I have to disagree here. For example, in the middle of a > > paragraph I may wish to put some text centred on lines by itself, > > and this may be in the middle of a sentence -- perhaps a parenthetical > > quotation. Or, in technical writing, a displayed equation in the > > middle of a sentence. > > This was my original thinking, but I'm inclined to see things > Keith's way now. The confusion you refer to arises from > terminology. There are logical paragraphs, which may include lists, > equations, quotes, and whatever other material logically belongs to > the paragraph, and there are "formatting paragraphs", if I may coin > a phrase, which refer to chunks of text that need to be adjusted. > > Any time you introduce a break, even within a logical paragraph, the > preceding text needs to be adjusted. I can't see any advantage to > including the text after an in-paragraph insertion in the adjustment > process, Yes, the preceding text needs to be adjusted. But why shouldn't the adjustment algorithm when working on one "physical paragraph" be allowed to "steal" one or more words from the next physical part of the logical paragraph. The advantage would be a better overall result due to a more global look at the optimization problem - at least theoretically. The more freedom is given to any optimization algorithm the better the result. Another question is, whether the improvement is worth the additional complexity - not of the algorithm itself, but of providing its input, i.e. collecting the logical paragraph and still dealing with inserts like equations and such. ulrich
Re: [Groff] Formatting algorithm
On Sat, May 03, 2014 at 02:23:10PM -0400, Peter Schaffter wrote: > > I suspect I'm a voice crying in the wilderness here, but we need to > consider that a greedy algorithm is almost always faster than a > dynamic programming solution; furthermore, greedy algorithms > sometimes lead to optimal solutions. "Optimal", in this case, > would entail both improved grey *and* preserving groff semantics. > > Food for thought. > I think, preserving groff semantics should not be part of the optimaltiy measure, but a hard constraint. It would be nice to have a formal definition of optimality and an interface that allows to plug in alternate algorithms/heuristics. "greedy algorithms sometimes lead to optimal solutions." yes, *sometimes* I have used greedy heuristics a lot in my time, but only when an exact algorithm (with reasonable speed) was not known. Dynamic programming can be quite fast and I don't see why any forking should be needed. ulrich lauther
Re: [Groff] Formatting algorithm
On Sun, May 04, 2014 at 02:59:19PM -0400, Doug McIlroy wrote: > > I don't see why any forking should be needed. > > I am all ears. I'd love to know a better way to cope with events > that are triggered by line breaks, when several different potential > line breaks are in play, as were discussed in my posting to which > Peter's referred. Forking is certainly unappealing, though in the > future of multicore processors it may not be as daunting as before. > > It seems there's an awful lot of state that may potentially vary > with line breaks. Forking is an easy way to cope. My question > remains: is there a better way? > > Doug In dynamic programming we maintain a set of optimum partial solutions, each stored as a node in an acyclic directed graph. Edges of the graph indicate from which partial solution an extended partial solution was derived. Finally we end up with a set of complete solutions, pick the best one and follow the path in the graph to recover the decisions made to arrive at this best solution. Afterwards all nodes of the graph a thrown away, i.e., they can be used to solve the next problem - in our case, the next paragraph. Often, useless nodes can already be discarded before the final solution is found. All this could possibly also be implemented using recursion and/or forking, but that would be less efficient (in terms of memory and running time needs) and - in my opinion - also harder to understand. Kind regards, ulrich
Re: [Groff] [groff] Formatting algorithm
On Thu, May 08, 2014 at 04:17:16PM -0400, Doug McIlroy wrote: [...] > I fully agree with the first paragraph. However, as there is essentially no > limit on the amount (or kind) of path-dependent state that may be needed > to calculate each partial solution, I see forking as the easiest way to > implement the recipe. [...] > Thanks for the elaborate discussion of your ideas. But a short question: Does TeX use forking for formatting? If not, are its results considered unsatisfactory or worse than what we are aiming at? Kind regards, ulrich
Re: [Groff] [groff] Formatting algorithm
On Fri, May 09, 2014 at 10:48:08AM +0100, Denis M. Wilson wrote: > The method used in TeX is the shortest path in a directed acyclic graph. > This is a well-understood problem. There seems unfortunately to be > nothing useful in the STL. The DAG would need to be a new data type. > To build and use a DAG we need - in general - a node-object and an edge-object. The node contains a list of outgoing edges, the edge points to its target node and contains its length (or cost). Possibly finding the shortest path and building the graph can be combined. In that case, we do not need any edges, just a pointer in the node to the "best" predecessor from which it was derived and the correspondig path length. > The real problem is assigning the values in the DAG. Something of the > sort must already be in Heirloom troff. > and in the KP paper. > As there are no modes in troff, I agree with Peter that new commands to > begin and end a paragraph are required. A careful review of the effect > of any troff command needs to be done, even possibly restricting the > effects of some. > > This is the time to introduce shaped paragraphs (also in Heirloom > Troff). > > IMHO the KP method *should* be used -- if anyone is going to do > anything at all. It's not going to be me, I'm too old. It's going to be > hard work, bit doable (Gunnar did it). May I ask how old you are? (I am 71 years old). ulrich
Re: [Groff] [groff] Formatting algorithm
On Fri, May 09, 2014 at 01:12:14PM +0100, Roger Leigh wrote: > On Fri, May 09, 2014 at 01:07:02PM +0200, Ulrich Lauther wrote: > > On Fri, May 09, 2014 at 10:48:08AM +0100, Denis M. Wilson wrote: > > > The method used in TeX is the shortest path in a directed acyclic graph. > > > This is a well-understood problem. There seems unfortunately to be > > > nothing useful in the STL. The DAG would need to be a new data type. > > > > > To build and use a DAG we need - in general - a node-object and an > > edge-object. > > The node contains a list of outgoing edges, the edge points to its target > > node > > and contains its length (or cost). > > The Boost Graph Library (BGL) does all this and has algorithms for > searching, traversal etc. The nodes and edges are templated and you > can attach arbitrary data to them. This might not be a dependency > you'd want in groff, but just mentioning it in case it's potentially > useful. > Yes, I know. The same holds for LEDA and the TURBO-library developed by myself (unfortunately proprietory). But the needed data structures are so simple that dragging in another library seems overkill. > > Regards, ulrich
Re: [Groff] Formatting algorithm, an experiment
On Mon, Mar 31, 2014 at 07:44:07PM -0400, Peter Schaffter wrote: > Here's the bare bones version of the algorithm I was thinking of > when I proposed improving line formatting by getting groff to > shoulder the burden for some of the work we do manually. It's > written out in brute-force pseudo-code; should be pretty clear. > To get a feeling for formating alternatives I implemented a simplified version of the Knuth-Plass algorithm. The idea is, to pack charakters as dense as possible and to minimize the maximum gap at the end of any line. In a second pass intra- and interword spacing could then be adjusted along the lines of the heuristic proposed by Peter Schaffter. To make tests realistic I implemented a primitive hyphenation algorithm that sometimes works :-) Character widths were taken from /usr/share/groff/1.21/font/devps/HR For speed up, I first use a greedy algorithm and employ its result as an upper bound for any gap in the dynamic programming solution. However, the speed-up achieved that way seems to be minimal. I tested with an English paragraph containing 775 words (before hyphenation): "In olden times, when wishing still did some good, there lived a king whose daughters were all beautiful, ...". This is a stand-alone program, just for a feasibility test. It reads a text (which is considered one paragraph), and runs the formatter. Results: Lines of code 370 plus 184 for my linked list class. The core algorithm takes just 95 lines of code. Break-objects generated: 823 or 0.9 per hyphenated syllable. After formatting, these objects go into a list of garbage and can be reused for the next paragraph. Running time under Ubuntu on Intel(R) Atom(TM) CPU N455 @ 1.66GHz: Less than one millisecond when compiled with g++ -O4. I used a line length of 100 times the width of the space-character. The maximum gap at the end of any lines was: greedy: 10.6 spaces KP: 7.1 spaces I think, the experiment shows that running time is no issue at all. Kind regards, ulrich
Re: [Groff] groff variable for ideal
On Mon, Jun 16, 2014 at 11:24:46PM +0100, Ralph Corderoy wrote: > Hi Bernd, > > > A `groff' option for running the `gideal' preprocessor is needed. > > Only once the preprocessor has a significant enough audience to make it > worthwhile? Meanwhile, it can continue to be explicitly pipelined? > The way I handle preprocessors and other options, is, to put them into a (pseudo-) comment in the first line of a document, like e.g.: .\" tbl eqn lnd This line is interpreted by my groff shell script and I can never forget to run the required preprocessors and to set the appropriate optoins (landscape in the example). Cheers, ulrich
[Groff] My way to run preprosessors and to set options
On Tue, Jun 17, 2014 at 11:13:26PM +0200, Bernd Warken wrote: > > Von: "Ulrich Lauther" > > > > The way I handle preprocessors and other options, is, to put them into a > > (pseudo-) comment > > in the first line of a document, like e.g.: > > > > .\" tbl eqn lnd > > > > This line is interpreted by my groff shell script and I can never forget to > > run the required > > preprocessors and to set the appropriate optoins (landscape in the example). > > That sounds very good. Did you already implement that for general groff? > No, I am not (yet?) a groff contributer. But I could publish my script, if there is general interest. ulrich lauther
Re: [Groff] My way to run preprosessors and to set options
On Wed, Jun 18, 2014 at 10:48:51AM +0200, Bernd Warken wrote: > > No, I am not (yet?) a groff contributer. But I could publish my script, if > > there is general interest. > > Please publish your script! The implementation in `grog' would be very easy. > But `groff.cpp' > needs C++, which is still quite hard. > > It would be useful as well, if the `tmac' name is included as well: man, > mdoc, me, mm, me, mom, etc. > For it is often hard to discover with `grog' and `groffer' which `tmac' > should be there, e.g. the > difference of `man' and `ms'. > It is attached and might need some adjustments according to individual needs. Some comments: The default macro package is mm, man and mom are also supported. The script "addtbl" adds numerical entries of specified table colums and writes new table lines containing the respective sum. The script "squezetbl" eliminates leading and trailing blanks from table entries Have fun, ulrich #! /bin/bash [ $# = 0 ] && { echo usage: $0 [ -f out ] file exit } PRE= OPTS= OUT= PDF= MAC=mm while [ $# != 0 ] do case "$1" in -f) shift OUT=$1 ;; -man) MAC=man ;; -l) # landscape FORM=lnd ;; -pdf) PDF=1 ;; *) FILE="$1" # check for .\" eqn tbl add lnd eng mom for i in `read x < $1; echo $x` do case $i in eqn) OPTS="$OPTS -e" ;; lnd) FORM=lnd ;; tbl) OPTS="$OPTS -t" PRE="$PRE | squezetbl " ;; add) PRE="$PRE | addtbl " ;; eng) longdash="\40-\40 (em" ;; mom) MAC=mom ;; *) : esac done ;; esac shift done case $FILE in *.mom) MAC=mom; BASE=${FILE%.mom} ;; *) BASE=$FILE esac [ "$OUT" = "" ] && OUT=${BASE}.ps case "$MAC" in mom) SO="/home/privat/bin/defines.mom" ;; mm) SO="/home/privat/bin/roffinit" if [ "$FORM" = lnd ] then OPTS="$OPTS -r L=21.12c -r W=23.95c -r O=2.8c" else OPTS="$OPTS -r L=29.00c -r W=15.75c -r O=2.5c" fi ;; *) esac OPTS="$OPTS -$MAC" if [ "$FORM" = lnd ] then OPTS="$OPTS -P-l -P-pa4" else OPTS="$OPTS -P-pa4" fi echo "{ cat $SO; cat $FILE $PRE } | groff -Tps -k $OPTS - > $OUT" eval "{ cat $SO; cat $FILE $PRE } | groff -Tps -k $OPTS - > $OUT" [ "$PDF" = 1 ] && ps2pdf $OUT $BASE.pdf echo done
Re: [Groff] Three topics related to images
On Thu, Jun 19, 2014 at 03:40:42PM +0200, mikkel meinike wrote: > Hello all > I have during the past two years become increasingly groff user or perhaps > more specifick mom uses. I try as much as possible to stick to one macro > package to keep my text setting life as simple as possible. I am a human > being who work with images and therefore I also come a long way by now with > pictures in mom, but now I come to a point where I have a few questions > about this topic. > > To place two images side by side. > How to place to two or more images side by side. HTML treateds a little > picture almost as if it were a text item. If you put two pictures in the > code after eatch other then they appear side by side (if there is space for > that on the line). Can you do something similar in groff or what does it > take to put two pictures up next to each other? > Here is an example of how I do it usually: Finding a shortest path from node $a$ to node $e$ using Dijkstra's algorithm: .P .mk .PSPIC -L dijkstra.eps 10c .rt .sp -0.7v .PSPIC -R dijkstra2.eps 10c Why the ".sp -0.7v" is needed to achieve alignment, is mystery to me. Could somebody explain? Now, that I think about it, it might be possible to put the images into a table. But I never tried that. Cheers, ulrich
Re: [Groff] My way to run preprosessors and to set options
On Thu, Jun 19, 2014 at 10:33:01PM +0200, Bernd Warken wrote: > > Von: "Ulrich Lauther" > > > .\" tbl eqn lnd > > I understand that `lnd' has to do with `landscape'. > Is that something useful for `groff' or `mm'? > Where did you get this idea? > yes, it stands for landscape and I use it when I prepare a talk (or overhead foils in former times). Is there a better way to do this? ulrich
Re: [Groff] Three topics related to images
On Fri, Jun 20, 2014 at 11:49:51AM +0200, Tadziu Hoffmann wrote: > > > It looks like -mm but the misalignment doesn't happen when > > I try it. > > Ulrich: Perhaps then the bounding box of one of the pictures is > wrong? Does it also happen if you use the same picture twice? > Sorry, it was my fault: the two pictures of a network were nearly identical, but with different text labels. On the righthand picture, one of the labels was placed too far up. Sorry again, ulrich
Re: [Groff] Formatting algorithm, an experiment
In the meantime I have send the tgz-file directly to Dough, not to the list, and he was able to read it. Waiting for comments, ulrich
Re: [Groff] Formatting algorithm, an experiment
On Fri, Jun 27, 2014 at 03:43:24PM +0200, Steffen Nurpmeso wrote: > > Oh, after fiddling with unsupported linker options etc. to compile > the showcase i got a SIGBUS. You know, as in "Bus stop, wet day, > she's there" etc. Only the umbrella is still missing. > Ciao, > > --steffen Not clear to me, if the comment refers to my code or to the groff formatting discussion. If the first, could you provide details? Peter Schaffter had no problem compiling and running the code. Cheers, ulrich
Re: [Groff] Formatting algorithm, an experiment
On Fri, Jun 27, 2014 at 08:06:38PM +0200, Steffen Nurpmeso wrote: > Hello Ulrich, > [ ... ] > (But again, i personally never had a problem with the typesetting > quality of troff (with the TeX-borrowed German hyphenation > enabled), proof-reading provided -- the German translation of > K & R "Programming in C" 2nd Edition has been typeset like that > (by the translators Prof. Dr. Schreiner and Dr. Janich) which > actually convinced me -- recalling its quality -- to try to go > troff (after loosing our setup). Actually, I don't have a problem with groffs typesetting either. As I pointed out in my comments to Peter, the fine points of typesetting are beyond me, but obviously more sophisticated users do see a need for improvement. But my contribution was triggered by the discussion on the groff mission statement and on pro and cons of the Knuth/Plass algorithm and its alleged complexity. So I was motivated to share my experience in implementing mathematical optimization solutions. Cheers, ulrich
Re: [Groff] Overview, Sept. 2014
On Wed, Sep 10, 2014 at 09:57:31AM +0100, Ralph Corderoy wrote: > Hi, > ... > > That's my favourite. Its conventions might be different, given its age, > but I think it's pretty consistent. Enthusiasm for anything other than > trivial changes in style would soon wear thin if bugs were being > introduced. And given the limited scope of the code base, is wrapping > every man and his dog in a setter()/getter() really needed just because > it seems the norm in the C++/Java world? (The code isn't really C++, > more C with Classes.) > you may be right about setter()/getter() usage; other modifications would really improve readability and maintainability: - capitalization of class names - a naming convention for class member variables - reducing the number of global variables - for each class a block of comments explaining what the class is all about > Cheers, ulrich -- -lauther
Re: [Groff] Overview, Sept. 2014
On Wed, Sep 10, 2014 at 12:16:06PM +0200, Werner LEMBERG wrote: > > > you may be right about setter()/getter() usage; > > He is definitely right! :-) > > > other modifications would really improve readability and > > maintainability: > > - capitalization of class names > > - a naming convention for class member variables > > Mhmm, this is much work, and I don't see immediate benefits. IMHO, > groff's C++ code is quite clear, and I ask you to show an example > where `readability and maintainability' could be *really* improved by > using uppercased stuff – I need more than a `we have learnt that in > school' to be convinced. I didn't learn it school (when I went to school, computer science was not yet around) but the hard way in 30 years of C++ programming. > Additionally, `git blame' would become much more inconvenient to use. > I am not familiar with git and git blame, used cvs in my active time. Could you explain, what the problem with upper case class names and git blame would be? > > - reducing the number of global variables > > Why? Again, please provide an example that could benefit. > because it is toublesome to find out where they are initialized, modified, and read. ulrich
Re: [Groff] Overview, Sept. 2014
On Wed, Sep 10, 2014 at 03:55:12PM +0200, Werner LEMBERG wrote: > > > Because it consumes space in BSS, or DATA -- and then even causing > > linker work upon loading time, even if never used. > > A program with a DATA section is shit ;) > > Well, I don't care :-) groff uses static constructors to initialize > some of the global variables, this is a very nice and elegant feature > of C++. > > The problem with global variables is their long range effect, comparable with the infamous goto statement: considered harmful. ulrich
Re: [Groff] Overview, Sept. 2014
On Wed, Sep 10, 2014 at 05:29:13PM +0200, Ingo Schwarze wrote: > Hi Ulrich, > > Ulrich Lauther wrote on Wed, Sep 10, 2014 at 01:01:37PM +0200: > > On Wed, Sep 10, 2014 at 12:16:06PM +0200, Werner LEMBERG wrote: > > >> Additionally, `git blame' would become much more inconvenient to use. > > > I am not familiar with git and git blame, used cvs in my active time. > > Could you explain, what the problem with upper case class names > > and git blame would be? > > You got that wrong. ;-) > > Git blame is almost exactly the same as cvs annotate, > which should answer your question. > > Actually, familiarity with CVS can greatly help you to quickly get > going with some features of git - and it can also mislead you to > get confused about some other aspects of git. I tried that half a > decade ago... > > Some things work more or less similarly in git: > > * cvs co module -> git clone module >Except that it also mirrors the whole repo including history. > * cvs log -> git log >But it only shows the ancestors of one given commit, >there is no notion of "all (even later) versions of a file". >And as opposed to CVS history, git history is not linear. > * cvs annotate-> git blame > * cvs diff-> git diff (and git show) > * cvs status -> git status (well, kind of) > * cvs co tag -> git checkout ref > * cvs up -> git pull >Only vaguely similar and full of traps for the unwary; >when getting confused, it may help to do git fetch >and git merge separately and explicitly, even though >that isn't quite simple to get right, either. > * cvs up -C -> git reset --hard > * cvs add file-> git add file > * cvs rm -> git rm > * cvs tag (no -b) -> git tag > > Some things are completely different: > > * cvs init-> not needed, no replacement >Every git module is a stand-alone repo. >Consequently, you don't usually do things like cvs rdiff. > * cvs import -> not needed (what a relief!) >It can all be comfortably done with git init / git add / git push. > * cvs co rev file -> absolutely impossible in git >You can only change the branch or commit of the whole repo at once. > git checkout ref file >Is more similar to cvs up -j, but you normally don't do that, >you rather use git merge or git cherry-pick or git revert, >all of which commit right away (without pushing) > * cvs add dir -> not needed, no replacement > git add directory >Does something completely different, never do that coming from CVS. > * cvs commit -> completely different concept >The whole git add / git commit / git push three-step concept >feels EXTREMELY confusing and contorted when coming from CVS. >This is a point you really want to spend time on to thoroughly >understand the git mindset. > * cvs tag -b -> git branch and git checkout -b >These may seem superficially similar, but the whole concept of >branches is completely different. The concept of git is both >simpler and more powerful, which i consider git's main asset. >This is another aspect you really want to spend time on >to thorougly understand. >In CVS, you typically use tag -b very rarely. >In git, you use checkout -b (and reset) all the time. >Somewhere in the middle of this, you need to understand the >difference between git checkout and git reset >even though the latter has no CVS analogue short of >cvs tag -bF which you almost never do in CVS >but which is a common operation when working with git. >As a last step in this area, you must learn about >git rebase even though there is no equivalent in CVS and >even though you need to be very careful with it after push. > * cvs admin -m-> absolutely impossible in git by design >No replacement that keeps other people's checkouts working. > * cvs admin -o-> absolutely impossible in git by design > * git stash >Doesn't exist in CVS, but you will definitely find use for it. > > Most definitely, you want to read gitrevisions(7). That will teach > you about the complexity of git (some might cry "overengineering"), > but you won't find your way around any git repo without understanding > at least some bits of that. > > Ulrich, I hope the above table helps you to find your way around > the git manuals - which tend to be somewhat wordy and long-winded, > hardly avoidable given the overabundance of features coming with > git. > > Yours, > Ingo Thanks a lot! ulrich
Re: [Groff] Overview, Sept. 2014
On Wed, Sep 10, 2014 at 01:23:41PM +0200, Werner LEMBERG wrote: > > >> Additionally, `git blame' would become much more inconvenient to > >> use. > > > > I am not familiar with git and git blame, used cvs in my active > > time. Could you explain, what the problem with upper case class > > names and git blame would be? > > Please say `git help blame' on the command line and read this > command's manpage :-) > well, I know how to find and read man-pages. But I was confused about the connection you made between moving to upper case class names and git blame. I guess, what you really wanted to say is that ANY nonfunctional change would lead to "false reports" of git blame. Right? ulrich
Re: [Groff] Overview, Sept. 2014
On Wed, Sep 10, 2014 at 08:02:30PM +0200, Werner LEMBERG wrote: > > > The problem with global variables is their long range effect, > > comparable with the infamous goto statement: considered harmful. > > I like `goto' a lot, and it is an invaluable instruction if used with > care. Yes, e.g., for breaking out of a inner loop. > The same is true with global variables. Sorry to say, but we > are now going into hearsay and hollow statements, which isn't helpful. > > It's now the third time that I ask for a real example in groff's code > that you consider irritating. > I'll hopefully come back to that after more code reading. ulrich
Re: [Groff] Overview, Sept. 2014
On Wed, Sep 10, 2014 at 10:16:47PM +0200, Werner LEMBERG wrote: > > > I may have to look into this C++ stuff. I have only written C and I > > have not figured out how to write multi-threaded applications > > without global variables. And I make good use of goto and > > longjmp. Apps would be a lot junkier without them. > > Well, right now groff's C++ is essentially C code with some useful > additions. It doesn't use `high-level' C++ concepts like templates > (although there is at least one place where this would be useful to > avoid macro trickery). > That templates are not used is a GOOD THING. Templates are great when you write a library, but should be used sparingly in applications. (Of course, there are exeptions, just as with goto's and globals). ulrich
Re: [Groff] Overview, Sept. 2014
On Thu, Sep 11, 2014 at 01:11:40PM -0400, James K. Lowden wrote: > On Wed, 10 Sep 2014 11:49:37 +0200 > Ulrich Lauther wrote: > > > other modifications would really > > improve readability and maintainability: > > - capitalization of class names > > - a naming convention for class member variables > > - reducing the number of global variables > > You want to tread lightly where style is concerned. Whether or not > something is more "readable" depends very much on what you're used to. > There's no consensus in the C ++ community at large on the above > recommendations. > > Many people are accustomed to capitalizing classes and decorating > member names. I think the first is a requirement in Java, and the > latter was popularized by Microsoft's ugly "m_varname" convention. In > his books, Stroustrup uses capitalized class names and ordinary, > undecorated variable names. > > Stroustrup has observed that if you ask a room of experts for > suggestions on how to improve C++ and make it more accessible to the > beginner, you'll be deafened by silence. If you want a lively > discussion, he says, ask where the curly braces should go. > > > - for each class a block of comments explaining what the > > class is all about > > For this particular suggestion to appear on the groff list is a little > ironic, no? Since the epoch Unix source code has been documented with > man pages adjacent to the source in the tree, with its rich formatting > features. Surely in-line text-only documentation as comments would be a > retrograde step, and a long one at that? Else we might as well close > up shop and rename the project Doxygen! > As I understand it, the man-pages are directed at the user of a program who wants to know WHAT a program is supposed to do and how she can control it via options. Comments in the source are directed at the programmer, who wants to understand HOW the functionality of the program is accomplished. I think, these are two totally different cups of tea. I am not a friend of overloading code with comments, like a++; // a is incremented but I doubt that a sophisticated mathematical algorithm, e.g., Knuth/Plass's dynamic programming approach to paragraph formatting could be understood without some helpful comments, including - the task a class is supposed to do or the role these object(s) play - the role of key variables - pseudo code of non-trivial algorithms - pointers to relevant literature All this is not to be found in the man-page and does not belong there. ulrich
Re: [Groff] Overview, Sept. 2014
On Thu, Sep 11, 2014 at 05:46:22PM -0400, James K. Lowden wrote: [ ... ] > If by "all about" Urich meant a sentence or two, sure, a comment block > is fine. If by "all about" he meant a description of the semantics of > the public interface (which is what I thought he meant) then ISTM that > belongs in a manual, not in the source code. N'est-ce pas? > I was NOT referring in any way to semantics or public interface, but to the inner workings of the implementation and how to make it understandable to a later maintainer (or to the original programmer after a few years). That should have been clear from the previous discussion on programming style. To give an example: The seemingly trivial string searching function strstr() can be implemented using sophisticated algorithms like Rabin–Karp algorithm, Knuth–Morris–Pratt algorithm, Boyer–Moore string search, ... Their description belongs NOT into the man-page (though a hint about the time-complexity would be nice). But to understand the source code would be impossible without explanations and pointers to the relevant literature. ulrich
Re: [Groff] PDFPIC macro
On Sun, Sep 21, 2014 at 03:29:18PM +0100, Keith Marshall wrote: > > > > Yes, it is. Someone on the list has contacted me, with a view to writing > > the > > code, > > Who might that be? If it was off-list, then we have a problem -- we all > need to be kept in the picture, with this sort of stuff. I ask because... > > > and I have provided the perl version. > > I have not seen this, nor any pointer to it, yet I have already begun to > explore possibilities at the C/C++ level. I don't want to waste my time > duplicating someone else's effort, but I would need some help to find my > way through perl code. > It was me, who asked for the perl code and got it just today. I did not yet start any work on it, just a quick look at the code to find out how difficult translation to C++ would be. If you a going to implement a C/C++ version, I won't proceed. So far I did not post on the list, because I had not yet decided to work on this. Deri provided also a link to the pdf-documentation, which unfortunately consists of 978 pages: wwwimages.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf Deri also gave some hints on the structure of pdf documents, which he might post to the list. > Regards, ulrich -- -lauther
Re: [Groff] new automake system
On Mon, Sep 22, 2014 at 01:17:39AM +0200, Bernd Warken wrote: > > I would improve your install commands a bit into: > > test -d old && rm -rf old > test -d groff && mv groff old > git clone git://git.savannah.gnu.org/groff.git > cd groff > git checkout automake2 > ./bootstrap > mkdir build > cd build > ../configure > make -j > > Bernd Warken To make this work on my ubuntu 12.04 LTS „Precise Pangolin“ system I had to apt-get install autoconf automake libtool texinfo bison flex and then to install automake 1.12.2 from source, as the version 1.11.3 that came with apt-get install autoconf was rejected as too old. Cheers, ulrich
Re: [Groff] new automake system
On Mon, Sep 22, 2014 at 01:17:39AM +0200, Bernd Warken wrote: > I would improve your install commands a bit into: > > test -d old && rm -rf old > test -d groff && mv groff old > git clone git://git.savannah.gnu.org/groff.git > cd groff > git checkout automake2 > ./bootstrap > mkdir build > cd build > ../configure > make -j > I did the bootstrapping as described and then 'make dist' to generate a groff-1.22.2.tar.gz. I expanded this file at some other place, went into the new groff-1.22.2 directory and typed ./configure --prefix=/home//groff_test make make install Now whe I type 'groff_test/bin/groff -v I get : GNU groff version 1.22.2 Copyright (C) 2013 Free Software Foundation, Inc. . . called subprograms: groff_test/bin/groff: can't find `DESC' file groff_test/bin/groff:fatal error: invalid device `ps' However, ls -l groff_test/share/groff/1.22.2/font/devps/DESC gives me -rw-r--r-- 1 privat privat 189 Sep 24 22:12 groff_test/share/groff/1.22.2/font/devps/DESC Probably I did something utterly silly, but no idea what. Please help a poor struggler! ulrich
Re: [Groff] new automake system
On Thu, Sep 25, 2014 at 01:13:19AM +0200, Bertrand Garrigues wrote: > Hi Ulrich, > Hm ... I see no obvious mistake in your commands, and could not > reproduce the problem. I have no idea of what's going on. Could you > please apply the attached patch to trace the error we have when > attempting to open the DESC file ? > I made some research and found: 1. with ./configure; make ./configure --prefix=/home/privat/groff_test; make; make install groff_test/bin/groff -v I get Failed to open /usr/local/share/groff/site-font/devps/DESC: No such file or directory Failed to open /usr/local/share/groff/1.22.2/font/devps/DESC: No such file or directory Failed to open /usr/lib/font/devps/DESC: No such file or directory This may be a fault on my side, not to use "make clean" after changing the prefix; or missing dependencies? 2. I then tried make clean; ./configure --prefix=/home/privat/groff_test; make; make install and got Failed to open /home/privat/groff_test/share/groff/site-font/devps/DESC: No such file or directory 3. Finally I did make distclean; ./configure --prefix=/home/privat/groff_test; make; make install and got the same result: Failed to open /home/privat/groff_test/share/groff/site-font/devps/DESC: No such file or directory The directory /home/privat/groff_test/share/groff/site-font exists, but is empty. The needed DESC-file is in groff_test/share/groff/1.22.2/font/devps, not in groff_test/share/groff/site-font/devps Cheers, ulrich
Re: [Groff] new automake system
On Fri, Sep 26, 2014 at 10:52:49AM +0200, Bertrand Garrigues wrote: > Hi Ulrich, > > > No, you found a bug ... > > > not to use "make clean" after changing the prefix; or missing > > dependencies? > > The groff binary is not rebuilt, because defs.h was not regenerated, and > thus defs.h still have the old paths. On master, defs.h is forced to be > rebuilt. > > defs.h: FORCE > [...] > FORCE: > > I tried another solution, adding a dependency between defs.h and > config.status (config.status is generated by configure). It works on my > environment, could you please test it ? > o.k. I'll test it. > > 2. > > I then tried > > make clean; ./configure --prefix=/home/privat/groff_test; make; > > make install > > and got > > Failed to open > > /home/privat/groff_test/share/groff/site-font/devps/DESC: > > No such file or directory > > > > 3. > > Finally I did > > make distclean; ./configure --prefix=/home/privat/groff_test; make; > > make install > > and got the same result: > > Failed to open > > /home/privat/groff_test/share/groff/site-font/devps/DESC: > > No such file or directory > > > > The directory /home/privat/groff_test/share/groff/site-font exists, but is > > empty. > > > > The needed DESC-file is in groff_test/share/groff/1.22.2/font/devps, > > not in groff_test/share/groff/site-font/devps > > Calling 'make clean' or 'make distclean' fixed your problem. The error > message you got (missing file in site-font) is normal and comes from the > additional traces I gave you. We first try to use the fonts in site-font > in priority (directory where the user can manually add its own fonts), > and then only the default directory in share/groff/1.22.2/font/devps. > As I understand the patch leads to termination when the file is not found in site-font. Wouldn't it be better to terminate only after all possible places have been checked and then give a message "DESC could neither be found in site-font nor in /share/groff/1.22.2/font" or similar and then keep this code in the official version? > Regards, > ulrich
Re: [Groff] new automake system
On Fri, Sep 26, 2014 at 10:52:49AM +0200, Bertrand Garrigues wrote: > Hi Ulrich, > > > This may be a fault on my side, > > No, you found a bug ... > > > not to use "make clean" after changing the prefix; or missing > > dependencies? > > The groff binary is not rebuilt, because defs.h was not regenerated, and > thus defs.h still have the old paths. On master, defs.h is forced to be > rebuilt. > > defs.h: FORCE > [...] > FORCE: > > I tried another solution, adding a dependency between defs.h and > config.status (config.status is generated by configure). It works on my > environment, could you please test it ? > yes, with your defs.patch applied (and the other patched stuff removed) it works: groff -v now gives: GNU groff version 1.22.2 Copyright (C) 2013 Free Software Foundation, Inc. [disclaimer stuff] called subprograms: GNU grops (groff) version 1.22.2 GNU troff (groff) version 1.22.2 Thank you, ulrich
[Groff] understanding groff's source code
Hi, I am trying to read and understand groff source code, which is - at least for me - not easy. In case of questions, should one ask on the list or are there specialists who are able and willing to help? An example: In input.cpp there is a linked list class "node_list". Member functions are not commented, but what length(), append(), constructor and destructor do is obvious. However, not so for extract(). One would expect that an element of the list is extracted - as the list is singly linked, the first element - and that the rest of the list stays intact. However, head and tail are set to zero, i.e. the list becomes empty. But what happens to the other elements? Are memory leaks generated? Why is delete_node_list() not called? And btw. why is node_list in input.cpp but delete_node_list() in node.cpp? As I remarked in an earlier post, a short explanation explaining the idea of a class would be VERY helpful. E.g., what does a node-object represent? Here the reader is left in the dark. Cheers, ulrich
Re: [Groff] understanding groff's source code
On Mon, Sep 29, 2014 at 09:05:48AM +0100, Ralph Corderoy wrote: > Hi Ulrich, > > > In case of questions, should one ask on the list > > I'd say ask here; answers would be part of the public record. These > answers are all based on a quick look; I don't know they're correct. > > > However, not so for extract(). > > node *node_list::extract() > { > node *temp = head; > head = tail = 0; > return temp; > } > > The list is extracted, not a node; a pointer to the first element, if > any, is returned. The caller can walk the list themselves. The > node_list forgets about those elements. > Thanks for the explanation! Things would be easier if there were minimal comments, like so: class node_list { // a singly linked list of nodes void node_list::append(node *n) // appends node n to the list node *node_list::extract() // removes all elements from the list, which thus becomes empty. // returns a chain of nodes that had been in the list, i.e., the first // element of that chain, or zero if the list was empty. > Cheers, ulrich
[Groff] order of PRINTSTYLE and other requests in mom
Hi, the mom-docu says: As mentioned above, PRINTSTYLE TYPESET must come before any changes to mom’s default typographic settings. For example, .PAPER A4 .LS 14 .PRINTSTYLE TYPESET will not changes mom’s default paper size to A4, nor her default document leading [to] 14 points, whereas .PRINTSTYLE TYPESET .PAPER A4 .LS 14 will. However, my file .\" mom lnd .PAGEWIDTH842p .PAGELENGTH 595p .PRINTSTYLE TYPESET .PT_SIZE 90 .sp 10c Newly painted! prints "Newly painted!" in big letters and landscape, as intended. However, if I move the .PAGE* requests down, after .PRINTSTYLE, they are ignored and the output looks like Newly painted! So who is wrong? mom, the docu, or my understanding? Cheers, ulrich
Re: [Groff] order of PRINTSTYLE and other requests in mom
On Sun, Oct 05, 2014 at 01:25:54AM -0400, Peter Schaffter wrote: > Ulrich -- > > PRINTSTYLE requires page dimensions in order to set the margins, > and uses whatever is in effect. PAGEWIDTH, PAGELENGTH and PAPER > can, in fact, come before PRINTSTYLE. However, I'm averse to the > word "except" in documentation, so this is not mentioned. I will, > however, update the PAGEWIDTH section to mention the possible need > for setting a line length. > > Final note: In the example you sent, PRINTSTYLE is unnecessary > and probably shouldn't be there. PRINTSTYLE is required only for > document processing, not straightforward typesetting. > > Hope this clears things up. > Yes, thanks a lot. I now see that PRINTSTYLE is described in 5.3.3.2, i.e. clearly as part of "5. DOCUMENT PROCESSING WITH MOM". BTW, there are two typos: will not changes mom’s default paper size to A4, nor her default document leading 14 points, whereas should be will not change mom’s default paper size to A4, nor her default document leading of 14 points, whereas BTW2 I was expecting besides .PAPER A4 something like .PAPER A4 LANDSCAPE but couldn't find any mention of "landscape" in the docu. Of course, with .MAC LandScape END . PAGE 842p 595p 2.5c 2.5c 2.5c 2.5c .END I can do it, but .PAPER A4 LANDSCAPE would be convenient. Cheers, ulrich
Re: [Groff] order of PRINTSTYLE and other requests in mom
On Sun, Oct 05, 2014 at 04:37:40PM -0400, Peter Schaffter wrote: > Ulrich -- > > On Sun, Oct 05, 2014, Ulrich Lauther wrote: > > BTW, there are two typos: > > will not changes mom’s default paper size to A4, nor her > > default document leading 14 points, whereas > > > > should be > > will not change mom’s default paper size to A4, nor her > > default document leading of 14 points, whereas > > Aha! From this little bit, I discovered that a) you're not reading > the most up-to-date documentation, and b) I forgot that the PAPER, > PAGEWIDTH, and PAGELENGTH order wrt PRINTSTYLE had already been > dealt with in 2.0-b! (Yes, as an exception.) I suggest updating > your mom installation from the repo (current mom version is 2.0-c) > or grabbing the tarball from the mom site: > > http://www.schaffter.ca/mom/mom-2.0-c.tar.gz > o.k., did it. So the mom version in http://ftp.gnu.org/gnu/groff/groff-1.22.2.tar.gz is outdated. > > BTW2... > > .PAPER A4 LANDSCAPE > > would be convenient. > > I'll add it to the next release. > Thanks a lot! > Cheers. > ulrich
Re: [Groff] PDF_IMAGE and MOM
On Sun, Nov 02, 2014 at 11:45:48AM +0100, mikkel meinike wrote: > > #Removes the file extension so I only have the base name > > rose=`echo "$1" |sed 's/.pnm//'` > A simpler way: rose=${1%.pnm} Cheers, ulrich
Re: [Groff] GNU troff version 1.22.3
On Wed, Nov 05, 2014 at 09:15:54AM +0100, Werner LEMBERG wrote: > > groff 1.22.3 has been released. > First, thanks a lot! Should groff compile with gcc version 4.6.3 without warnings? Cheers, ulrich
Re: [Groff] GNU troff version 1.22.3
On Wed, Nov 05, 2014 at 11:00:50AM +0100, Werner LEMBERG wrote: > > >> groff 1.22.3 has been released. > >> > > First, thanks a lot! > > > > Should groff compile with gcc version 4.6.3 without warnings? > > I guess the answer is no. There are some warnings here and there, and > I haven't found the time (and interest) to fix them. Patches are > welcomed :-) > > >Werner I tried to fix it. Please find my attempt at patching below. While working on this, I found that "make clean" does not work on my system (Ubuntu 12.4). I get make[1]: Entering directory `/usr/local/src/groff-1.22.3/src/libs/gnulib' CDPATH="${ZSH_VERSION+.}:" && cd . && aclocal-1.14 -I m4 /bin/bash: aclocal-1.14: command not found make[1]: *** [aclocal.m4] Error 127 and when I type aclocal-1.14 I get No command 'aclocal-1.14' found, did you mean: Command 'aclocal-1.4' from package 'automake1.4' (main) Command 'aclocal-1.10' from package 'automake1.10' (main) Command 'aclocal-1.11' from package 'automake' (main) aclocal-1.14: command not found aclocal --version gives aclocal (GNU automake) 1.12.2 So the question: Is that specific version of aclocal-1.14 needed, or would just aclocal do as well? Cheers, ulrich -- # patch to avoid warnings from gcc 4.6.3 # # To apply this patch: # STEP 1: Chdir to the source directory. # STEP 2: Run the 'applypatch' program with this patch file as input. # # If you do not have 'applypatch', it is part of the 'makepatch' package # that you can fetch from the Comprehensive Perl Archive Network: # http://www.perl.com/CPAN/authors/Johan_Vromans/makepatch-x.y.tar.gz # In the above URL, 'x' should be 2 or higher. # # To apply this patch without the use of 'applypatch': # STEP 1: Chdir to the source directory. # STEP 2: Run the 'patch' program with this file as input. # End of Preamble Patch data follows diff -c 'groff-1.22.3/src/devices/grohtml/post-html.cpp' '/tmp/groff-1.22.3/src/devices/grohtml/post-html.cpp' Index: ./src/devices/grohtml/post-html.cpp *** ./src/devices/grohtml/post-html.cpp Thu Nov 6 18:44:17 2014 --- ./src/devices/grohtml/post-html.cpp Tue Nov 4 09:38:35 2014 *** *** 5002,5008 string split_file = file_list.file_name(); split_file += '\0'; fflush(stdout); ! FILE* foo = freopen(split_file.contents(), "w", stdout); fragment_no++; if (dialect == xhtml) writeHeadMetaStyle(); --- 5002,5008 string split_file = file_list.file_name(); split_file += '\0'; fflush(stdout); ! freopen(split_file.contents(), "w", stdout); fragment_no++; if (dialect == xhtml) writeHeadMetaStyle(); diff -c 'groff-1.22.3/src/libs/libgroff/Makefile.sub' '/tmp/groff-1.22.3/src/libs/libgroff/Makefile.sub' Index: ./src/libs/libgroff/Makefile.sub *** ./src/libs/libgroff/Makefile.subThu Nov 6 18:11:54 2014 --- ./src/libs/libgroff/Makefile.subTue Nov 4 09:38:35 2014 *** *** 146,152 @echo Making version.cpp @echo const char \*version_string = \"$(src_version)\"\; >$@ @echo const char \*revision_string = \"$(src_revision)\"\; >>$@ ! @echo const char \*Version_string = \"$(src_version).$(src_revision)\"\; \ | sed -e 's/\.0\"/\"/' >>$@ # We have to avoid $(COMPILE.c) since we must not use groff's `assert.h' --- 146,152 @echo Making version.cpp @echo const char \*version_string = \"$(src_version)\"\; >$@ @echo const char \*revision_string = \"$(src_revision)\"\; >>$@ ! @echo extern \"C\" const char \*Version_string = \"$(src_version).$(src_revision)\"\; \ | sed -e 's/\.0\"/\"/' >>$@ # We have to avoid $(COMPILE.c) since we must not use groff's `assert.h' diff -c 'groff-1.22.3/src/libs/libgroff/font.cpp' '/tmp/groff-1.22.3/src/libs/libgroff/font.cpp' Index: ./src/libs/libgroff/font.cpp *** ./src/libs/libgroff/font.cppThu Nov 6 16:18:39 2014 --- ./src/libs/libgroff/font.cppTue Nov 4 09:38:35 2014 *** *** 740,746 if (test_file) { FILE *f = fopen(p, "r"); if (f) { ! char* foo = fgets(line, 254, f); fclose(f); test_file = 0; char *linep = strchr(line, '\0'); --- 740,746 if (test_file) { FILE *f = fopen(p, "r"); if (f) { ! fgets(line, 254, f); fclose(f); test_file = 0; char *linep = strchr(line, '\0'); diff -c 'groff-1.22.3/src/libs/libgroff/new.cpp' '/tmp/groff-1.22.3/src/libs/libgroff/new.cpp' Index: ./src/libs/libgroff/new.cpp *** ./src/libs/libgroff/new.cpp Thu Nov 6 16:29:01 2014 --- ./src/libs/libgroff/new.cpp Tue Nov 4 09:38:35 2014 *** *** 28,34 static void ewrite(const char *s) { ! ssize_t foo = write(2, s, strlen(s)); } void *operator new(size_t size) --- 28,34 static void ewrite(const cha
Re: [Groff] [bug #43569] Fix for compile warnings with gcc 4.6.3
On Mon, Nov 10, 2014 at 10:07:01AM +, anonymous wrote: From: anonymous Subject: [bug #43569] Fix for compile warnings with gcc 4.6.3 "anonymous" was me. Failed to log in first. Sorry, ulrich
Re: [Groff] Question about .substring
On Wed, Nov 19, 2014 at 05:24:22PM +, Ralph Corderoy wrote: > Hi Steffen, > > > > > Replace the string named xx with the substring defined by > > > > the indices n1 and n2. > The full documentation of .substring wasn't originally given. > > -- Request: .substring str n1 [n2] > Replace the string named STR with the substring defined by the > indices N1 and N2. The first character in the string has index 0. > If N2 is omitted, it is taken to be equal to the string's length. shouldn't that be "it is taken to be equal to the string's length - 1" ? (As we count from zero.) ulrich
Re: [Groff] Converting very small file into .dvi
On Tue, Dec 30, 2014 at 10:26:00PM +0100, Grégoire Babey wrote: > Thank you Tadziu, I was using gedit with utf-8. > > Thank you Werner. Using -k, the error message is still there. > It doesn't matter, using dvips, I could turn the dvi-file into .ps. > > maybe, you should inspect yor input file with hexdump? > Cheers ulrich
Re: Groff on Raspberry?
On Wed, Oct 06, 2021 at 03:58:19PM +0200, Oliver Corff wrote: > Dear All, > > Please bear with me if the answer is in front of my nose (I did not see > it yet). Does anybody know whether the Raspberry Pi OS comes with groff? > I run Rasbian on a PI-zero and Ubuntu Mate on a pi 4. Both have got groff out of the box. Best ulrich
weird behaviour of .sp| with expression
Hi all, look at this code: .nr t1 5c .nr t2 5c .nr foo1 \n[t1]u+\n[t2]u foo1 \n[foo1] .nr foo2 (\n[t1]+\n[t2])u foo2 \n[foo2] .sp |10c 10 c .sp |\n[t1]u+\n[t2]u no braket .sp |(\n[t1]+\n[t2])u with braket It prints foo1 283464 foo2 283464 so both esxpressions are evaluted to the same result. Then it prints "10c no bracket" on one line somewhere in the middle of my page. But "with bracket" is printed o few lines below. How come? -ulrich
Re: .SPACE in mom
Here is a macro to be used with mom, that moves to a distance down from top or up from bottom, depending on the sign of the argument: .\" Goto position relative to top or bottom of page depending .\" on sign of argument, respecting margins with parameter "m" .\" Examples: .Goto -3c / .Goto 3c m .MAC Goto END . ie \\$1<0 \{\ .nr tmp \\n[#PAGE_LENGTH]+\\$1-\\n[#LEAD] .if '\\$2'm' .nr tmp \\n[tmp]-\\n[#B_MARGIN] . \} . el \{\ .nr tmp \\$1 .if '\\$2'm' .nr tmp \\n[tmp]+\\n[#T_MARGIN] \} . vpt 0 . SP |\\n[tmp]u . vpt .END Have fun, ulrich
macro returning a value?
Is there a trick to make a macro or string return a value? Motivation: I can write position: \n[.d] and get the current position in units. But I want millimeters, \n[.d]*25.4/72000 or, as arithmetic is in integer, \n[.d]*254/72 The only solution I found looks like this: .de Pos END .nr foo (\\n[.d]u-\\[.v]u)*254+1)/72000 \\n[foo] mm/10 .END .fi position: \n[.d] units, .Pos But this solution doesn’t make me happy. Help a poor struggler! ulrich
Re: macro returning a value?
On Sat, Nov 13, 2021 at 12:19:09PM -0500, Peter Schaffter wrote: > On Sat, Nov 13, 2021, Ulrich Lauther wrote: > > Is there a trick to make a macro or string return a value? > > > The only solution I found looks like this: > > > > .de Pos END > > .nr foo (\\n[.d]u-\\[.v]u)*254+1)/72000 > > \\n[foo] mm/10 > > .END > > > > .fi > > position: \n[.d] units, > > .Pos > > .nr foo has an error -- s/b \\n[.v] -- and the u scaling indicators > are superfluous. Fixed, the macro could be written > > .de Pos > \R'foo (\\n[.d]-\\n[.v]*254+1)/72000'\\n[foo]mm/10 > .. > > which allows you to enter > > position: \n[.d] units, \*[Pos]. > Wow! Works nicely. But why is "R" escaped only once? \\R works too. And I had to add a line ".sp -1v" at the end of the macro; otherwise I get a blank line after position: ... ulrich
Re: macro returning a value?
On Sun, Nov 14, 2021 at 12:33:38PM +0100, Ulrich Lauther wrote: > On Sat, Nov 13, 2021 at 12:19:09PM -0500, Peter Schaffter wrote: > > On Sat, Nov 13, 2021, Ulrich Lauther wrote: > > > Is there a trick to make a macro or string return a value? snip > > .de Pos > > \R'foo (\\n[.d]-\\n[.v]*254+1)/72000'\\n[foo]mm/10 > > .. > > > > which allows you to enter > > > > position: \n[.d] units, \*[Pos]. > > > > Wow! Works nicely. > > But why is "R" escaped only once? \\R works too. > And I had to add a line ".sp -1v" at the end of the macro; otherwise I get a > blank line after position: ... > I now found out that the space between "foo" and the openening bracket causes the unintended blank line. But why? ulrich -- -lauther
Re: macro returning a value?
> You shouldn't be seeing a blank line. What's more, removing the > space before the opening parens should cause the \R escape to fail > with 'troff: :: warning: missing number'. A backtrace > points directly to the \R line. > > I'm mystified. Can you send a small example exhibiting the problem > (input and output) along with your groff command line? > I cannot reproduce the case without the blank and no extra blank line. In the attached file the macro Pos1 gives the correct result, but an extra line. Pos2 gives a wrong result, but I don't see any error message. Pos3 gives the correct result without an extra line. With "man groff" I cannot find an option to enable error messages. My command line is "groff -Tps test > test.ps". I attach the two files. Thanks for your help, ulrich .ps 20 .vs 22 .nf .de Pos1 \R'foo1 (\\n[.d]*254+72)/72000' \\n[foo1] mm/10 .. position: \n[.d] units, \*[Pos1] position: \n[.d] units, \*[Pos1] .de Pos2 \R'foo2(\\n[.d]*254+72)/72000' \\n[foo2] mm/10 .. position: \n[.d] units, \*[Pos2] position: \n[.d] units, \*[Pos2] .de Pos3 \R'foo3 (\\n[.d]*254+72)/72000' \\n[foo3] mm/10 .sp -1v .. position: \n[.d] units, \*[Pos3] position: \n[.d] units, \*[Pos3] test.ps Description: PostScript document
Re: Converting between macro sets?
Not a script and not -ms to -me but a set of macros that allow me to use some -mm comands with -mom. ulrich On Thu, Aug 18, 2022 at 02:08:23PM -0400, Robert Goulding wrote: > Just out of curiosity, has anyone written a script to, say, convert text > written with -ms to -me? > > Robert. >