Skip to content
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

Arbitrary number for \gresetinitiallines #1488

Closed
jperon opened this issue Feb 28, 2020 · 37 comments
Closed

Arbitrary number for \gresetinitiallines #1488

jperon opened this issue Feb 28, 2020 · 37 comments

Comments

@jperon
Copy link
Contributor

jperon commented Feb 28, 2020

Woud it be possible to have more than 2 lines for the initial ?
I tried a workaround with wrapfigure, which sounds promising, but the length of the lines doesn't adjust, so they get out of margin :

\documentclass[12pt]{article}

\usepackage{gregoriotex,libertine,wrapfig}

\begin{document}

\begin{wrapfigure}[3]{l}{0.25\textwidth}
{\fontsize{120pt}{140pt}\selectfont I}
\end{wrapfigure}
\makeatletter\gre@noinitial\makeatother
\gabcsnippet{(c3)
()N(ed~)vo(e)cá(ehgh)bit(fd~) me,(e.) *(,)
et(fde) e(ef/hg)go(h) ex(h)áu(hhh)di(fe)am(e.f!gwh) e(hfge)um :(e.) (:)
e(fde)rí(ehh)pi(f)am(fdf) e(fgFE'f)um,(fe..) (;)
et(ef~) glo(e)ri(ef/hg)fi(g)cá(gi/jhhf)bo(h_g) e(hghf)um :(f.) (:)
lon(hg~)gi(h)tú(i)di(h)ne(hhh) di(f)é(fgFE'f)rum(fe..) (;)
ad(e!f'g)im(gf~)plé(fgE'C)bo(c!e'f) e(fgFE'f)um.(fe..) (::)
}


\end{document}

Perhaps it could be related to #1418

@rpspringuel
Copy link
Contributor

This is something that's been on my ideal list of features for a while now, but I've not had a chance to work on it. Right now the readjustment of the line length that is necessary after the initial is handled within the manual line breaks and so it's necessary for the gabc code to contain multiple z or Z in order for multiline initials. I'd like to move that into the automatic line breaking mechanisms to remove this dependency and make it (and the placement of the initial) more responsive to setting \gresetinitiallines to numbers higher than 2.

There is, however, a work around for now. If \gresetinitiallines{2} is set, then the first "line" of the score can actually be more than 1 line of the score. The initial's vertical placement has to be adjusted manually using initialraise but it's possible to simulate a 3 (or more) line initial in a fragile way:

\documentclass[12pt]{article}

\usepackage{gregoriotex,libertine,wrapfig}

\grechangestyle{initial}{\fontsize{200pt}{0pt}\selectfont}
\newdimen\initialwidth
\initialwidth=0.25\textwidth
\grechangedim{manualinitialwidth}{\the\initialwidth}{scalable}
\grechangedim{initialraise}{-25pt}{scalable}
\gresetinitiallines{2}

\begin{document}

\gabcsnippet{(c3)
IN(ed~)vo(e)cá(ehgh)bit(fd~) me,(e.) *(,)
et(fde) e(ef/hg)go(h) ex(h)áu(hhh)di(fe)am(e.f!gwh) e(hfge)um :(e.) (:)
et(ef~) glo(e)ri(ef/hg)fi(g)cá(gi/jhhf)bo(h_g) e(hghf)um :(f.) (:z)
lon(hg~)gi(h)tú(i)di(h)ne(hhh) di(f)é(fgFE'f)rum(fe..) (;)
et(ef~) glo(e)ri(ef/hg)fi(g)cá(gi/jhhf)bo(h_g) e(hghf)um :(f.) (:)
lon(hg~)gi(h)tú(i)di(h)ne(hhh) di(f)é(fgFE'f)rum(fe..) (;)
et(ef~) glo(e)ri(ef/hg)fi(g)cá(gi/jhhf)bo(h_g) e(hghf)um :(f.) (:)
lon(hg~)gi(h)tú(i)di(h)ne(hhh) di(f)é(fgFE'f)rum(fe..) (;)
ad(e!f'g)im(gf~)plé(fgE'C)bo(c!e'f) e(fgFE'f)um.(fe..) (::z)
}


\end{document}

@rpspringuel
Copy link
Contributor

See #1491 for my progress on this.

@rpspringuel rpspringuel linked a pull request Feb 4, 2021 that will close this issue
@davidweichiang
Copy link

davidweichiang commented Jan 28, 2025

Would it be good enough to use post_linebreak_filter to change the width of the rules to match the width of the line? The above example, plus the post_linebreak_filter hack, looks like:

Image

@rpspringuel
Copy link
Contributor

That would be almost exactly what I was thinking about, I've just never been able to figure out how to get the post_linebreak_filter to work that way. That's why my work on multi-line initials is stuck with still exploiting a z that is present in the gabc (though I've reduced it to just 1 being required in the semi-manual mode).

The thing I'm working on right now is getting the initial positioned correctly vertically (it's baseline should line up with the baseline of the last shortened line. This means calculating/predicting the heights of the lower lines because the initial is typeset at the beginning of the first line (as part of the first syllable). Unfortunately, calculating/predicting line heights of lines which haven't been printed yet is hard, and only possible in our case because of the our second pass adjustment of line heights (which means we record the information needed to make those calculations).

@davidweichiang
Copy link

The post_linebreak_filter hack is at https://github.com/davidweichiang/gregorio/tree/parshape. The TeX code uses an attribute to mark the box that contains the staff lines, and the Lua code just assumes that the top-level hlists are lines and that they have the desired width.

\parshape and \wrapfig work, but for some reason \lettrine does not.

What's the baseline of a line of music? Is it the baseline of the words?

@rpspringuel
Copy link
Contributor

It's the baseline of the lowest element. That's usually the lyrics, but could be the translation (if present). If there are no lyrics then the baseline is the baseline that the lyrics would have if they were present.

@davidweichiang
Copy link

Since there's some glue between the lines, should the initial remain aligned with the lowest indented line, even if the glue stretches or shrinks?

@rpspringuel
Copy link
Contributor

That has been our traditional alignment target, but to be honest as I've been working on this over the past few days I'm no longer sure that it's the correct alignment target.

In general for drop caps, I think it's more usual for the top of the dropped cap to be aligned with the top of the first line (though perhaps not including extensions above the nominal top line from things like accents). If we consider the initial in a score to be a form of drop cap, should it not have a similar alignment target? Perhaps the top line of the staff?

Of course, the complication here are the annotations. These go above the initial and we generally don't want them to protrude too high above the staff. Does this mean that annotations should push down the initial? Do they only do so if the are bigger than a certain size? Does the presence of above lines text, a commentary, or really high notes change this, and if so how?

I feel like some effort should be taken to look at old books with various size initials and see if there is any pattern to how things are lined up. Does anyone else have any opinions on this?

If we decide to keep the target alignment, #1491 is getting fairly close to getting the alignment right (I'm still missing something in my calculation of a custom line heights when variable line heights matter, look at the 2-line-initials test to see this problem, and have yet to deal with the glue issue that @davidweichiang just mentioned), but I haven't yet tried to incorporate @davidweichiang's solution for automatic adjustment of line width, so I don't know how the two will interact yet.

@davidweichiang
Copy link

Questions about #1491:

  • In adjust_initial_raise, would it be simpler to directly measure the height+depth of the lines (and glues) to figure out the vertical position?
  • I am not seeing how the result of adjust_initial_raise is getting passed back to TeX, but couldn't this function directly move the initial into the right place?
    If I'm thinking about this correctly, it would not require a second pass.

(I'm also not seeing why the variable heights computation requires a second pass, but that's a separate issue.)

@rpspringuel
Copy link
Contributor

would it be simpler to directly measure the height+depth of the lines (and glues) to figure out the vertical position?

Probably. I've never really considered that option. Is it possible? My understanding has always been that our biggest hurdle is the fact that TeX processes stuff in one direction only. Thus when I'm typesetting the initial (the first, or very nearly the first) item in the score, I don't yet know things like how tall the lines will be. What I can do, and incidentally what we do with the line heights, is start with a reasonable guess and then record information about the elements that are either extremely high or extremely low as we encounter them (and figure out what line they are on). Then on a second pass we can use that information to refine our guess and repeat the process. Ideally this process will converge relatively rapidly (perhaps on the second pass) so that our guesses stop changing (and we can say we've arrived at "the solution." That's why I'm looking at our line height information and mostly reproducing the calculations associated with that (though I'm clearly missing something, since I'm not quite getting the same result).

I am not seeing how the result of adjust_initial_raise is getting passed back to TeX, but couldn't this function directly move the initial into the right place?

It gets passed back to TeX by setting \gre@dimen@temp@five which is then used to set the \raise for the box with the initial. I suppose the printing of the initial could also be brought over, I just hadn't considered that possibility.

@davidweichiang
Copy link

https://github.com/davidweichiang/gregorio/tree/parshape now uses Lua to calculate the vertical shift. But it will be off if the glue stretches or shrinks.

post_linebreak_filter gets called after each paragraph is made, so it does have access to all the lines and their heights/depths. It adds them up and then shifts the initial down by that much.

Image

@davidweichiang
Copy link

Looking at the above image, though, I think I agree with your suggestion that aligning the top of the initial with the top of the first line is better (not to mention easier).

@rpspringuel
Copy link
Contributor

So, I've finally had a chance to look at your parshape branch and am coming up with several problems:

  1. You use \textwidth in gregoriotex-main.tex (lines 337 and 340). This is a LaTeX only macro and breaks our plainTeX support. You probably should be using our internal alias \gre@dimen@linewidth (which actually points at \hsize, the plainTeX equivalent).
  2. gregoriotex-main.tex line 268 still makes use of \gre@adjustlineifnecessary which you've removed. This leads to lots of test being unable to compile.
  3. Initials with descenders (which I admit, is probably a really rare thing) encroach on the line below them. See gabc-output/glyphs/shape-switching for an example. Admittedly, the initial in this test is a lowercase letter (g) which is why I think this is probably a really rare issue, and perhaps one we don't even need to fix (i.e. in the rare instance where initials have descenders, perhaps this is what they should do).
  4. Applied to tex-output/bugs/fix-1373 this seems to break embedding scores in a parbox (and the notes go with them).
  5. commentary is getting pushed into the right margin. See tex-output/commentary. It looks like the commentary box is getting pushed out by the initial width

@davidweichiang
Copy link

Thanks! I had not even tried running the tests yet. I can open a draft PR to make it easier to review.

@rpspringuel
Copy link
Contributor

Running the tests is SOP for me. I find if I go to long without running my changes through the tests I end up breaking something accidentally that takes me forever to find.

@davidweichiang
Copy link

I think the above issues are fixed. 1-2 are easy. 3 is fixed in Lua (add the depth of the descender to the depth of the k-th line), and 5 is also fixed in Lua and I hope it's not too ugly. I can't reproduce 4.

@davidweichiang
Copy link

I believe the tests that are now failing are all because the placement of the initial is not the same as before for 2-line initials.

What would you think about adding a \gresetinitialvalign command with options:

  • basebase: align the initial's baseline with the first line's baseline
  • top: align the initial's top with the first line's top

And initialraise would still shift the initial up or down relative to the above.

The reason for the odd choice of basebase is so that when \gresetinitialvalign and \gresetannotationvalign have overlapping options, they should have the same meaning.

@rpspringuel
Copy link
Contributor

I confirm the fixes to 1 & 2.

4 is no longer appearing for me, so that may have been caused by one of the others.

5 appears to be fixed as the tests with commentary no longer fail.

I am, however, getting some strange extra spacing above scores with multi-line initials:

Image

That's the illumination test, but I see the same in some other tests. The blue is the new result, the red the expectation. You can see the whole score has been pushed down a fair bit. The second score is even worse since it's being pushed down twice. Of the various tests where I'm seeing the issue, none have commentary and the worst are the ones with annotations, but I'm not seeing it on all tests with annotations, just all tests with 2-line initials:

  • gabc-output/glyphs/high-bars-3-lines.gabc
  • gabc-output/glyphs/high-bars-2-lines.gabc
  • gabc-output/glyphs/high-bars-5-lines.gabc
  • gabc-output/glyphs/high-bars.gabc
  • tex-output/illumination/illumination.tex
  • tex-output/bugs/fix-1139/fix-1139.tex
  • tex-output/bugs/fix-1141/fix-1141.tex
  • tex-output/hyphenation/hyphenation.tex

I've been running against develop branch in the test repository for the moment, so I don't have tests with more than 2-line initials.

The output reminds me of the stray \par that can get inserted when TeX code that doesn't print anything has lines which don't end with %. Let me go looking for that in the code.

@davidweichiang
Copy link

Thanks -- previously I thought the discrepancy was small, but that's huge.

@davidweichiang
Copy link

BTW, on my computer the diffs look like this

Image

and I'm only now realizing that that's not what it's supposed to be...

@rpspringuel
Copy link
Contributor

I've now added a gregorio-project/gregorio-test#358 to look specifically at this version of multi-line initials. The modified version of the multi-line initial test really shows the excess space.

Said space, however, is increasing with the size of the initial, so I don't think it's a matter of stray uncommented lines. I would expect uncommented lines to introduce the same amount of extra space in each case.

As for your diff file, your blue background is the problem. The diff colors are blue and red, blue for new result, red for expectation (gray is used for pixels which are the same). To view the image diffs correctly you need to have the paper rendered in white (or at least some color other than blue, red, and gray).

@davidweichiang
Copy link

The problem was that (after removing a \smash) the space originally taken up by the initial was being retained. Now it should be fixed, although the alignment of the initial itself is still a little bit off.

@davidweichiang
Copy link

An alternative to my suggestion above: add options

  • \greinitialanchor{baseline} (default) or \greinitialanchor{top}
  • \greinitialvalign{baseline} (default, align the initial's anchor with the first line's baseline) or \greinitialvalign{top} (align the initial's anchor with the first line's top)

and for completeness

  • \greannotationanchor{baseline} or \greannotation{top}
  • \greinitialvalign{bottom}

@MRoth1910
Copy link

I am late to the party (and understand that time is of the essence if you are aiming to include this in TeXLive 2025; I have been particularly hoping that some of the already-merged changes get released so I don't want to delay this)

Fr Samuel may remember my related issue mentioned on the mailing list that the current drop cap pushes too far down if it's a letter J (so all of the Jesu examples…). And as someone who makes use of the greannotation feature, I would strongly suggest looking in particular at the 1949 Liber antiohonarius and the 1908 gradual (both versions) and the Solesmes 1961 version.

I don't plan on using a multiline initial but I'm happy if that can be done. There are some elegant examples in the 1949 LA.

@rpspringuel
Copy link
Contributor

I like the term "anchor" for this and think we might adopt that over on the annotation side, but I'd make that a different PR.

What are the desirable anchors for the initials? top and baseline have been proposed, but it seems @MRoth1910's issue would benefit from having the descent height being available. Should top be the cap height or the ascender height? Should both of those options be available? Does it make sense to add the median line (just to be complete, that's the other vertical reference point)? Which of these are actually possible? If the initial is an illumination (i.e. an image) how are these various options interpreted?

For the \greinitialvalign should the baseline option be the baseline of the first line of the score or the lowest line of the initial (these are the same for 1-line initials, but this makes a big difference for larger ones). Do we need separate settings for these? I would have thought that the baseline of the lowest line of the initial was sufficient, but perhaps other see something different.

Finally, mindful of the timeframe, which of these can we implement quickly and which are doable but will take time we don't really have right now. The TL pretest begins Saturday. Any feature we can't close out by the end of the week should be postponed to the next release.

@davidweichiang
Copy link

After looking at the results of #1608, I came to think that the only reasonable options were:

  • if a 1-line initial, align the baseline to the baseline
  • if 2+ lines, align the top of the initial to the top of the top line

Both can of course be adjusted using \greinitialraise.

When a 2-line initial's baseline is aligned to the lower baseline, it creates to me an optical illusion that the initial should be read with the second line. Also, computing the lowering distance takes a lot of code. I'd be happy deleting that code.

@rpspringuel
Copy link
Contributor

Those are, to me, the most logical ones and I’d be happy with just having them at this point. If some of the other options are requested after people start using the new feature, we can look at adding them as an enhancement. It’s not like we’re going to lose the progress we’ve made towards the ones we’ve been working on. It will always be there in the commit history if we need to resurrect it.

Sent with GitHawk

@davidweichiang
Copy link

If the default \greinitialraise is 0, then I imagine it will collide with the annotation. And it doesn't seem right for there to be a different default depending on \gresetinitiallines, does it?

@rpspringuel
Copy link
Contributor

I think it'll only collide if the annotation is multi-line or has a significant descender.

I'm looking through the tests and noticing that the vertical distance collapse that get's rid of the extra space above the initial is also collapsing distances that are intentional. Look at tex-output/per-line-multi. That test deliberately introduces lots of extra space on some of the lines. All that extra space is removed now.

@davidweichiang
Copy link

I'll take a good look at that test. However, I've noticed that that test sometimes fails, and when I re-run it, it passes. (I can't remember which PR I've noticed this for.) Is that the case for you?

@rpspringuel
Copy link
Contributor

I don't think I've noticed that with this particular test, but I have noticed that phenomena with other tests. I thought it was just because I was doing to many things at once and had accidentally changed my gregoriotex installation in the middle of the test suite, but if you're seeing it too, then it's probably a real issue. Maybe something wrong with how the correct number of LuaLaTeX passes is detected? The intermittent nature of the failure is what I don't get at the moment.

@davidweichiang
Copy link

davidweichiang commented Feb 5, 2025 via email

@davidweichiang
Copy link

Either I'm not seeing the problem on my end, or the latest commit fixed it. These are the tests that are failing for me:

gabc-output/glyphs/high-bars-5-lines.gabc : FAIL - [gabc-output/glyphs/high-bars-5-lines.gabc.out/page-0.png] differ from expected
gabc-output/glyphs/high-bars-2-lines.gabc : FAIL - [gabc-output/glyphs/high-bars-2-lines.gabc.out/page-0.png] differ from expected
gabc-output/glyphs/high-bars.gabc : FAIL - [gabc-output/glyphs/high-bars.gabc.out/page-0.png] differ from expected
gabc-output/glyphs/high-bars-3-lines.gabc : FAIL - [gabc-output/glyphs/high-bars-3-lines.gabc.out/page-0.png] differ from expected
magick: unable to open image 'bar-substitution.pdf': No such file or directory @ error/blob.c/OpenBlob/3596.
gabc-output/bar-substitution.gabc : FAIL - Failed to create images for gabc-output/bar-substitution.gabc.out/bar-substitution.pdf
tex-output/illumination/illumination.tex : FAIL - [tex-output/illumination/illumination.tex.out/page-0.png] differ from expected
tex-output/bugs/fix-1139/fix-1139.tex : FAIL - [tex-output/bugs/fix-1139/fix-1139.tex.out/page-0.png] differ from expected
tex-output/bugs/fix-1141/fix-1141.tex : FAIL - [tex-output/bugs/fix-1141/fix-1141.tex.out/page-0.png] differ from expected
tex-output/hyphenation/hyphenation.tex : FAIL - [tex-output/hyphenation/hyphenation.tex.out/page-0.png tex-output/hyphenation/hyphenation.tex.out/page-1.png] differ from expected

The high-bars ones are very slight differences that don't appear to have anything to do with initials; the others are all because the placement of 2-line initials changed.

@davidweichiang
Copy link

I'm trying out new options:

\gresetinitialanchor{...}: what part of the initial to align

  • top
  • baseline (default)
  • bottom

\gresetinitialposition{...}: what to align the initial to

  • firsttop = top of first line
  • lastbase = baseline of last line (default)
  • lastbottom = bottom of last line

I believe the most sensible options are top and firsttop with initialraise=-0.5cm, or bottom and lastbase with initialraise=0cm.

In these examples, the initial is deliberately too small:

Image

Unfortunately there are more tests now that don't pass. If the initial has a descender, this code now inserts a little more space below it than before.

@davidweichiang
Copy link

Very open to better ideas for the options, since I don't know much about what is needed. A simpler setup could be a single command \gresetinitialvalign that has four options: top = top to first line top, first = baseline to first line baseline, last = baseline to last line baseline, bottom = bottom to last line bottom.

@rpspringuel
Copy link
Contributor

I think the way you've set up the options is a good way of handling it. Fundamentally we have to pick the location on two different objects (the initial and the score) which are going to be the alignment base point, so it makes perfect sense to me that there be two settings, one for each object. That's how we do it for the annotations, though I much prefer the word anchor that you chose to my by.

For the other, position is fine. I can't think of a word that creates an instant connection to the anchor, which is about the only thing that I would be looking for at this point.

Can you push those option changes so that I can look at how the tests are affected?

@davidweichiang
Copy link

davidweichiang commented Feb 6, 2025

Yes, they're pushed. The reason that some more tests fails is probably boring but I can offer my guess if you want.

Summary of options:

description annotations initials
what text line the anchor is on \greannotationby n/a (there can be only one)
where the anchor is on that line \greannotationvalign \greinitialanchor
what music line the anchor is aligned with n/a (always first) \greinitialposition
where on that line the anchor is aligned with n/a (always top) \greinitialposition also

Does it bother you that \greinitialposition does two things in one command, whereas \greannotationby and \greannotationvalign split it into two commands?

In any case, note that top means the top staff line, not including any notes that go above the staff or any abovelinestext. This is to match the behavior of annotations. On the other hand, bottom really is the bottom of the box, including lyrics and translations. This should probably be documented, both for annotations and initials.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants