--- /tmp/e.tmac.master	2021-08-22 22:51:59.000000000 +0000
+++ e.tmac	2021-08-23 00:11:07.000000000 +0000
@@ -61,7 +61,12 @@
 .do nr devtag-needs-end-of-title 0
 .do nr devtag-needs-title 1
 .
-.do mso devtag.tmac
+.do ie d DEVTAG-NH \{\
+.  tm \n(.F: warning: File 'devtag.tmac' is already sourced, skipt it.
+.\}
+.el \{\
+.  do mso devtag.tmac
+.\}
 .
 .if !\n(.g .ig
 .de @R		\" --- initialize number register to 0, if undefined
@@ -100,7 +105,10 @@
 .	do als check_need_title @check_need_title
 .
 .@R pf
-.if \n(pf .nx
+.if \n(pf \{\
+.  tm \n[.F]: warning: The macro file is read again
+.  nx
+.\}
 .
 .if !\n(.g .ig
 .de @S		\" --- initialize string/macro to empty, if undefined
@@ -175,7 +183,7 @@
 ..
 .
 .de @z			\" --- end macro
-.if \n@>1 .tm >> @z, .z=\\n(.z ?a=\\n(?a
+.if \n@>1 .tm >> @z (end macro) .z=\\n(.z ?a=\\n(?a
 .if !"\\n(.z"" \
 \{\
 .	tm Line \\n(c. -- Unclosed block, footnote, or other diversion (\\n(.z)
@@ -265,7 +273,7 @@
 .
 .
 .de @h			\" --- header
-.if \n@>1 .tm >> @h %=\\n% ?a=\\n(?a ?b=\\n(?b ?w=\\n(?w
+.if \n@>1 .tm >> (header) @h %=\\n% ?a=\\n(?a ?b=\\n(?b ?w=\\n(?w
 .if (\\n(.i+\\n(.o)>=\\n(.l \
 .	tm Line \\n(c. -- Offset + indent exceeds line length
 .\" initialize a pile of junk
@@ -295,7 +303,7 @@
 .mk _k				\" for columned output
 .if \\n(?n=1 .nm 1\"		restore line numbering if n1 mode
 .nr $c 1			\" set first column
-.if \n@>4 .tm -- @h >> .ns nl=\\n(nl %=\\n% _k=\\n(_k tm=\\n(tm
+.if \n@>4 .tm -- @h >> .ns nl=\\n(nl %=\\n% _k=\\n(_k tm=\\n(tm ?s=\\n(?s
 .ie \\n(?s \
 \{\
 .	nr ?s 0
@@ -308,7 +316,7 @@
 ..
 .
 .de @n			\" --- new column or page
-.if \n@>3 .tm >> @n nl=\\n(nl %=\\n% ?f=\\n(?f ?o=\\n(?o
+.if \n@>3 .tm >> @n (new column or page) nl=\\n(nl %=\\n% ?f=\\n(?f ?o=\\n(?o
 .if \\n(bm<=0 \
 .	nr bm \\n(.Vu
 .if (\\n(_w<=\\n($l)&(\\n(?W=0) \
@@ -323,7 +331,7 @@
 .ch @f
 .wh -\\n(_bu @f
 .nr _b +(\\n(ppp*\\n($vu)/100u \" add 1 paragraph v in case sweep past
-.if \n@>2 .tm @n .p=\\n(.p bm=\\n(bm _b=\\n(_b _B=\\n(_B
+.if \n@>2 .tm -- @n .p=\\n(.p bm=\\n(bm _b=\\n(_b _B=\\n(_B
 .nr ?f 0			\" reset footnote flag
 .if \\n(?o \
 \{\
@@ -360,12 +368,14 @@
 .os
 .$H\"				\" special column header macro
 .ns
+.if \n@>3 .tm << @n nl=\\n(nl %=\\n% ?f=\\n(?f ?o=\\n(?o
 ..
 .
 .de @f			\" --- footer
-.if \n@>1 .tm >> @f %=\\n% nl=\\n(nl ?a=\\n(?a ?b=\\n(?b ?f=\\n(?f
+.nr reached_footer 1
+.if \n@>1 .tm >> @f (footer) %=\\n% nl=\\n(nl ?a=\\n(?a ?b=\\n(?b ?f=\\n(?f
 .if \n@>2 .nr VL \\n(.pu-\\n(nlu
-.if \n@>2 .tm @f bm=\\n(bm _B=\\n(_B _b=\\n(_b .p-nl=\\n(VL
+.if \n@>2 .tm -- @f bm=\\n(bm _B=\\n(_B _b=\\n(_b .p-nl=\\n(VL
 .ec
 .if \\n(?T \
 \{\
@@ -391,10 +401,15 @@
 ..
 .
 .de @o			\" --- output footnote
+.if \n@>2 .tm >> @o (output footnote)
 .nf
 .ls 1
 .in 0
-.if \n@>2 .tm @o last printed text = \\n(nl placing @r trap at -\\n(_B
+.if \n@>2 \{\
+.  tm -- @o last printed text's vertical position = \\n(nl placing @r trap at -\\n(_B
+.  tm -- @o or \\n(.p-\\n(_B from the top
+.\}
+
 .wh -\\n(_Bu @r
 .if \\n(?n \
 .	nm \\n(ln
@@ -402,10 +417,10 @@
 .if \\n(?n \
 .	nm
 .fi
-.if \n@>2 .tm @o triggered @r (?o) = \\n(?o
+.if \n@>2 .tm -- @o triggered @r (?o) = \\n(?o
 .if \\n(?o \
 \{\
-.	di			\" just in case triggered @r
+.	di\"			\" just in case triggered @r
 .	if \\n(dn=0 \
 \{\
 .		rm |o
@@ -416,19 +431,21 @@
 .\}
 .rm |f
 .ch @r
+.if \n@>2 .tm << @o diversion |f is removed
 ..
 .
 .de @c			\" --- new column
-.if \n@>2 .tm	>> @c %=\\n%
+.if \n@>2 .tm	>> @c (new column) %=\\n%
 .rs
 .sp |\\n(_ku
 .@O +\\n($lu+\\n($su
 .nr $c +1
 .@n
+.if \n@>2 .tm	<< @c %=\\n% _k=\\n(_k nl=\\n(nl .d=\\n(.d
 ..
 .
 .de @e			\" --- end page
-.if \n@>2 .tm	>> @e
+.if \n@>2 .tm	>> @e (end page)
 .@O \\n(_ou
 .rs
 .\" Move to footer position.
@@ -436,37 +453,61 @@
 .@t $f\"			\" output footer title
 .nr ?h 0
 .bp
+.if \n@>2 .tm	<< @e
 ..
 .
 .de @t			\" --- output header or footer title
+.if \n@>2 \{\
+.  tm >> @t (output header or footer title if ?h=\\n(?h == 0
+.  tm >> @t and using macro \\$1)
+.\}
 .if !\\n(?h \
 \{\
+.	if \n@>2 \{\
+.		tm -- @t >> sz with tp=\\n(tp
+.	\}
 .	sz \\n(tp\"		\" set header/footer type fonts, etc.
+.	if \n@>2 .tm -- @t << sz
 .	@F \\n(tf
 .	lt \\n(_Lu		\" make title span entire page
 .	if \\n(?n \
 .		nm \\n(ln
 .	nf
+.	if \n@>2 .tm -- @t >> \\$1
 .	\\$1
+.	if \n@>2 .tm -- @t << \\$1
 .	br
 .	if \\n(?n \
 .		nm
+.	if \n@>2 \{\
+.		if '\\$1'$h' .tm << @t end output of header
+.		if '\\$1'$f' .tm << @t end output of footer
+.	\}
 .\}
 ..
 .
 .de $h			\" $$$ print header
+.if \n@>2 .tm >> $h (print header) ?c=\\n(?c
 .ds |z
 .if !\\n(?c \
 \{\
 .	if e .ds |z "\\*(|0
 .	if o .ds |z "\\*(|1
 .\}
-.if !\(ts\\*(|z\(ts\(ts \
+.if \n@>2 .tm -- $h header string is "\\*(|z"
+.if !\(ts\\*(|z\(ts\(ts \{\
+.	if \n@>2 .tm -- $h executing '	tl \\*(|z
+.	if \n@>2 .tm -- $h distance to the next trap .t=\\n(.tu .v=\\n(.v
+.	if \\n(.tu<1v .ab \n[.F]:\n(.c:\\$0: not enough space for the header title
 '	tl \\*(|z
+.\}
+.if \n@>2 .tm -- $h after executing '	tl \\*(|z
 .rm |z
+.if \n@>2 .tm << $h
 ..
 .
 .de $f			\" $$$ print footer
+.if \n@>2 .tm >> $f (print footer) ?c=\\n(?c
 .ds |z
 .if \\n(?c \
 \{\
@@ -481,10 +522,12 @@
 .if !\(ts\\*(|z\(ts\(ts \
 '	tl \\*(|z
 .rm |z
+.if \n@>2 .tm << $f
 ..
 .
 .de @r			\" --- reprocess overflow footnotes
-.if \n@>3 .tm		>> @r .z=\\n(.z ?f=\\n(?f ?a=\\n(?a ?b=\\n(?b _b=\\n(_b
+.if \n@>3 .tm >> @r (reprocess overflow footnotes) .z=\\n(.z ?f=\\n(?f\
+ ?a=\\n(?a ?b=\\n(?b _b=\\n(_b
 .di |o				\" save overflow footnote
 .nr ?o 1
 .nr _D \\n(dn
@@ -498,6 +541,7 @@
 .if !'\*(.T'html' .rn bp @b	\" --- begin page
 .
 .de bp			\" *** begin new page (overrides columns)
+.if \\n@>1 .tm	>> bp (begin new page (overrides columns))
 .do check_page_length
 .nr $c \\n($m			\" force new page, not new column
 .ie \\n(nl>0 \
@@ -506,11 +550,15 @@
 \{\
 .	if \\n(.$>0 \
 .		pn \\$1
-.	if \\n(?I \
+.	if \\n(?I \{\
+.	  if \n@>1 .tm	-- bp spring the header trap @h at top, $c=\\n($c nl=\\n(nl
 .		@h\"		\" 'spring' the header trap
+.	\}
 .\}
 .br
+.if \n@>1 .tm	-- bp planting trap @h at top, $c=\\n($c nl=\\n(nl
 .wh 0 @h			\" reset header
+.if \\n@>1 .tm	<< bp
 ..
 .
 .rn ll xl		\" *** special line length (local)
@@ -701,14 +749,18 @@
 .
 .
 .de pp			\" *** paragraph
+.if \n@>2 .tm >> pp (paragraph) calling lp with pi=\\n(piu
 .lp \\n(piu
+.if \n@>2 .tm << pp
 ..
 .
 .de lp			\" *** left aligned paragraph
+.if \n@>2 .tm >> lp (left aligned paragraph)
 .@p
 .if \\n(.$ \
 .	ti +\\$1
 .nr $p 0 1
+.if \n@>2 .tm << lp
 ..
 .
 .de ip			\" *** indented paragraph w/ optional tag
@@ -773,6 +825,7 @@
 ..
 .
 .de @p			\" --- initialize for paragraph
+.if \n@>2 .tm >> @p (initialize for paragraph)
 .do check_page_length
 .do check_need_title
 .if "\\n(.z"|e" .tm Line \\n(c. -- Unmatched continued equation
@@ -781,11 +834,16 @@
 .	in +\\$1n
 .ce 0
 .fi
+.if \n@>2 .tm -- @p >> @F with pf=\\n(pf
 .@F \\n(pf
+.if \n@>2 .tm -- @p << @F
+.if \n@>2 .tm -- @p >> sz with pp=\\n(pp
 .sz \\n(pp
+.if \n@>2 .tm -- @p << sz
 .sp \\n(psu
 .ne \\n(.Lv+\\n(.Vu
 .ns
+.if \n@>2 .tm << @p
 ..
 .
 .
@@ -949,17 +1007,46 @@
 ..
 .
 .de 1c			\" *** single columned output
+.if \n@>2 .tm >> 1c (single columned output)
 .do check_page_length
+.do mk end.of.2.column
 .br
 .nr $c 1
 .nr $m 1
 .ll \\n(_Lu\"			return to normal output
-.sp |\\n(nlu
+.
+.\" space to the end of the longer column
+.do ie (\\n[end.of.2.column] > \\n[end.of.1.column]) \{
+.do   nr next_y_pos \\n(nlu+1v
+.   \}
+.   el \{\
+.do   nr next_y_pos \\n[end.of.1.column]+1v
+.   \}
+.
+.if \n@>2 \{\
+.do  nr y_pos_trap  (\\n(.tu + \\n[y_pos])
+.do  tm -- 1c y-position of next trap =\\n[y_pos_trap]u
+.do  tm -- 1c next y-position of text \\n[y_pos]u
+.   \}
+.
+.do  sp |\\n[next_y_pos]u
 .@O \\n(_ou
+.if \n@>2 .tm << 1c
 ..
 .
-.de bc			\" *** begin column
-.sp \\n(.tu
+.do de bc		\" *** begin column
+.do mk end.of.1.column
+.if \n@>2 .tm >> bc (begin column)
+.nr nr_traps (-1) 1
+.if \n@>2 .tm -- bc nr_traps=\\n[nr_traps]
+.nr reached_footer 0
+.\" 'reached_footer' is changed in the macro "@f"
+.while (\\n[reached_footer]==0) \{\
+.  sp \\n(.tu
+.  nr nr_traps \\n+[nr_traps]
+.\}
+.
+.if \n@>2 .tm << bc number of traps before the footer trap: \\n[nr_traps]
 ..
 .
 .
@@ -967,13 +1054,14 @@
 .
 .
 .de (z			\" *** begin floating keep
-.if \n@>4 .tm >> (z, .z=\n(.z
+.if \n@>4 .tm >> (z (begin floating keep) .z=\n(.z
 .@D 4 \\$1 \\$2
 .@(
+.if \n@>4 .tm << (z
 ..
 .
 .de )z			\" *** end floating keep
-.if \n@>4 .tm >> )z, .z=\n(.z
+.if \n@>4 .tm >> )z (end floating keep) .z=\n(.z
 .sp \\n(zsu
 .@)
 .if \n@>4 .tm -- )z << @), .z=\n(.z
@@ -1004,7 +1092,7 @@
 .nf
 .ls 1
 .nr ?k 1
-.if \n@>4 .tm -- )z >> \\*(|x
+.if \n@>4 .tm -- )z >> \\*(|x (copy to save macro)
 \!.if \\\\n(nl>(\\\\n(tm+2v) .ne \\n(dnu-\\n(zsu
 .|k\"				\" and the body
 .ec
@@ -1020,7 +1108,7 @@
 ..
 .
 .de @k			\" --- output floating keep
-.if \n@>4 .tm >> @k, $1=\\$1, .z=\\n(.z
+.if \n@>4 .tm >> @k (output floating keep) $1=\\$1, .z=\\n(.z
 .ev 1
 .nf
 .ls 1
@@ -1035,6 +1123,7 @@
 .br
 .rm \\$1
 .ev
+.if \n@>4 .tm << @k
 ..
 .
 .de (t			\" XXX temp ref to (z
@@ -1112,10 +1201,11 @@
 ..
 .
 .de )c			\" *** end block centered text
+.if \n@>4 .tm >> )c (end block centered text)
 .if !"\\n(.z"|c" .tm Line \\n(c. -- Unmatched .)c
 .br				\" force out final line
 .di
-.if \n@>4 .tm >> .)c .l=\\n(.l .i=\\n(.i $i=\\n($i dl=\\n(dl
+.if \n@>4 .tm -- )c .l=\\n(.l .i=\\n(.i $i=\\n($i dl=\\n(dl
 .ev 1
 .ls 1
 .in (\\n(.lu-\\n(.iu-\\n(dlu)/2u
@@ -1133,6 +1223,7 @@
 .rm |c
 .if \\n(?n \
 .	nm \\n(ln
+.if \n@>4 .tm << .)c .l=\\n(.l .i=\\n(.i $i=\\n($i dl=\\n(dl
 ..
 .
 .
@@ -1449,13 +1540,19 @@
 .
 .
 .de sz			\" *** set point size and vertical spacing
+.if \n@>2 .tm >> sz (set point size and vertical spacing) type size $1=\\$1p $r=\\n($r
 .ps \\$1
+.if \n@>2 .tm -- sz if $r>0 >> @v
 .if \\n($r .@v
+.if \n@>2 .tm -- sz if $r>0 << @v
 .vs \\n(.sp*\\n($vu/100u	\" default vs at pointsize + 20%
+.if \n@>2 .tm << sz
 ..
 .
 .de @v			\" --- possibly set $v from $r
+.if \n@>2 .tm >> @v (possibly set $v from $r) $v=\\n($vu
 .if (1i>=240u)&(1p<=\\n($r)&(\\n($r<=4p) .nr $v \\n($r00/1p
+.if \n@>2 .tm << @v $v=\\n($vu
 ..
 .
 .de @V			\" --- possibly set $V from $R
@@ -1549,6 +1646,7 @@
 .
 .
 .de (f			\" *** begin footnote
+.if \n@>2 .tm	>> (f (begin footnote) $f=\\n($f
 .ec
 .if "\\n(.z"|f" .tm Line \\n(c. -- Invalid footnote nesting
 .ie "\\n(.z"" \
@@ -1573,8 +1671,10 @@
 \{\
 .		da\"		\" won't fit on page at all
 .		bc
-.		if !\\n(?f \
+.		if !\\n(?f \{\
 .			rm |f
+.			if \n@>2 -- (f diversion |f is removed, ?f=\\n(?f
+.\}
 .		da |f
 .\" Next 5 lines could be dropped if headers had their own environment.
 .		in 0		\" reset everything from .bc
@@ -1615,6 +1715,7 @@
 ..
 .
 .de )f			\" *** end footnote
+.if \n@>2 .tm >> )f (end footnote) .z=\\n(.z *=\\n*
 .ie "\\n(.z"|f" \
 \{\
 .	if \\n* \
@@ -1639,6 +1740,7 @@
 \!.)f
 .	ev
 .\}
+.if \n@>2 .tm << )f (end footnote)
 ..
 .
 .@R ff
@@ -1684,7 +1786,7 @@
 .af _x a
 .
 .de (x			\" *** begin index entry
-.if \n@>4 .tm >> (x, .z=\\n(.z
+.if \n@>4 .tm >> (x (begin index entry) .z=\\n(.z
 .ds |X x
 .if \\n(.$>0 \
 .	ds |X \\$1
@@ -1693,6 +1795,7 @@
 .el \
 .	nr _z 1
 .@\\n(_z
+.if \n@>4 .tm << (x, .z=\\n(.z
 ..
 .
 .de @0			\" --- finish (x if no current diversion
@@ -1707,7 +1810,7 @@
 ..
 .
 .de )x			\" *** end index entry
-.if \n@>4 .tm >> )x, .z=\\n(.z
+.if \n@>4 .tm >> )x (end index entry) .z=\\n(.z
 .ie "\\n(.z"" \
 \{\
 .	ds |x \\n%
@@ -1730,6 +1833,7 @@
 \!.)x \\$1 \\$2
 \!.rm =\\n(_x
 .\}
+.if \n@>4 .tm << )x, .z=\\n(.z
 ..
 .
 .de xp			\" *** print the index
@@ -2029,6 +2133,7 @@
 .@R ?b\"		\" pending floating keep at page bottom?
 .@R ?C\"		\" at chapter header?
 .@R ?e\"		\" in equation?
+.@R ?f\"		\" reset footnote flag?
 .@R ?H\"		\" suppress headers and footers next page?
 .@R ?I\"		\" has the header trap been sprung?
 .@R ?n\"		\" n1 mode?
