-
-
Notifications
You must be signed in to change notification settings - Fork 80
Apply Par margin to previous box in some cases in PGML. #1358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
8a1ff45 to
5743412
Compare
macros/core/PGML.pl
Outdated
| for my $i (0 .. $n - 1) { | ||
| my $item = $stack->[$i]; | ||
| my $next_par = $i + 1 < $n && $stack->[ $i + 1 ]{type} eq 'par' ? $stack->[ $i + 1 ] : undef; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change this to
| for my $i (0 .. $n - 1) { | |
| my $item = $stack->[$i]; | |
| my $next_par = $i + 1 < $n && $stack->[ $i + 1 ]{type} eq 'par' ? $stack->[ $i + 1 ] : undef; | |
| for my $i (0 .. $#$stack) { | |
| my $item = $stack->[$i]; | |
| my $next_par = $i < $#$stack && $stack->[ $i + 1 ]{type} eq 'par' ? $stack->[ $i + 1 ] : undef; |
and delete my $n = scalar(@$stack); above (line 1271). Perl is optimized for this and stores this number as a property of the array. So there is no reason to save the array length to yet another location. Also, perl offers the $# syntax for getting the index of the last entry in an array, so use that rather than adding or subtracting one from the array length.
5743412 to
fc008f1
Compare
drgrice1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good.
I think that the essential thing is that the divs that were added between list items be fixed, since that is invalid HTML. Adding the style to other block items (such as the lists themself) instead of injecting an empty div after it is not particularly important since that is at least valid HTML. I am not entirely certain what benefit that provides either.
|
I am unsure on the benefit as well, but I do feel the empty divs for spacing is not ideal. I was also wondering if there were any accessibility issues with not using Paragraph one.
<div style="margin-top:1em"></div>
Paragraph two.
<div style="margin-top:1em"></div>
Paragraph three.And this just feels better to me. But I couldn't figure out a way to do this, and assume that if the PGML parser was setup for this, <div style="margin-bottom:1em">
Paragraph one.
</div>
<div style="margin-bottom:1em">
Paragraph two.
</div>
<div style="margin:0">
Paragraph three.
</div> |
|
There is nothing wrong with using an empty Using |
|
I agree with @drgrice1 that removing the As for the implementation itself, I had considered something like this in my suggestion, but because this is in the base In fact, I had considered something more general yet. Were I writing this code today (rather than something like 20 years ago), I would replace the whole my $method = ucfirst($item->{type});
if (Value::can($self, $method)) {
$string = $self->$method($item, $block, $i);
} else {
PGML::Warning "Warning: unknown block type '$item->{type}' in " . ref($self) . "::format\n";
}In fact, I might replace the main loop by my $string, $di;
for (my $i = 0; $i < $#$stack; $i += 1 + ($di || 0)) {
my $item = $self->{item} = $stack->[$i];
$self->{nl} = (!defined($strings[-1]) || $strings[-1] =~ m/\n$/ ? "" : "\n");
my $method = ucfirst($item->{type});
if (Value::can($self, $method)) {
($string, $di) = $self->$method($item, $block, $i);
push(@strings, $string) unless !defined $string || $string eq '';
} else {
PGML::Warning "Warning: unknown block type '$item->{type}' in " . ref($self) . "::format\n";
}
}Then the various methods could check the stack in any way they wanted to (not just know about a following This makes all the item implementations get the same data and work the same way. It allows the creation of new item types without having to modify the main loop. And it allows the item implementations to deal with the block's stack in whatever way they need to. Finally, it avoids all the pattern matching done and the awkward Anyway, this would mean that you don't have to keep adding extra parameters to specific item implementations in the future, and all items are implemented in the same way. |
|
@dpvc Thanks. I am looking at implementing what you stated, but unsure how to modify the |
|
Sorry, I missed the string being sent to the my $state = {
block => $block,
strings => [],
i => 0,
};
while ($state->{i} < $#$stack) {
my $item = $self->{item} = $stack->[$state->{i}++];
$self->{nl} = (!defined($state->{strings}[-1]) || $state->{strings}[-1] =~ m/\n$/ ? "" : "\n");
my $method = ucfirst($item->{type});
if (Value::can($self, $method)) {
my $string = $self->$method($item, $state);
push(@{$state->{strings}}, $string) unless !defined $string || $string eq '';
} else {
PGML::Warning "Warning: unknown block type '$item->{type}' in " . ref($self) . "::format\n";
}
}Then Of course, this requires changes to the implementation functions that previously used |
|
Implemented the suggested changes to the main |
92ac3ed to
094666c
Compare
|
Seems my change missed adding a new line character that makes one of the unit tests fails. Trying to track that down unless someone else sees where a newline wasn't added correctly. |
macros/core/PGML.pl
Outdated
| my $self = shift; | ||
| my $item = shift; | ||
| return $self->nl . '<div style="margin-top:1em"></div>' . "\n"; | ||
| return '<div style="margin-top:1em"></div>' . "\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The unit test is failing because of the removal of $self->nl . here. This removal seems to be an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I should add that for the PGML::Format::html package, almost all of these new lines should be removed. I think that at some point there was an attempt to make the resulting output more human readable by adding these newlines. However, that also results in larger output that is sent. That is not desirable, and instead minimized html code should be the goal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, yea it was an error, in trying to revert the Par function I missed that.
I could go remove some of those new lines if you would like, though maybe that should be a new PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, lets leave that for another pull request.
094666c to
a013860
Compare
drgrice1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While we are fixing HTML validation issues here, there is one more that I have observed. On line 1638 (in this pull request at least), there is a span tag that contains an hr tag. It is invalid for a span to contain an hr. That can be easily fixed by changing that span to a div. That will not affect the resulting display, and is then valid HTML.
You could add that to this pull request if you like.
Apply the spacing between paragraphs added by the Par block in in HTML to the previous block instead of inserting an empty div with a margin. This adds the margin from the Par block to the previous Indent div, list, or list item block. Based on the code from @dpvc in openwebwork#1355.
As suggested by @dvpc, refactor the PGML::format::string loop to call the appropriate method if it exists. Also all methods now have access to the block and current state of the loop to use as needed.
e299780 to
154e463
Compare
This was never used anywhere else (that I could find), so no need to store the current item in the PGML::format::string loop.
dpvc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm OK with this as is, but regarding passing $block, I think it makes more sense to put that into the state and modify the few functions that use that. I almost put $item into that as well, but didn't want you to have to edit every function. But there are only a couple that use $block.
macros/core/PGML.pl
Outdated
| /tag/ && do { $string = $self->Tag($item); last }; | ||
| my ($self, $block) = @_; | ||
| my $stack = $block->{stack}; | ||
| my $state = { strings => [], i => 0 }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On looking at this, with all the $state->{strings}[-1] references I'm wondering if it wouldn't be better to do
my @strings;
my $state = { strings => \@strings, i => 0 };so that 1275 can go back to its original form, as can 1283 and 1284, and 1278 can use @strings.
macros/core/PGML.pl
Outdated
| . "</div>\n"; | ||
| my $em = 2.25 * $item->{indent}; | ||
| my $bottom = '0'; | ||
| if (defined $block->{stack}[ $state->{i} ] && $block->{stack}[ $state->{i} ]{type} eq 'par') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be useful to do
my $next = $block->{stack}[ $state->{i} ];
if (defined $next && $next->type eq 'par') {to reduce the number of dereferences that need to be performed. Similarly for lines 1544 and 1558.
macros/core/PGML.pl
Outdated
| $bottom = '1em'; | ||
| $state->{i}++; | ||
| } | ||
| return $self->nl . "<div style=\"margin: 0 0 $bottom ${em}em;\">\n" . $self->string($item) . $self->nl . "</div>\n"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you really are trying to save individual characters being part of the HTML output, then remove the semi-colon after '${em}em' and the \n at the end, here.
macros/core/PGML.pl
Outdated
| my $list = $bullet{ $item->{bullet} }; | ||
| my $margin = '0'; | ||
| if (defined $block->{stack}[ $state->{i} ] && $block->{stack}[ $state->{i} ]{type} eq 'par') { | ||
| $margin = '0 0 1em 0'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, if you want to reduce characters, leave off the final 0, which is implied by the second 0.
|
@dpvc thanks for the suggestions, I'll go make some of the changes. I party didn't include |
All of the format methods now receive a single state hash instead of the item, block, and state as separate inputs. Reduce the number of times some variables are dereferenced from the state hash. Remove some white space to minimize HTML output. Leaving newline characters `\n` alone for now.
|
I appreciate your making those changes. That alls looks good. One last thing I just thought of is that the new |
|
I think that changing So I am just up voting @dpvc's last suggestion! |
This way only "item" methods are capitalized to distinguish them from other methods which are not a block item type.
|
The method is now called |
Apply the spacing between paragraphs added by the Par block in in HTML to the previous block instead of inserting an empty div with a margin. This adds the margin from the Par block to the previous Indent div (including adding a div around an indent of zero), list, or list item block.
Based on the code from @dpvc in #1355.
Unsure if this should be extended to any other blocks.