[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[bug #63449] [tbl] causes grotty to complain "character above first line
From: |
G. Branden Robinson |
Subject: |
[bug #63449] [tbl] causes grotty to complain "character above first line discarded" |
Date: |
Wed, 30 Nov 2022 07:44:26 -0500 (EST) |
URL:
<https://savannah.gnu.org/bugs/?63449>
Summary: [tbl] causes grotty to complain "character above
first line discarded"
Project: GNU troff
Submitter: gbranden
Submitted: Wed 30 Nov 2022 12:44:24 PM UTC
Category: Preprocessor tbl
Severity: 3 - Normal
Item Group: Warning/Suspicious behaviour
Status: In Progress
Privacy: Public
Assigned to: gbranden
Open/Closed: Open
Discussion Lock: Any
Planned Release: None
_______________________________________________________
Follow-up Comments:
-------------------------------------------------------
Date: Wed 30 Nov 2022 12:44:24 PM UTC By: G. Branden Robinson <gbranden>
Problem observed in groff 1.22.4 and goes back years.
Several references to it can be found online. None seem to correctly diagnose
the cause. Here are two.
https://stackoverflow.com/questions/38253755/man-page-grotty-error-character-above-first-line-discarded
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=673436
The problem ultimately lies in bug #62471, but that is difficult to resolve as
it arises from a design decision and the limitations of character-cell output
devices.
If a non-boxed tbl(1) table has at least one vertical rule in it and the table
starts at the top of the page (i.e., there is no top margin, and the current
drawing position when the page begins is 1v), then this warning will happen
because when formatting for troff, vertical rules are drawn 1v _above_ the top
of the page. This is so that intersections with horizontal rules can be
detected by grotty and replaced with appropriate intersection characters.
(Except on the 'utf8' output device, this is always a plus sign.)
I have several test cases not yet structured into a regression test script,
and a functional fix, but I'm not happy with it design-wise. I think I want
to move the Boolean flags I'm using into the "flags" data structure and break
the rigid correspondence of that struct with tbl's region options. It feels
to me right now that that would be cleaner, or at least less dirty, than what
I'm doing.
Test inputs:
$ more EXPERIMENTS/overheight-tbl*
::::::::::::::
EXPERIMENTS/overheight-tbl1.roff
::::::::::::::
.TS
L |.
foo
.TE
::::::::::::::
EXPERIMENTS/overheight-tbl2.roff
::::::::::::::
.TS
_
L |.
foo
.TE
::::::::::::::
EXPERIMENTS/overheight-tbl3.roff
::::::::::::::
.TS
L |.
_
foo
.TE
::::::::::::::
EXPERIMENTS/overheight-tbl4.roff
::::::::::::::
.TS
L.
_
foo
.TE
::::::::::::::
EXPERIMENTS/overheight-tbl5.roff
::::::::::::::
.TS
L.
foo
_
.TE
Fix, of questionable design:
diff --git a/src/preproc/tbl/main.cpp b/src/preproc/tbl/main.cpp
index 03cfb8f91..b3089cb1e 100644
--- a/src/preproc/tbl/main.cpp
+++ b/src/preproc/tbl/main.cpp
@@ -344,6 +344,8 @@ void process_input_file(FILE *fp)
struct options {
unsigned flags;
+ bool has_full_vlines; // the table has a '|' as a column classifier
+ bool has_top_hline; // the table as an hline in row 1 (not from a box)
int linesize;
char delim[2];
char tab_char;
@@ -353,7 +355,8 @@ struct options {
};
options::options()
-: flags(0), linesize(0), tab_char('\t'), decimal_point_char('.')
+: flags(0), has_full_vlines(false), has_top_hline(false), linesize(0),
+ tab_char('\t'), decimal_point_char('.')
{
delim[0] = delim[1] = '\0';
}
@@ -825,6 +828,7 @@ format *process_format(table_input &in, options *opt,
case '-': // tbl also accepts this
got_format = true;
t = FORMAT_HLINE;
+ opt->has_top_hline = true;
break;
case '=':
got_format = true;
@@ -1099,6 +1103,7 @@ format *process_format(table_input &in, options *opt,
list->zero_width = 1;
break;
case '|':
+ opt->has_full_vlines = true;
c = in.get();
list->vline++;
break;
@@ -1260,7 +1265,8 @@ table *process_data(table_input &in, format *f, options
*opt)
int format_index = 0;
bool give_up = false;
enum { DATA_INPUT_LINE, TROFF_INPUT_LINE, SINGLE_HLINE, DOUBLE_HLINE }
type;
- table *tbl = new table(ncolumns, opt->flags, opt->linesize,
+ table *tbl = new table(ncolumns, opt->flags, opt->has_full_vlines,
+ opt->has_top_hline, opt->linesize,
opt->decimal_point_char);
if (opt->delim[0] != '\0')
tbl->set_delim(opt->delim[0], opt->delim[1]);
@@ -1287,6 +1293,8 @@ table *process_data(table_input &in, format *f, options
*opt)
type = SINGLE_HLINE;
else
type = DOUBLE_HLINE;
+ if (0 == current_row)
+ tbl->has_top_hline = true;
}
else {
in.unget(d);
diff --git a/src/preproc/tbl/table.cpp b/src/preproc/tbl/table.cpp
index 798817aa3..e75c7ab8d 100644
--- a/src/preproc/tbl/table.cpp
+++ b/src/preproc/tbl/table.cpp
@@ -1242,12 +1242,13 @@ void vertical_rule::print()
}
}
-table::table(int nc, unsigned f, int ls, char dpc)
+table::table(int nc, unsigned f, bool hfv, bool hth, int ls, char dpc)
: nrows(0), ncolumns(nc), linesize(ls), decimal_point_char(dpc),
vrule_list(0), stuff_list(0), span_list(0),
entry_list(0), entry_list_tailp(&entry_list), entry(0),
- vline(0), row_is_all_lines(0), left_separation(0), right_separation(0),
- total_separation(0), allocated_rows(0), flags(f)
+ vline(0), row_is_all_lines(0), left_separation(0),
+ right_separation(0), total_separation(0), allocated_rows(0), flags(f),
+ has_full_vlines(hfv), has_top_hline(hth)
{
minimum_width = new string[ncolumns];
column_separation = ncolumns > 1 ? new int[ncolumns - 1] : 0;
@@ -2957,9 +2958,15 @@ void table::do_top()
prints(".ls\n"
".vs\n");
}
- else if (flags & (ALLBOX | BOX)) {
+ else if (flags & (ALLBOX | BOX))
print_single_hline(0);
- }
+ // On terminal devices, a vertical rule of the height of the table
+ // will stick out 1v above a table that is unboxed or lack a
+ // horizontal rule on the first row. This is necessary for
+ // grotty's rule intersection detection. We also make room for it so
+ // that the vertical rule is not drawn above the top of the page.
+ else if (has_full_vlines && !has_top_hline)
+ prints(".if n .sp\n");
//printfs(".mk %1\n", row_top_reg(0));
}
diff --git a/src/preproc/tbl/table.h b/src/preproc/tbl/table.h
index c703fb1cd..247e794cb 100644
--- a/src/preproc/tbl/table.h
+++ b/src/preproc/tbl/table.h
@@ -83,6 +83,7 @@ struct vertical_rule;
class table {
int nrows;
int ncolumns;
+ bool has_full_vlines;
int linesize;
char delim[2];
char decimal_point_char;
@@ -142,8 +143,10 @@ public:
NOWARN = 0x00000080,
EXPERIMENTAL = 0x80000000 // undocumented; use as a hook for
experiments
};
+ bool has_top_hline;
char *expand;
- table(int nc, unsigned flags, int linesize, char decimal_point_char);
+ table(int nc, unsigned flags, bool has_full_vlines,
+ bool has_top_hline, int linesize, char decimal_point_char);
~table();
void add_text_line(int r, const string &, const char *, int);
_______________________________________________________
Reply to this item at:
<https://savannah.gnu.org/bugs/?63449>
_______________________________________________
Message sent via Savannah
https://savannah.gnu.org/
- [bug #63449] [tbl] causes grotty to complain "character above first line discarded",
G. Branden Robinson <=