I am fixing a number of problems I've had with denature, and I'll submit a few patches soon. In particular, I've changed calc_columns_in_table() so that it gets the maximum number of columns in a table (I had problems with comment tags between the <table> and <tr> tags).
But in the meantime, I am trying to deal with the lack of column padding when a row in a table has a lesser number of columns. I think I understand approximately what is going on, but I have a few problems, particularly in get_column_widths():
a) What does the idiom "%{ }" and "@{ }" do? I haven't run into that one before. Is is some sort of derefence?
b) I don't follow how the "colspan-stack" stuff works. Each <td> pushes the data, and each </td> pops it. How is it that there is sensible data for each row and column when print_fo_table_start is called?
c) I need to communicate to the print_fo_td_start() function that the colspan for a <td> entry has changed. Is it possible to manipulate the parse tree directly through '$node->attr("colspan")'? If not, how would I communicate that info? Using format_push()/format_get()? Somehow adding it to the %table info in @table_data?
Thanks for any help.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As you've probably noticed, denatures current table code is nasty
(the product of 2am gota get it working, heh). So anything you can do
to fix it is greatly appreciated.
So, in answer to your questions:
a) Yea the %{} casts a hash reference back to a hash and the @{} casts a
array refrence back to an array. if you have a hash say %foo you can do:
my $foo_ref = \%foo; # this will create a reference to the foo hash.
And if you want you can access the keys of foo through the refrence as:
my $val = $foo_ref->{"key"}
Then the %{} casts back to a hash
foreach my $key (sort keys %{$foo_ref})
b) The colspan-stack stuff is only used if we are placing a table inside of
that cell. I use it to calculate the amount of space the new table has to
work with.
So I take the number from the colspan-stack and add the sizes from the
current tables cell-width array for that number of rows. The colspan-stack
is created *after* the table start has been printed, its created as I walk
the tree and work with each node.
The print_fo_table_start function uses the cell-widths as are created with
get_column_widths to print the size of each of the cells.
This is all because FOP is unable to handle dynamic tables and requires the
sizes to be printed before the table starts.
So, onto c), how to do this.
The problem is not with the print_fo_table_start as it will always print
out the max number of datacells. The problem is in the get_column_widths
function. Its in here that it will die if the sizes are wrong, and in
here where we can fiddle the numbers to make it correct.
At the point where it dies (the error_death call), you will need to remove
that and put in some processing to extend the widths array (replace the
last element with -1 and add entries with -1 for the number of missing
rows). Then create a function or something such that you can pass it a row
and a number, it will find the last cell in that row and do something like:
which should add the number of missing cells to the colspan attribute of
the last cell when you find it (not sure if the first line is totally correct
but should be close).
I *think* thats all that would need to be done, but there could be something I'm
forgetting.
Hope that helps, if not let me know.
dj2
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Great, thanks. I'll submit a patch later when I've cleaned it up and isolated it a bit (I have other custom changes that you won't be wanting). I actually changed the colspan in get_widths_in_row() rather than in the error_death call.
A couple of points. Changing the cell->attr() will be inconsistent with the colspan-stack stuff. Not likely to be a big deal, save for the rare case of a "short row" containing a table in its last column. Even then it will render, it will just be small.
Second, I am uncertain about the implications of an "implicit" tag. Because you skip over implicit <td> tags in get_widths_in_row() without checking for the colspan attribute, I'm guessing that implicit tags are not only without content but also without attributes. Can I change an implicit <td> tag to have a colspan attribute? If so, do I have to mark it as non-implicit? If not, I'll have to hope that there is at least one non-implicit tag that can be expanded.
Thanks again for your help.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Right, changing it in get_widths_in_row is what I meant, sorry if I wasn't clear (just using the error_death as a reference point into the get_widths_in_row function).
Changing the cell->attr() inside of the get_widths_in_row *should* work with the colspan-stack because the colspan stack is build later, as the tree is walked.
The get_widths_in_row stuff is happening before the tree is walked to pre-calculate the size of each cell. So you should be able to fiddle the content of the tree and have it picked up correctly by the actual walk routine.
Implict tags are put into the tree by the parser when it sees something like a comment inside of a table. An actual td tag should not be an implicit tag, unless I'm missing something. Implicit tags have content, and you could probably attach attributes to them if you wanted, I just skip them in the get_widths_in_row routine because you *probably* don't want them in your table (comments don't count towards the table rows/cells but they may be needed later like pagebreaks or something).
dj2
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am fixing a number of problems I've had with denature, and I'll submit a few patches soon. In particular, I've changed calc_columns_in_table() so that it gets the maximum number of columns in a table (I had problems with comment tags between the <table> and <tr> tags).
But in the meantime, I am trying to deal with the lack of column padding when a row in a table has a lesser number of columns. I think I understand approximately what is going on, but I have a few problems, particularly in get_column_widths():
a) What does the idiom "%{ }" and "@{ }" do? I haven't run into that one before. Is is some sort of derefence?
b) I don't follow how the "colspan-stack" stuff works. Each <td> pushes the data, and each </td> pops it. How is it that there is sensible data for each row and column when print_fo_table_start is called?
c) I need to communicate to the print_fo_td_start() function that the colspan for a <td> entry has changed. Is it possible to manipulate the parse tree directly through '$node->attr("colspan")'? If not, how would I communicate that info? Using format_push()/format_get()? Somehow adding it to the %table info in @table_data?
Thanks for any help.
As you've probably noticed, denatures current table code is nasty
(the product of 2am gota get it working, heh). So anything you can do
to fix it is greatly appreciated.
So, in answer to your questions:
a) Yea the %{} casts a hash reference back to a hash and the @{} casts a
array refrence back to an array. if you have a hash say %foo you can do:
my $foo_ref = \%foo; # this will create a reference to the foo hash.
And if you want you can access the keys of foo through the refrence as:
my $val = $foo_ref->{"key"}
Then the %{} casts back to a hash
foreach my $key (sort keys %{$foo_ref})
b) The colspan-stack stuff is only used if we are placing a table inside of
that cell. I use it to calculate the amount of space the new table has to
work with.
So I take the number from the colspan-stack and add the sizes from the
current tables cell-width array for that number of rows. The colspan-stack
is created *after* the table start has been printed, its created as I walk
the tree and work with each node.
The print_fo_table_start function uses the cell-widths as are created with
get_column_widths to print the size of each of the cells.
This is all because FOP is unable to handle dynamic tables and requires the
sizes to be printed before the table starts.
So, onto c), how to do this.
The problem is not with the print_fo_table_start as it will always print
out the max number of datacells. The problem is in the get_column_widths
function. Its in here that it will die if the sizes are wrong, and in
here where we can fiddle the numbers to make it correct.
At the point where it dies (the error_death call), you will need to remove
that and put in some processing to extend the widths array (replace the
last element with -1 and add entries with -1 for the number of missing
rows). Then create a function or something such that you can pass it a row
and a number, it will find the last cell in that row and do something like:
my $colspan = $cell->attr("colspan") || 1;
$colspan += num_missing;
$cell->attr("colspan", $colspan);
which should add the number of missing cells to the colspan attribute of
the last cell when you find it (not sure if the first line is totally correct
but should be close).
I *think* thats all that would need to be done, but there could be something I'm
forgetting.
Hope that helps, if not let me know.
dj2
Great, thanks. I'll submit a patch later when I've cleaned it up and isolated it a bit (I have other custom changes that you won't be wanting). I actually changed the colspan in get_widths_in_row() rather than in the error_death call.
A couple of points. Changing the cell->attr() will be inconsistent with the colspan-stack stuff. Not likely to be a big deal, save for the rare case of a "short row" containing a table in its last column. Even then it will render, it will just be small.
Second, I am uncertain about the implications of an "implicit" tag. Because you skip over implicit <td> tags in get_widths_in_row() without checking for the colspan attribute, I'm guessing that implicit tags are not only without content but also without attributes. Can I change an implicit <td> tag to have a colspan attribute? If so, do I have to mark it as non-implicit? If not, I'll have to hope that there is at least one non-implicit tag that can be expanded.
Thanks again for your help.
Right, changing it in get_widths_in_row is what I meant, sorry if I wasn't clear (just using the error_death as a reference point into the get_widths_in_row function).
Changing the cell->attr() inside of the get_widths_in_row *should* work with the colspan-stack because the colspan stack is build later, as the tree is walked.
The get_widths_in_row stuff is happening before the tree is walked to pre-calculate the size of each cell. So you should be able to fiddle the content of the tree and have it picked up correctly by the actual walk routine.
Implict tags are put into the tree by the parser when it sees something like a comment inside of a table. An actual td tag should not be an implicit tag, unless I'm missing something. Implicit tags have content, and you could probably attach attributes to them if you wanted, I just skip them in the get_widths_in_row routine because you *probably* don't want them in your table (comments don't count towards the table rows/cells but they may be needed later like pagebreaks or something).
dj2