File size: 36,106 Bytes
128403f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 |
%% COLOURED BOXES
%
% change this info string if making any custom modification
\ProvidesPackage{sphinxpackageboxes}[2024/07/01 v7.4.0 advanced colored boxes]
% 7.4.0 removes usage of some booleans "...withbackgroundcolor" and
% "...withbordercolor" as well as \spx@boxes@border dimen which was
% actually really needed nowhere. This was done in sync with changes in
% sphinx.sty, sphinxlatexadmonitions.sty and sphinxlatexliterals.sty.
%
% Optionally executes \RequirePackage for:
%
% - pict2e. Ideally we would like to use the v0.4a 2020/08/16 release of this
% package as it allows dimensional arguments to its \moveto, \lineto, etc...
% Or we could use extra package "picture". We opt for custom wrappers
% \spx@moveto, \spx@lineto, ..., working with old versions.
%
% - ellipse. This package extends pict2e with elliptical arcs. Its author
% Daan Leijen also has contributed package longfbox which is part of
% TeXLive. Had I known about it, I would perhaps have based Sphinx CSS on
% top of longfbox at least partly. But this would not have spared me all
% the work in sphinx.sty, which was a long walk until 6.2.0 version.
% Besides I don't need the breakable boxes from longfbox, as Sphinx has
% its own rather advanced layer on top of framed. I would need to check if
% some thorny color issues solved by Sphinx (and not by tcolorbox) at page
% breaks are solved by longfbox as well. (I have not tested)
% At 6.2.0 refactoring, we do not wait for at begin document to try to load
% pict2e. Actually since 6.0.0 the default is for code-blocks to use
% rounded boxes, and the only reason since then to wait "at begin document"
% was to check if user had reverted that default and in fact pict2e was not
% needed. But with \sphinxbox, we can not know for sure even in that case
% that pict2e is not needed. And even back then it would have been possible
% to user to try to employ \sphinxsetup via raw directive in document body
% and require some rounded corners (which was thus impossible to satisfy).
% Time to be much simpler and attempt unconditionally to load pict2e
% immediately. This will also have advantage that we can use
% \@ifpackageloaded{pict2e} and not have to query and save its setting later
% at begin document.
\IfFileExists{pict2e.sty}
{\RequirePackage{pict2e}}
{\PackageWarningNoLine{sphinx}{%
The package pict2e is required for rounded boxes.\MessageBreak
It does not seem to be available on your system.\MessageBreak
Options for setting radii will be ignored%
}%
% Formerly a \sphinxbuildwarning was issued but if we did that now it
% would mean that the produced PDF will always have a red banner near its
% end about pict2e not being available if indeed it is not available, even
% if user has reverted the default and dropped rounded corners. Formerly
% the serious warning was done after having checked at begin document that
% indeed a rounded corner option had been used. As we drop the check now,
% let's be more discrete and simply duplicate the earlier warning to make
% it visible near end of compilation log and console output.
\AtEndDocument{\PackageWarningNoLine{sphinx}{%
The package pict2e is required for rounded boxes.\MessageBreak
As it does not seem to be available on your system,\MessageBreak
options setting radii have all been ignored}}%
}%
\IfFileExists{ellipse.sty}
{\RequirePackage{ellipse}}
{\PackageWarningNoLine{sphinx}{%
The package ellipse is required for elliptical corners.\MessageBreak
It does not seem to be available on your system.\MessageBreak
All non-straight corners will use circle arcs.%
}%
\AtEndDocument{\PackageWarningNoLine{sphinx}{%
The package ellipse is required for elliptical corners.\MessageBreak
As it does not seem to be available on your system,\MessageBreak
all non-straight corners have used circle arcs.}}%
}%
% The pict2e release v0.4b of 2020/09/30 does not allocate scratch dimen
% register \@tempdimd which ellipse package uses. Thus ellipse package is
% broken since (written on March 20, 2023). Simply allocate the register
% ourself to fix that, pending some upstream fix.
\@ifpackageloaded{ellipse}{\ifdefined\@tempdimd\else\newdimen\@tempdimd\fi}{}
% Provides box registers \spx@tempboxa, \spx@tempboxb usable in other places
\newbox\spx@tempboxa
\newbox\spx@tempboxb
%%%%%%%%%%%%%%%%
% Internal registers, conditionals, colors to be configured by each caller
% via a preliminary "setup" call
\newif\ifspx@boxes@withshadow
\newif\ifspx@boxes@insetshadow
%%% \newif\ifspx@boxes@withbackgroundcolor % removed at 7.4.0
\newif\ifspx@boxes@withshadowcolor
%%% \newif\ifspx@boxes@withbordercolor % removed at 7.4.0
\newif\ifspx@boxes@shadowinbbox
%
\newdimen\spx@boxes@border@top
\newdimen\spx@boxes@border@right
\newdimen\spx@boxes@border@bottom
\newdimen\spx@boxes@border@left
%
\newdimen\spx@boxes@padding@top
\newdimen\spx@boxes@padding@right
\newdimen\spx@boxes@padding@bottom
\newdimen\spx@boxes@padding@left
%
\newdimen\spx@boxes@shadow@xoffset
\newdimen\spx@boxes@shadow@yoffset
%
\newdimen\spx@boxes@radius@topleft@x
\newdimen\spx@boxes@radius@topright@x
\newdimen\spx@boxes@radius@bottomright@x
\newdimen\spx@boxes@radius@bottomleft@x
\newdimen\spx@boxes@radius@topleft@y
\newdimen\spx@boxes@radius@topright@y
\newdimen\spx@boxes@radius@bottomright@y
\newdimen\spx@boxes@radius@bottomleft@y
%
% These colors will be set to colors defined appropriately by caller of
% \spx@boxes@fcolorbox@setup macro
% spx@boxes@bordercolor
% spx@boxes@backgroundcolor
% spx@boxes@shadowcolor
% spx@boxes@textcolor
%%%%%%%%%%%%%%%%
% "setup" macro
%
% It must be called prior to \spx@boxes@fcolorbox for parameters of the latter
% to be initialized.
%
% It also prepares \spx@boxes@fcolorbox to expand to one of
% \spx@boxes@fcolorbox@rectangle or \spx@boxes@fcolorbox@rounded depending on
% the configuration and availability of the pict2e package.
%
% The #1 is one of: pre, topic, warning, danger, etc....
%
% We delay until here the parsing of radii options to extract x and y
% components.
\def\spx@boxes@setradii#1 #2 #3\@nnil#4#5{%
#4\dimexpr#1\relax
#5\dimexpr#2\relax
\ifdim#5=-\maxdimen#5#4\fi
% if one of them is zero or negative set both to zero
\ifdim#4>\z@\else#4\z@#5\z@\fi
\ifdim#5>\z@\else#4\z@#5\z@\fi
}%
% if ellipse.sty is not available ignore the second component of all radii
% specifications, use circle arcs with radius the x component
\@ifpackageloaded{ellipse}
{}
{\def\spx@boxes@setradii#1 #2 #3\@nnil#4#5{#4\dimexpr#1\relax #5#4}}
% Using \dimexpr for maximal user input flexibility.
\def\spx@boxes@fcolorbox@setup#1{%
\spx@boxes@border@top \dimexpr\@nameuse{spx@#1@border@top}\relax
\spx@boxes@border@right \dimexpr\@nameuse{spx@#1@border@right}\relax
\spx@boxes@border@bottom\dimexpr\@nameuse{spx@#1@border@bottom}\relax
\spx@boxes@border@left \dimexpr\@nameuse{spx@#1@border@left}\relax
%
\spx@boxes@padding@top \dimexpr\@nameuse{spx@#1@padding@top}\relax
\spx@boxes@padding@right \dimexpr\@nameuse{spx@#1@padding@right}\relax
\spx@boxes@padding@bottom\dimexpr\@nameuse{spx@#1@padding@bottom}\relax
\spx@boxes@padding@left \dimexpr\@nameuse{spx@#1@padding@left}\relax
%
\edef\spx@temp{\csname spx@#1@radius@topleft\endcsname\space}%
\expandafter
\spx@boxes@setradii
\spx@temp
{-\maxdimen}
\@nnil
\spx@boxes@radius@topleft@x\spx@boxes@radius@topleft@y
\edef\spx@temp{\csname spx@#1@radius@topright\endcsname\space}%
\expandafter
\spx@boxes@setradii
\spx@temp
{-\maxdimen}
\@nnil
\spx@boxes@radius@topright@x\spx@boxes@radius@topright@y
\edef\spx@temp{\csname spx@#1@radius@bottomright\endcsname\space}%
\expandafter
\spx@boxes@setradii
\spx@temp
{-\maxdimen}
\@nnil
\spx@boxes@radius@bottomright@x\spx@boxes@radius@bottomright@y
\edef\spx@temp{\csname spx@#1@radius@bottomleft\endcsname\space}%
\expandafter
\spx@boxes@setradii
\spx@temp
{-\maxdimen}
\@nnil
\spx@boxes@radius@bottomleft@x\spx@boxes@radius@bottomleft@y
%
\@nameuse{ifspx@#1@withshadow}%
\spx@boxes@withshadowtrue
\spx@boxes@shadow@xoffset \dimexpr\@nameuse{spx@#1@shadow@xoffset}\relax
\spx@boxes@shadow@yoffset \dimexpr\@nameuse{spx@#1@shadow@yoffset}\relax
\else
\spx@boxes@withshadowfalse
\fi
% not nesting in previous to avoid TeX conditional subtleties
\@nameuse{ifspx@#1@insetshadow}%
\spx@boxes@insetshadowtrue
\else
\spx@boxes@insetshadowfalse
\fi
%
\sphinxcolorlet{spx@boxes@bordercolor}{sphinx#1BorderColor}%
%
\sphinxcolorlet{spx@boxes@backgroundcolor}{sphinx#1BgColor}%
%
\@nameuse{ifspx@#1@withshadowcolor}%
\spx@boxes@withshadowcolortrue
\sphinxcolorlet{spx@boxes@shadowcolor}{sphinx#1ShadowColor}%
\else
\spx@boxes@withshadowcolorfalse
\fi
% Display elements pre, topic, warning et al. by default do not include
% shadow in box (legacy; and only topic actually uses a shadow per default)
% This may be refactored still more in future, but this 6.2.0 extra helped
% reduce workload from code-blocks (pre), contents (topic) and admonitions.
% As this conditional is a priori false and should only be changed locally
% (by \sphinxbox), this line is actually superfluous.
\spx@boxes@shadowinbboxfalse
\spx@boxes@fcolorbox@setup@fcolorbox
}
\@ifpackageloaded{pict2e}
{% pict2e is available and loaded
\def\spx@boxes@fcolorbox@setup@fcolorbox{%
\if1% use rounded boxes only if needed (rx>0 iff ry>0)
\ifdim\spx@boxes@radius@topleft@x >\z@0\fi
\ifdim\spx@boxes@radius@topright@x >\z@0\fi
\ifdim\spx@boxes@radius@bottomright@x>\z@0\fi
\ifdim\spx@boxes@radius@bottomleft@x >\z@0\fi
1\def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle}%
\else
\def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rounded}%
\fi
}% end of definition of setup@fcolorbox in case of presence of pict2e
}%
{% pict2e could not be loaded, we must always use fcolorbox@rectangle
\def\spx@boxes@fcolorbox@setup@fcolorbox{%
\def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle}%
}% end of definition of setup@fcolorbox in case of absence of pict2e
}% end of "no pict2e" branch
%%%%%%%%%%%%%%%%
% Support of box-decoration-break=slice
%
% 6.2.0 has renamed and moved this here from sphinxlatexliterals.sty,
% to facilitate supporting box-decoration-break=slice for all directives,
% not only code-block.
%
% It also modified when these post actions are executed, in order
% for openboth to be able to trigger usage of fcolorbox@rectangle.
% So now openbottom and opentop also take advantage of this possible
% optimization.
\def\spx@boxes@fcolorbox@setup@openbottom{%
\spx@boxes@border@bottom \z@
\spx@boxes@radius@bottomright@x\z@ \spx@boxes@radius@bottomright@y\z@
\spx@boxes@radius@bottomleft@x \z@ \spx@boxes@radius@bottomleft@y \z@
\spx@boxes@fcolorbox@setup@fcolorbox
}%
\def\spx@boxes@fcolorbox@setup@opentop{%
\spx@boxes@border@top \z@
\spx@boxes@radius@topright@x\z@ \spx@boxes@radius@topright@y\z@
\spx@boxes@radius@topleft@x \z@ \spx@boxes@radius@topleft@y \z@
\spx@boxes@fcolorbox@setup@fcolorbox
}%
\def\spx@boxes@fcolorbox@setup@openboth{%
\spx@boxes@border@top \z@
\spx@boxes@border@bottom \z@
\spx@boxes@radius@bottomright@x\z@ \spx@boxes@radius@bottomright@y\z@
\spx@boxes@radius@bottomleft@x \z@ \spx@boxes@radius@bottomleft@y \z@
\spx@boxes@radius@topright@x\z@ \spx@boxes@radius@topright@y\z@
\spx@boxes@radius@topleft@x \z@ \spx@boxes@radius@topleft@y \z@
\def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle}%
}%
%%%%%%%%%%%%%%%%
% \sphinxbox (added at 6.2.0)
%
% For an inline box, possibly rounded.
\newcommand\sphinxbox[1][]{% #1 stands for the options, they are... optional!
% \leavevmode makes sure TeX switches to paragraph mode, which is necessary
% if this is first in a paragraph or a list element. The \sphinxAtStartPar
% mechanism also ensures this automatically, if not redefined, but not with
% lualatex as then it is by default doing nothing.
\leavevmode
\begingroup
\ifcsname spx@boxes@sphinxbox@isnested\endcsname
% nested boxes reset all box options to be as the \sphinxboxsetup
% defaults, before applying their specific options
\spx@boxes@sphinxbox@reset
\else
% top layer box, toggle the nested flag
\csname spx@boxes@sphinxbox@isnested\endcsname
\fi
% we do not use \sphinxboxsetup as it is a user command extending the
% "reset" storage
\setkeys{sphinxbox}{#1}%
\spx@boxes@fcolorbox@setup{box}%
\spx@boxes@shadowinbboxtrue% inline sphinx boxes include shadow in bbox
\ifspx@box@withtextcolor\color{sphinxboxTextColor}\fi
%
% MEMO: the fcolorbox@{rectangle,rounded} draw the contents (which here
% will be encapsulated as \box\z@) last, i.e. after shadow, background,
% and border and their color commands. The \reset@color from naked
% top-level \color commands in argument (which can not arise from Sphinx
% mark-up anyhow) would end up being placed via color.sty \aftergroup core
% mechanism in token stream after \spx@boxes@sphinxbox@a (which is the
% first \aftergroup) hence after the box contents with its unbalanced
% color pushes is shipped to PDF. So the missing color pop specials are
% inserted then in correct order at correct place (after the \endgroup at
% end of \spx@boxes@sphinxbox@a but this is not relevant) and do not end
% up causing havoc in push/pop pairs (and all this happens on same page).
%
% There is thus no reason here to go to the trouble to add an extra
% \color@begingroup/\color@endgroup or like pair to encapsulate the caught
% contents in order for the \box\z@ to contain as many color pop's as it
% has color pushes. But as this is subtle, this comment was added for
% future maintenance. Actually even if the contents were not drawn last,
% their (purely theoretical, as Sphinx mark-up can not create it) missing
% color pop's would not have caused trouble I guess as long as the color
% insertions for shadow, background, border are correctly balanced.
\setbox0\hbox\bgroup\aftergroup\spx@boxes@sphinxbox@a
\afterassignment\spx@box@TeXextras
\let\next=%
}
\def\spx@boxes@sphinxbox@a{\spx@boxes@fcolorbox{%
\ifspx@opt@box@addstrut\strut\fi\box\z@}\endgroup}
\newcommand\newsphinxbox[2][]{%
\newcommand#2[1][]{\sphinxbox[#1,##1]}%
}
% Let's catch \renewsphinxbox[...]{\sphinxbox} which would cause \sphinxbox
% to fall into infinite looping on use.
\newcommand\renewsphinxbox[2][]{%
\in@{#2}{\sphinxbox}%
\ifin@
\PackageWarning{sphinx}{Attempt to \string\renewsphinxbox\space
the \string\sphinxbox\space command\MessageBreak
itself. This is not allowed and will be ignored.\MessageBreak
Reported}%
\else
\renewcommand#2[1][]{\sphinxbox[#1,##1]}%
\fi
}
%%%%%%%%%%%%%%%%
% MACROS
%
% \spx@boxes@fcolorbox expands either to \spx@boxes@fcolorbox@rectangle
% or \spx@boxes@fcolorbox@rounded depending on preliminary set-up.
%
% This is decided by the "setup" which must have been executed by the caller.
% Let's give it some (thus unneeded) default fall-back for clarity.
\def\spx@boxes@fcolorbox{\spx@boxes@fcolorbox@rectangle}
%
% A macro \spx@boxes@fcolorbox@setuphook used to be executed at start of the
% \hbox constructs (rectangle or rounded). This was used until 6.2.0 for the
% support of pre_box-decoration-break option, hence was really an internal
% non-public macro. As it is not needed anymore, with some hesitation it got
% entirely removed at 6.2.0 on the occasion of a refactoring of interactions of
% this file with sphinxlatexliterals.sty. Besides its name should have been
% rather something such as \spx@boxes@fcolorbox@atstartofhbox.
%
% After "setup", \spx@boxes@fcolorbox expands to one of:
%
% - \spx@boxes@fcolorbox@rectangle (4 padding parameters, 4 border widths, 2 shadow widths,
% and three colours: background, border and shadow; same as in CSS styling)
%
% It branches to one of:
% - \spx@boxes@fcolorbox@externalshadow
% - \spx@boxes@fcolorbox@insetshadow (same concept of "inset" as in CSS styling)
%
% - \spx@boxes@fcolorbox@rounded: rounded corners using the picture environment
% and pict2e package for its low-weight interface to PDF graphics operations
% MEMO: we have also successfully tested usage of tcolorbox.sty (its \tcbox) but
% decided to use pict2e.sty for the following reasons:
% 1- PDF build was observed to be an order of magnitude faster,
% 2- the boxes we can do with pict2e appear to be fancy enough,
% almost matching what one can see in HTML renderings,
% 2- orders of magnitude smaller dependency (tcolorbox uses the pgf TeX
% framework), although on Ubuntu it seems texlive-pictures is
% needed which also contains the whole of pgf/TikZ... so this point
% is a bit moot...
% For code-blocks, attachments of caption and continuation hints are done
% exactly as prior to extension of Sphinx via this package, whether the box
% has straight or rounded corners. The vertical space occupied is the same,
% if nothing else is changed (perhaps in future the title itself could be also
% rendered in a rounded box?)
%%%%%%%%
%//// \spx@boxes@fcolorbox@rectangle
%
% This box will have the same baseline as its argument (which is typeset in
% horizontal mode). It takes into account four border widths parameters, four
% padding parameters, two shadow widths (each possibly negative), and three
% colors: background, border and shadow. Its boundary box takes into account
% border and padding. Width of shadow is taken into account if the boolean
% \ifspx@boxes@shadowinbbox is \iftrue. The "setup" sets it to \iffalse.
% Prior to 6.2.0, shadow size was included in bbox but the callers manually
% removed it by extra steps. The \sphinxbox command sets it to \iftrue after
% the "setup".
%
% It is up to the caller to take extra steps if the border and padding must go
% into margin as well (see sphinxlatexliterals.sty for how this is done in
% \spx@verb@FrameCommand).
%
% In usage as a "FrameCommand" with framed.sty, the argument will already be a
% collection of TeX boxes (and interline glues).
%
% This was designed so that the parameters configured by "setup" are
% interpreted as they would be as CSS properties in an HTML context.
\long\def\spx@boxes@fcolorbox@rectangle#1{%
\hbox\bgroup
\setbox\spx@tempboxa
\hbox{\kern\dimexpr\spx@boxes@border@left+\spx@boxes@padding@left\relax
{#1}%
\kern\dimexpr\spx@boxes@padding@right+\spx@boxes@border@right\relax}%
\ht\spx@tempboxa
\dimexpr\ht\spx@tempboxa+\spx@boxes@border@top+\spx@boxes@padding@top\relax
\dp\spx@tempboxa
\dimexpr\dp\spx@tempboxa+\spx@boxes@padding@bottom+\spx@boxes@border@bottom\relax
\ifspx@boxes@insetshadow
\expandafter\spx@boxes@fcolorbox@insetshadow
\else
\expandafter\spx@boxes@fcolorbox@externalshadow
\fi
}
% external shadow
\def\spx@boxes@fcolorbox@externalshadow{%
% reserve space to external shadow if on left
\ifspx@boxes@withshadow
\ifspx@boxes@shadowinbbox
\ifdim\spx@boxes@shadow@xoffset<\z@\kern-\spx@boxes@shadow@xoffset\fi
\fi
\fi
% BACKGROUND
% draw background and move back to reference point
{\color{spx@boxes@backgroundcolor}%
\vrule\@height\ht\spx@tempboxa
\@depth\dp\spx@tempboxa
\@width\wd\spx@tempboxa
\kern-\wd\spx@tempboxa
}%
% BOX SHADOW
% draw shadow and move back to reference point
\ifspx@boxes@withshadow
\vbox{%
\moveright\spx@boxes@shadow@xoffset
\hbox{\lower\spx@boxes@shadow@yoffset
\vbox{\ifspx@boxes@withshadowcolor
\color{spx@boxes@shadowcolor}%
\else
% 6.2.0: guard against a manually inserted \color command in
% contents which could leak at a page break to the shadow
\normalcolor
\fi
\ifdim\spx@boxes@shadow@yoffset<\z@
\hrule\@height-\spx@boxes@shadow@yoffset
\kern\spx@boxes@shadow@yoffset
\fi
\setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa{%
\ifdim\spx@boxes@shadow@xoffset<\z@\vrule\@width-\spx@boxes@shadow@xoffset\fi
\hss
\ifdim\spx@boxes@shadow@xoffset>\z@\vrule\@width\spx@boxes@shadow@xoffset\fi
}%
\ht\spx@tempboxb\ht\spx@tempboxa
\dp\spx@tempboxb\dp\spx@tempboxa
\box\spx@tempboxb
\ifdim\spx@boxes@shadow@yoffset>\z@
\kern-\spx@boxes@shadow@yoffset
\hrule\@height\spx@boxes@shadow@yoffset
\fi
\kern-\dp\spx@tempboxa
}% end of \vbox, attention it will have zero depth if yoffset>0
\kern-\wd\spx@tempboxa
\ifdim\spx@boxes@shadow@xoffset>\z@
\kern-\spx@boxes@shadow@xoffset
\fi
}% end of \hbox, attention its depth is only yoffset if yoffset>0
}% end of \vbox
\fi % end of shadow drawing, and we are back to horizontal reference point
% BOX BORDER
% 7.4.0 requires a set border color
\vbox{\color{spx@boxes@bordercolor}%
\hrule\@height\spx@boxes@border@top
\kern-\spx@boxes@border@top
\setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa
{\vrule\@width\spx@boxes@border@left
\hss\vrule\@width\spx@boxes@border@right
}%
\ht\spx@tempboxb\ht\spx@tempboxa
\dp\spx@tempboxb\dp\spx@tempboxa
\box\spx@tempboxb
\kern-\spx@boxes@border@bottom
\hrule\@height\spx@boxes@border@bottom
\kern-\dp\spx@tempboxa
}% attention this box has zero depth due to \hrule at bottom
% step back to horizontal reference point
\kern-\wd\spx@tempboxa
% end of border drawing
% CONTENTS
% adjust the total depth to include the bottom shadow
\ifspx@boxes@withshadow
\ifdim\spx@boxes@shadow@yoffset>\z@
\dp\spx@tempboxa\dimexpr\dp\spx@tempboxa+\spx@boxes@shadow@yoffset\relax
\fi
\fi
\box\spx@tempboxa
% include lateral shadow in total width
\ifspx@boxes@withshadow
\ifspx@boxes@shadowinbbox
\ifdim\spx@boxes@shadow@xoffset>\z@\kern\spx@boxes@shadow@xoffset\fi
\fi
\fi
\egroup
}
% inset shadow
%
% The parameters signs are interpreted as in CSS styling.
\def\spx@boxes@fcolorbox@insetshadow{%
% BACKGROUND
% draw background and move back to reference point
% 7.4.0 always assumes a background color
{\color{spx@boxes@backgroundcolor}%
\vrule\@height\ht\spx@tempboxa
\@depth\dp\spx@tempboxa
\@width\wd\spx@tempboxa
\kern-\wd\spx@tempboxa
}%
% BOX SHADOW
% draw shadow and move back to reference point
\ifspx@boxes@withshadow
\hbox{\vbox{\ifspx@boxes@withshadowcolor
\color{spx@boxes@shadowcolor}%
\else
% 6.2.0: guard against a manually inserted \color command in
% contents which could leak at a page break to the shadow
\normalcolor
\fi
% NOTA BENE
% We deliberately draw shadow partially under an area later covered by frame
% with the idea to avoid anti-aliasing problems but in fact this may be a bad
% idea with border is thin.
% This may need some extra testing with PDF viewers... reports welcome!
\ifdim\spx@boxes@shadow@yoffset>\z@
\hrule\@height\dimexpr\spx@boxes@border@top+\spx@boxes@shadow@yoffset\relax
\kern-\spx@boxes@shadow@yoffset
\kern-\spx@boxes@border@top
\fi
\setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa{%
\ifdim\spx@boxes@shadow@xoffset>\z@
\vrule\@width\dimexpr\spx@boxes@border@left+\spx@boxes@shadow@xoffset\relax\fi
\hss
\ifdim\spx@boxes@shadow@xoffset<\z@
\vrule\@width\dimexpr-\spx@boxes@shadow@xoffset+\spx@boxes@border@right\relax\fi
}%
\ht\spx@tempboxb\ht\spx@tempboxa
\dp\spx@tempboxb\dp\spx@tempboxa
\box\spx@tempboxb
\ifdim\spx@boxes@shadow@yoffset<\z@
\kern\spx@boxes@shadow@yoffset
\kern-\spx@boxes@border@bottom
\hrule\@height\dimexpr-\spx@boxes@shadow@yoffset+\spx@boxes@border@bottom\relax
\fi
\kern-\dp\spx@tempboxa
}% end of \vbox, attention it will have zero depth if yoffset<0
\kern-\wd\spx@tempboxa
}% end of \hbox, attention its depth is only |yoffset| if yoffset<0
\fi % end of inset shadow drawing, and we are back to horizontal reference point
% BOX BORDER
% 7.4.0 requires a set border color
\vbox{\color{spx@boxes@bordercolor}%
\hrule\@height\spx@boxes@border@top
\kern-\spx@boxes@border@top
\setbox\spx@tempboxb\hb@xt@\wd\spx@tempboxa
{\vrule\@width\spx@boxes@border@left
\hss\vrule\@width\spx@boxes@border@right
}%
\ht\spx@tempboxb\ht\spx@tempboxa
\dp\spx@tempboxb\dp\spx@tempboxa
\box\spx@tempboxb
\kern-\spx@boxes@border@bottom
\hrule\@height\spx@boxes@border@bottom
\kern-\dp\spx@tempboxa
}% attention this box has zero depth due to \hrule at bottom
% step back to horizontal reference point
\kern-\wd\spx@tempboxa
% end of border drawing
% CONTENTS
\box\spx@tempboxa
\egroup
}
% let's abort input if pict2e package could not be loaded.
% To be extra safe we also alias @rounded to @rectangle but
% a priori the architecture is done so that @rounded will never
% be called in that case by other Sphinx LaTeX components.
\@ifpackageloaded{pict2e}
{}
{\def\spx@boxes@fcolorbox@rounded{\spx@boxes@fcolorbox@rectangle}%
\endinput
}
% we proceed now in the context of pict2e being available and loaded
% (TeX being a macro-expansion based language it would have
% swallowed all the coming definitions even if pict2e
% had in fact not been loaded... but we aborted the input above)
%%%%%%%%
%//// \spx@boxes@fcolorbox@rounded
%
% Prior to 6.2.0, a constant border-width was applied as the border was
% obtained as a \strokepath. This allowed 4 distinct radii but not to vary the
% border widths. Now the border is drawn by two \fillpath operation, the first
% one filling up to external border, the second one actually filling for the
% background paradoxically on top of it, up to internal border path.
%
% This 6.2.0 abandonment of \strokepath allowed great simplification in
% supporting opentop, openbottom and openboth situations, and it can
% allow automatic support of openleft and openright analogs.
%
% And 6.2.0 also implements elliptical arcs thanks to ellipse package,
% which extends pict2e.
% Currently, inset shadow is not supported.
%
% Prior to 6.2.0 an inset shadow triggered the rectangle variant, so we never
% ended here, but now it is simply ignored. This change does not appear to me
% to be breaking, as it changes output only for conf.py's specifying both
% rounded corners and an inset shadow and the documentation said it was
% incompatible.
% wrappers for pict2e usage if old
% Better not to copy over 2020 pict2e definitions in case
% something internal changes
% However our wrappers will work ONLY with dimensional inputs
% No need to pre-expand the arguments
% Braces in case the expression uses parentheses
\def\spx@moveto(#1,#2){\moveto({\strip@pt\dimexpr#1\relax},{\strip@pt\dimexpr#2\relax})}
\def\spx@lineto(#1,#2){\lineto({\strip@pt\dimexpr#1\relax},{\strip@pt\dimexpr#2\relax})}
% attention here the [N] becomes mandatory
% \circlearc[<N>]{<X>}{<Y>}{<RAD>}{<ANGLE1>}{<ANGLE2>}
\def\spx@circlearc[#1]#2#3#4%#5#6
{\circlearc[#1]{\strip@pt\dimexpr#2\relax}%
{\strip@pt\dimexpr#3\relax}%
{\strip@pt\dimexpr#4\relax}%
}
% attention here too the [N] becomes mandatory
% the core path macro of ellipse.sty. Thanks to Daan Leijen, author of this
% package.
% \elliparc [<initial>]{<center-x>}{<center-y>}{<x-rad>}{<y-rad>}{<start-angle>}{<end-angle>}
% maybe this wrapper is unneeded but I don't have real time to check
\def\spx@elliparc[#1]#2#3#4#5%#6#7
{\elliparc[#1]{\strip@pt\dimexpr#2\relax}%
{\strip@pt\dimexpr#3\relax}%
{\strip@pt\dimexpr#4\relax}%
{\strip@pt\dimexpr#5\relax}%
}
% Macro whose execution prepares a path to be either stroked or filled
% Only fill operation is used at 6.2.0. The radii are given by the set box
% parameters, but the width and height are in \spx@width and \spx@height. A
% \put command will be used for appropriate shifts.
% 6.2.0 adds elliptical corners!
% But I feel perhaps I need to think about how x-radius and y-radius should
% interact with border-width. So consider output WIP for time being.
\def\spx@boxes@border@defpath{%
\spx@moveto(\spx@boxes@radius@bottomleft@x,\z@)% our \spx@moveto is a bit rigid
% and we must use \z@ not 0 here
\spx@lineto(\spx@width-\spx@boxes@radius@bottomright@x,\z@)%
% x and y radii are either both positive or both zero
% probably not needed to actually guard against the latter case,
% let's do it nevertheless
\ifdim\spx@boxes@radius@bottomright@x>\z@
\ifdim\spx@boxes@radius@bottomright@x=\spx@boxes@radius@bottomright@y
\spx@circlearc[2]{\spx@width-\spx@boxes@radius@bottomright@x}%
{\spx@boxes@radius@bottomright@y}%
{\spx@boxes@radius@bottomright@x}{-90}{0}%
\else
\spx@elliparc[2]{\spx@width-\spx@boxes@radius@bottomright@x}%
{\spx@boxes@radius@bottomright@y}%
{\spx@boxes@radius@bottomright@x}
{\spx@boxes@radius@bottomright@y}{-90}{0}%
\fi
\fi
\spx@lineto(\spx@width,%
\spx@height-\spx@boxes@radius@topright@y)%
\ifdim\spx@boxes@radius@topright@x>\z@
\ifdim\spx@boxes@radius@topright@x=\spx@boxes@radius@topright@y
\spx@circlearc[2]{\spx@width-\spx@boxes@radius@topright@x}
{\spx@height-\spx@boxes@radius@topright@y}%
{\spx@boxes@radius@topright@x}{0}{90}%
\else
\spx@elliparc[2]{\spx@width-\spx@boxes@radius@topright@x}
{\spx@height-\spx@boxes@radius@topright@y}%
{\spx@boxes@radius@topright@x}%
{\spx@boxes@radius@topright@y}{0}{90}%
\fi
\fi
\spx@lineto(\spx@boxes@radius@topleft@x,\spx@height)%
\ifdim\spx@boxes@radius@topleft@x>\z@
\ifdim\spx@boxes@radius@topleft@x=\spx@boxes@radius@topleft@y
\spx@circlearc[2]{\spx@boxes@radius@topleft@x}%
{\spx@height-\spx@boxes@radius@topleft@y}%
{\spx@boxes@radius@topleft@x}{90}{180}%
\else
\spx@elliparc[2]{\spx@boxes@radius@topleft@x}%
{\spx@height-\spx@boxes@radius@topleft@y}%
{\spx@boxes@radius@topleft@x}%
{\spx@boxes@radius@topleft@y}{90}{180}%
\fi
\fi
\spx@lineto(\z@,\spx@boxes@radius@bottomleft@y)%
\ifdim\spx@boxes@radius@bottomleft@x>\z@
\ifdim\spx@boxes@radius@bottomleft@x=\spx@boxes@radius@bottomleft@y
\spx@circlearc[2]{\spx@boxes@radius@bottomleft@x}%
{\spx@boxes@radius@bottomleft@y}%
{\spx@boxes@radius@bottomleft@x}{180}{270}%
\else
\spx@elliparc[2]{\spx@boxes@radius@bottomleft@x}%
{\spx@boxes@radius@bottomleft@y}%
{\spx@boxes@radius@bottomleft@x}%
{\spx@boxes@radius@bottomleft@y}{180}{270}%
\fi
\fi
}% end of definition of \spx@boxes@border@defpath
% The customization of the various parameters must have been done via an
% appropriate call to \spx@boxes@fcolorbox@setup, which will have set up
% \spx@boxes@fcolorbox to expand to \spx@boxes@fcolorbox@rounded, and will
% have set its various parameters.
%
\long\def\spx@boxes@fcolorbox@rounded #1{%
\hbox{%
\ifspx@boxes@withshadow
\ifspx@boxes@insetshadow
\spx@boxes@withshadowfalse % ignore inset shadow
\fi
\fi
% reserve space to external shadow if on left
\ifspx@boxes@withshadow
\ifspx@boxes@shadowinbbox
\ifdim\spx@boxes@shadow@xoffset<\z@\kern-\spx@boxes@shadow@xoffset\fi
\fi
\fi
\vbox{%
% adjust vertical bbox
\ifspx@boxes@withshadow
\ifdim\spx@boxes@shadow@yoffset<\z@
\kern-\spx@boxes@shadow@yoffset
\fi
\fi
\setlength{\unitlength}{1pt}%
\setbox\spx@tempboxa
\hbox{\kern\dimexpr\spx@boxes@border@left+\spx@boxes@padding@left\relax
{#1}%
\kern\dimexpr\spx@boxes@padding@right+\spx@boxes@border@right\relax}%
\ht\spx@tempboxa
\dimexpr\ht\spx@tempboxa+\spx@boxes@border@top+\spx@boxes@padding@top\relax
\dp\spx@tempboxa
\dimexpr\dp\spx@tempboxa+\spx@boxes@padding@bottom+\spx@boxes@border@bottom\relax
\edef\spx@width{\number\wd\spx@tempboxa sp}%
\edef\spx@height{\number\dimexpr\ht\spx@tempboxa+\dp\spx@tempboxa sp}%
\hbox{%
\begin{picture}%
% \strip@pt\dimexpr to work around "old" LaTeX picture limitation
% (we could use the "picture" package, this would add another dependency)
(\strip@pt\dimexpr\spx@width\relax,\strip@pt\dimexpr\spx@height\relax)%
\spx@boxes@border@defpath
\ifspx@boxes@withshadow
\ifspx@boxes@withshadowcolor
\color{spx@boxes@shadowcolor}%
\else
% 6.2.0: here and elsewhere guard against a manually inserted
% \color command in contents which could leak to the shadow
% to the shadow
\normalcolor
\fi
\put(\strip@pt\spx@boxes@shadow@xoffset,%
\strip@pt\dimexpr-\spx@boxes@shadow@yoffset\relax)
{\fillpath}%
\fi
\spx@boxes@border@defpath% must be redone after each \fillpath! (even if
% was in a \put)
% 7.4.0 requires a set border color
\color{spx@boxes@bordercolor}%
\fillpath
% and backgroundcolor command
\color{spx@boxes@backgroundcolor}%
\edef\spx@width{\number\dimexpr\spx@width-\spx@boxes@border@left
-\spx@boxes@border@right sp}%
\edef\spx@height{\number\dimexpr\spx@height-\spx@boxes@border@top
-\spx@boxes@border@bottom sp}%
% redefine a path (in relative coordinates) matching the area delimited
% by the internal borders
\spx@boxes@border@defpath
% use \put to shift, and fill it with background color
\put(\strip@pt\spx@boxes@border@left,\strip@pt\spx@boxes@border@bottom)
{\fillpath}%
\end{picture}}% end of picture \hbox in \vbox
% back-up vertically for outputting the contents
\kern-\dimexpr\ht\spx@tempboxa+\dp\spx@tempboxa\relax
% adjust vertical bbox
\ifspx@boxes@withshadow
\ifdim\spx@boxes@shadow@yoffset>\z@
\dp\spx@tempboxa\dimexpr\dp\spx@tempboxa+\spx@boxes@shadow@yoffset\relax
\fi
\fi
% inhibit TeX's "line skip" adjustment when piling up hboxes in a vbox
\nointerlineskip
\box\spx@tempboxa
}% end of \vbox
% include lateral shadow in total width
\ifspx@boxes@withshadow
\ifspx@boxes@shadowinbbox
\ifdim\spx@boxes@shadow@xoffset>\z@\kern\spx@boxes@shadow@xoffset\fi
\fi
\fi
}% end of \hbox
}%
\endinput
|