From 441b90d40e05f8abd69f44312dace4a0713c4edc Mon Sep 17 00:00:00 2001 From: Eric Biedert Date: Sun, 6 Oct 2024 18:12:04 +0200 Subject: [PATCH] Allow height `auto` to inherit without rescaling --- README.md | 2 +- src/droplet.typ | 40 ++++++++++++++++++++++++--------------- tests/explicit/ref/1.png | Bin 14893 -> 21524 bytes tests/explicit/test.typ | 5 +++++ 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index ff8cf07..2c7700c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ The package comes with a single `dropcap` function that takes content and a few | Parameter | Description | Default | |------------------|-------------------------------------------------------------------|---------| -| `height` | The height of the dropped capital in lines or as length. | `2` | +| `height` | The height of the dropped capital in lines, as length, or `auto`. | `2` | | `justify` | Whether the text should be justified. | `auto` | | `gap` | The space between the first letter and the text. | `0pt` | | `hanging-indent` | The indent of lines after the first. | `0pt` | diff --git a/src/droplet.typ b/src/droplet.typ index 23d9fbd..79fd8a9 100644 --- a/src/droplet.typ +++ b/src/droplet.typ @@ -4,23 +4,14 @@ // Sets the font size so the resulting text height matches the given height. // -// If not specified otherwise in "text-args", the top and bottom edge of the -// resulting text element will be set to "bounds". -// // Parameters: // - height: The target height of the resulting text. -// - text-args: Arguments to be passed to the underlying text element. +// - text-args: Named arguments to be passed to the underlying text element. // - body: The content of the text element. // -// Returns: The text with the set font size. +// Returns: The text with the adjusted size. #let sized(height, ..text-args, body) = context { - let styled-text = text.with( - top-edge: "bounds", - bottom-edge: "bounds", - ..text-args.named(), - body - ) - + let styled-text = text.with(..text-args.named(), body) let factor = height / measure(styled-text(1em)).height styled-text(factor * 1em) } @@ -47,7 +38,8 @@ // // Parameters: // - height: The height of the first letter. Can be given as the number of -// lines (integer) or as a length. +// lines (integer) or as a length. If set to `auto`, no scaling is +// applied. // - justify: Whether to justify the text next to the first letter. // - gap: The space between the first letter and the text. // - hanging-indent: The indent of lines after the first line. @@ -71,6 +63,18 @@ ..text-args, body ) = layout(bounds => { + let text-args = text-args + + if height != auto { + // Set default top and bottom edge to "bounds" if not specified. + if "top-edge" not in text-args.named() { + text-args = arguments(..text-args, top-edge: "bounds") + } + if "bottom-edge" not in text-args.named() { + text-args = arguments(..text-args, bottom-edge: "bounds") + } + } + let (letter, rest) = if text-args.pos() == () { extract(body) } else { @@ -82,7 +86,13 @@ letter = transform(letter) } - let letter-height = resolve-height(height) + let letter-height = if height == auto { + // Don't rescale if height is set to auto. + measure(text(..text-args.named(), letter)).height + } else { + resolve-height(height) + } + let depth = resolve-height(depth) // Create dropcap with the height of sample content. @@ -124,7 +134,7 @@ height - measure(new).height - par.leading.to-absolute() ) - if top-position >= letter-height + depth and height > prev-height { + if top-position >= letter-height + depth - 1e-6pt and height > prev-height { // Limit reached, new element doesn't fit anymore split(rest, index - 1) break diff --git a/tests/explicit/ref/1.png b/tests/explicit/ref/1.png index d0e5525f5745ca493b831988b4699daed34cf606..360c778fcd68bf361bfe8701b0baad0bf51f0e2a 100644 GIT binary patch delta 8534 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⪙3Dvz6>}Iu{LKSes{#<9Z|3iNEXV~G9gG;J<1+IAe zI{=s_nNGI*90x~~S`TEXiQjqD#NcWHBAtS@dqn(ehTe{E6?M;jmT;TpakhrrthRp= zWwDvl;rxU5`i^>?ItCpE_74MKX_(Dw-Jcp}GY@~`pxJ7*9DnTgJeD11tHpW-UK-dw zWZD;$46@qH5&uG4W3gHK7nes^Y+=jU5Yp*^UHiJS$vq*5L=Bbn( ze$%X|SLb=jW&Y1jE-ZJ$MKw{GzM_WRQ~iP#EvgYx0*w{(4O(z0Rt~vgRIBQNmZwx~ z%c90fDUHo-%blC;&A0ODI*0p3t!n2g`G!&pS{5~4%4p2&!=3Bb{s;U!^@39K(N=#b z^=eC_mV?uYRy%}uqOP1HR~Z9Uxb2Q-X6ih$$B@21O)WS&khXgF$2edo`Ltn z-qDUWTGMP!0z^8;X#wTzoXd=7u2*&k9H z;AER#023zM;*?o(seHFf$7kl8KIZ3F;T}<^D^-HlMFrEOGg55{b(Q+|1AZ@W0ps2S z;$;o6Ms~vDwuP`%^6N+Ch)M&7w=D)o=uJrNPy%z+6<8~uz>YojqrNTsfD5J|T+4JK z@QA4Zuw4ey&lA28PQ63buKQA>f>Wj%l3*b+BtjBIHb zb*`kLV)EMtu)JFBCj;W>(hVz+c;!`^SEZrUGsILHfRkSN=Cx8Um z36Q9YsP&{e_Dim{8?)+Vw~e}9sbgplt2PxhRvsDBLF(!pI-7r5<(<1thSkb14}j6~ zA7Ha&f$vX%6|xDquZb44|nSNdhK(gclL!=B?AP1o6kC(sisK>IhzCz2++6aw(AdUFrGEa`f_4Y#nDvtX} zW+{aa%doSIlB|FHg^}{$nldIx(wt>=S5O)3SBn7%SFh&H8z@s&I}?Unsd&wM2WaC} z@|@-H2alACSEq*-gUbl-Vt8N80&tuRky)RYzvHXcm6G3IrWEpoq`Ut$%96D71sRK$ zEL*wi#TTAmw&dBT=g(P#%f%Fc=ideRcv^DG^mka9lrn!KjcaqFCLF3r8nN2RxwwR_ z;IjKq08=lcue=TWb?%MHqc@P98Xx`mQEHuyOUMSunKgWTRt0q&Sqd<#0N~$KlT(rw zo}QLGb9xT5XQU*p;AC8`af{lxMQt#m8c~g?MpT0l)re|DH5gHis76$S5!HxlL^T*u pji^RcgApIqh-ySN7*W3`{{>O&T#cesEB^oh002ovPDHLkV1l4jk0by9 diff --git a/tests/explicit/test.typ b/tests/explicit/test.typ index 3f31da9..2d92e73 100644 --- a/tests/explicit/test.typ +++ b/tests/explicit/test.typ @@ -8,3 +8,8 @@ #dropcap(square(size: 1em), gap: 1em, height: 3, lorem(13)) #dropcap(square(), height: 14pt, gap: 1em, lorem(10)) #dropcap[\#1][The winner has won what was to win.] +#dropcap(height: auto, gap: 1em)[ + #figure(rect(), caption: [Rect]) +][ + To the left is a rectangle inside a figure with a caption, that this text is wrapped around. +]