├── .gitignore ├── LICENSE ├── README.md ├── build.lua ├── support ├── build-config.lua └── dtxchecksum.lua └── wrapstuff.dtx /.gitignore: -------------------------------------------------------------------------------- 1 | *.aux 2 | *.auxlock 3 | *.bak 4 | *.bbl 5 | *.bcf 6 | *.blg 7 | *.bst 8 | *.cls 9 | *.def 10 | *.dvi 11 | *.fd 12 | *.fdb_latexmk 13 | *.fls 14 | *.glg 15 | *.glo 16 | *.gls 17 | *.hd 18 | *.id 19 | *.idx 20 | *.ilg 21 | *.ind 22 | *.ins 23 | *.log 24 | *.md5 25 | *.out 26 | *.pdf 27 | *.sav 28 | *.sty 29 | *.swp 30 | *.synctex.gz 31 | *.synctex.gz(busy) 32 | *.synctex(busy) 33 | *.tmp 34 | *.toc 35 | *.ver 36 | *.xdv 37 | *.zip 38 | *~ 39 | build/ 40 | support/*.id 41 | support/*.txt 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The LaTeX Project Public License 2 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- 3 | 4 | LPPL Version 1.3c 2008-05-04 5 | 6 | Copyright 1999 2002-2008 LaTeX3 Project 7 | Everyone is allowed to distribute verbatim copies of this 8 | license document, but modification of it is not allowed. 9 | 10 | 11 | PREAMBLE 12 | ======== 13 | 14 | The LaTeX Project Public License (LPPL) is the primary license under 15 | which the LaTeX kernel and the base LaTeX packages are distributed. 16 | 17 | You may use this license for any work of which you hold the copyright 18 | and which you wish to distribute. This license may be particularly 19 | suitable if your work is TeX-related (such as a LaTeX package), but 20 | it is written in such a way that you can use it even if your work is 21 | unrelated to TeX. 22 | 23 | The section `WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE', 24 | below, gives instructions, examples, and recommendations for authors 25 | who are considering distributing their works under this license. 26 | 27 | This license gives conditions under which a work may be distributed 28 | and modified, as well as conditions under which modified versions of 29 | that work may be distributed. 30 | 31 | We, the LaTeX3 Project, believe that the conditions below give you 32 | the freedom to make and distribute modified versions of your work 33 | that conform with whatever technical specifications you wish while 34 | maintaining the availability, integrity, and reliability of 35 | that work. If you do not see how to achieve your goal while 36 | meeting these conditions, then read the document `cfgguide.tex' 37 | and `modguide.tex' in the base LaTeX distribution for suggestions. 38 | 39 | 40 | DEFINITIONS 41 | =========== 42 | 43 | In this license document the following terms are used: 44 | 45 | `Work' 46 | Any work being distributed under this License. 47 | 48 | `Derived Work' 49 | Any work that under any applicable law is derived from the Work. 50 | 51 | `Modification' 52 | Any procedure that produces a Derived Work under any applicable 53 | law -- for example, the production of a file containing an 54 | original file associated with the Work or a significant portion of 55 | such a file, either verbatim or with modifications and/or 56 | translated into another language. 57 | 58 | `Modify' 59 | To apply any procedure that produces a Derived Work under any 60 | applicable law. 61 | 62 | `Distribution' 63 | Making copies of the Work available from one person to another, in 64 | whole or in part. Distribution includes (but is not limited to) 65 | making any electronic components of the Work accessible by 66 | file transfer protocols such as FTP or HTTP or by shared file 67 | systems such as Sun's Network File System (NFS). 68 | 69 | `Compiled Work' 70 | A version of the Work that has been processed into a form where it 71 | is directly usable on a computer system. This processing may 72 | include using installation facilities provided by the Work, 73 | transformations of the Work, copying of components of the Work, or 74 | other activities. Note that modification of any installation 75 | facilities provided by the Work constitutes modification of the Work. 76 | 77 | `Current Maintainer' 78 | A person or persons nominated as such within the Work. If there is 79 | no such explicit nomination then it is the `Copyright Holder' under 80 | any applicable law. 81 | 82 | `Base Interpreter' 83 | A program or process that is normally needed for running or 84 | interpreting a part or the whole of the Work. 85 | 86 | A Base Interpreter may depend on external components but these 87 | are not considered part of the Base Interpreter provided that each 88 | external component clearly identifies itself whenever it is used 89 | interactively. Unless explicitly specified when applying the 90 | license to the Work, the only applicable Base Interpreter is a 91 | `LaTeX-Format' or in the case of files belonging to the 92 | `LaTeX-format' a program implementing the `TeX language'. 93 | 94 | 95 | 96 | CONDITIONS ON DISTRIBUTION AND MODIFICATION 97 | =========================================== 98 | 99 | 1. Activities other than distribution and/or modification of the Work 100 | are not covered by this license; they are outside its scope. In 101 | particular, the act of running the Work is not restricted and no 102 | requirements are made concerning any offers of support for the Work. 103 | 104 | 2. You may distribute a complete, unmodified copy of the Work as you 105 | received it. Distribution of only part of the Work is considered 106 | modification of the Work, and no right to distribute such a Derived 107 | Work may be assumed under the terms of this clause. 108 | 109 | 3. You may distribute a Compiled Work that has been generated from a 110 | complete, unmodified copy of the Work as distributed under Clause 2 111 | above, as long as that Compiled Work is distributed in such a way that 112 | the recipients may install the Compiled Work on their system exactly 113 | as it would have been installed if they generated a Compiled Work 114 | directly from the Work. 115 | 116 | 4. If you are the Current Maintainer of the Work, you may, without 117 | restriction, modify the Work, thus creating a Derived Work. You may 118 | also distribute the Derived Work without restriction, including 119 | Compiled Works generated from the Derived Work. Derived Works 120 | distributed in this manner by the Current Maintainer are considered to 121 | be updated versions of the Work. 122 | 123 | 5. If you are not the Current Maintainer of the Work, you may modify 124 | your copy of the Work, thus creating a Derived Work based on the Work, 125 | and compile this Derived Work, thus creating a Compiled Work based on 126 | the Derived Work. 127 | 128 | 6. If you are not the Current Maintainer of the Work, you may 129 | distribute a Derived Work provided the following conditions are met 130 | for every component of the Work unless that component clearly states 131 | in the copyright notice that it is exempt from that condition. Only 132 | the Current Maintainer is allowed to add such statements of exemption 133 | to a component of the Work. 134 | 135 | a. If a component of this Derived Work can be a direct replacement 136 | for a component of the Work when that component is used with the 137 | Base Interpreter, then, wherever this component of the Work 138 | identifies itself to the user when used interactively with that 139 | Base Interpreter, the replacement component of this Derived Work 140 | clearly and unambiguously identifies itself as a modified version 141 | of this component to the user when used interactively with that 142 | Base Interpreter. 143 | 144 | b. Every component of the Derived Work contains prominent notices 145 | detailing the nature of the changes to that component, or a 146 | prominent reference to another file that is distributed as part 147 | of the Derived Work and that contains a complete and accurate log 148 | of the changes. 149 | 150 | c. No information in the Derived Work implies that any persons, 151 | including (but not limited to) the authors of the original version 152 | of the Work, provide any support, including (but not limited to) 153 | the reporting and handling of errors, to recipients of the 154 | Derived Work unless those persons have stated explicitly that 155 | they do provide such support for the Derived Work. 156 | 157 | d. You distribute at least one of the following with the Derived Work: 158 | 159 | 1. A complete, unmodified copy of the Work; 160 | if your distribution of a modified component is made by 161 | offering access to copy the modified component from a 162 | designated place, then offering equivalent access to copy 163 | the Work from the same or some similar place meets this 164 | condition, even though third parties are not compelled to 165 | copy the Work along with the modified component; 166 | 167 | 2. Information that is sufficient to obtain a complete, 168 | unmodified copy of the Work. 169 | 170 | 7. If you are not the Current Maintainer of the Work, you may 171 | distribute a Compiled Work generated from a Derived Work, as long as 172 | the Derived Work is distributed to all recipients of the Compiled 173 | Work, and as long as the conditions of Clause 6, above, are met with 174 | regard to the Derived Work. 175 | 176 | 8. The conditions above are not intended to prohibit, and hence do not 177 | apply to, the modification, by any method, of any component so that it 178 | becomes identical to an updated version of that component of the Work as 179 | it is distributed by the Current Maintainer under Clause 4, above. 180 | 181 | 9. Distribution of the Work or any Derived Work in an alternative 182 | format, where the Work or that Derived Work (in whole or in part) is 183 | then produced by applying some process to that format, does not relax or 184 | nullify any sections of this license as they pertain to the results of 185 | applying that process. 186 | 187 | 10. a. A Derived Work may be distributed under a different license 188 | provided that license itself honors the conditions listed in 189 | Clause 6 above, in regard to the Work, though it does not have 190 | to honor the rest of the conditions in this license. 191 | 192 | b. If a Derived Work is distributed under a different license, that 193 | Derived Work must provide sufficient documentation as part of 194 | itself to allow each recipient of that Derived Work to honor the 195 | restrictions in Clause 6 above, concerning changes from the Work. 196 | 197 | 11. This license places no restrictions on works that are unrelated to 198 | the Work, nor does this license place any restrictions on aggregating 199 | such works with the Work by any means. 200 | 201 | 12. Nothing in this license is intended to, or may be used to, prevent 202 | complete compliance by all parties with all applicable laws. 203 | 204 | 205 | NO WARRANTY 206 | =========== 207 | 208 | There is no warranty for the Work. Except when otherwise stated in 209 | writing, the Copyright Holder provides the Work `as is', without 210 | warranty of any kind, either expressed or implied, including, but not 211 | limited to, the implied warranties of merchantability and fitness for a 212 | particular purpose. The entire risk as to the quality and performance 213 | of the Work is with you. Should the Work prove defective, you assume 214 | the cost of all necessary servicing, repair, or correction. 215 | 216 | In no event unless required by applicable law or agreed to in writing 217 | will The Copyright Holder, or any author named in the components of the 218 | Work, or any other party who may distribute and/or modify the Work as 219 | permitted above, be liable to you for damages, including any general, 220 | special, incidental or consequential damages arising out of any use of 221 | the Work or out of inability to use the Work (including, but not limited 222 | to, loss of data, data being rendered inaccurate, or losses sustained by 223 | anyone as a result of any failure of the Work to operate with any other 224 | programs), even if the Copyright Holder or said author or said other 225 | party has been advised of the possibility of such damages. 226 | 227 | 228 | MAINTENANCE OF THE WORK 229 | ======================= 230 | 231 | The Work has the status `author-maintained' if the Copyright Holder 232 | explicitly and prominently states near the primary copyright notice in 233 | the Work that the Work can only be maintained by the Copyright Holder 234 | or simply that it is `author-maintained'. 235 | 236 | The Work has the status `maintained' if there is a Current Maintainer 237 | who has indicated in the Work that they are willing to receive error 238 | reports for the Work (for example, by supplying a valid e-mail 239 | address). It is not required for the Current Maintainer to acknowledge 240 | or act upon these error reports. 241 | 242 | The Work changes from status `maintained' to `unmaintained' if there 243 | is no Current Maintainer, or the person stated to be Current 244 | Maintainer of the work cannot be reached through the indicated means 245 | of communication for a period of six months, and there are no other 246 | significant signs of active maintenance. 247 | 248 | You can become the Current Maintainer of the Work by agreement with 249 | any existing Current Maintainer to take over this role. 250 | 251 | If the Work is unmaintained, you can become the Current Maintainer of 252 | the Work through the following steps: 253 | 254 | 1. Make a reasonable attempt to trace the Current Maintainer (and 255 | the Copyright Holder, if the two differ) through the means of 256 | an Internet or similar search. 257 | 258 | 2. If this search is successful, then enquire whether the Work 259 | is still maintained. 260 | 261 | a. If it is being maintained, then ask the Current Maintainer 262 | to update their communication data within one month. 263 | 264 | b. If the search is unsuccessful or no action to resume active 265 | maintenance is taken by the Current Maintainer, then announce 266 | within the pertinent community your intention to take over 267 | maintenance. (If the Work is a LaTeX work, this could be 268 | done, for example, by posting to comp.text.tex.) 269 | 270 | 3a. If the Current Maintainer is reachable and agrees to pass 271 | maintenance of the Work to you, then this takes effect 272 | immediately upon announcement. 273 | 274 | b. If the Current Maintainer is not reachable and the Copyright 275 | Holder agrees that maintenance of the Work be passed to you, 276 | then this takes effect immediately upon announcement. 277 | 278 | 4. If you make an `intention announcement' as described in 2b. above 279 | and after three months your intention is challenged neither by 280 | the Current Maintainer nor by the Copyright Holder nor by other 281 | people, then you may arrange for the Work to be changed so as 282 | to name you as the (new) Current Maintainer. 283 | 284 | 5. If the previously unreachable Current Maintainer becomes 285 | reachable once more within three months of a change completed 286 | under the terms of 3b) or 4), then that Current Maintainer must 287 | become or remain the Current Maintainer upon request provided 288 | they then update their communication data within one month. 289 | 290 | A change in the Current Maintainer does not, of itself, alter the fact 291 | that the Work is distributed under the LPPL license. 292 | 293 | If you become the Current Maintainer of the Work, you should 294 | immediately provide, within the Work, a prominent and unambiguous 295 | statement of your status as Current Maintainer. You should also 296 | announce your new status to the same pertinent community as 297 | in 2b) above. 298 | 299 | 300 | WHETHER AND HOW TO DISTRIBUTE WORKS UNDER THIS LICENSE 301 | ====================================================== 302 | 303 | This section contains important instructions, examples, and 304 | recommendations for authors who are considering distributing their 305 | works under this license. These authors are addressed as `you' in 306 | this section. 307 | 308 | Choosing This License or Another License 309 | ---------------------------------------- 310 | 311 | If for any part of your work you want or need to use *distribution* 312 | conditions that differ significantly from those in this license, then 313 | do not refer to this license anywhere in your work but, instead, 314 | distribute your work under a different license. You may use the text 315 | of this license as a model for your own license, but your license 316 | should not refer to the LPPL or otherwise give the impression that 317 | your work is distributed under the LPPL. 318 | 319 | The document `modguide.tex' in the base LaTeX distribution explains 320 | the motivation behind the conditions of this license. It explains, 321 | for example, why distributing LaTeX under the GNU General Public 322 | License (GPL) was considered inappropriate. Even if your work is 323 | unrelated to LaTeX, the discussion in `modguide.tex' may still be 324 | relevant, and authors intending to distribute their works under any 325 | license are encouraged to read it. 326 | 327 | A Recommendation on Modification Without Distribution 328 | ----------------------------------------------------- 329 | 330 | It is wise never to modify a component of the Work, even for your own 331 | personal use, without also meeting the above conditions for 332 | distributing the modified component. While you might intend that such 333 | modifications will never be distributed, often this will happen by 334 | accident -- you may forget that you have modified that component; or 335 | it may not occur to you when allowing others to access the modified 336 | version that you are thus distributing it and violating the conditions 337 | of this license in ways that could have legal implications and, worse, 338 | cause problems for the community. It is therefore usually in your 339 | best interest to keep your copy of the Work identical with the public 340 | one. Many works provide ways to control the behavior of that work 341 | without altering any of its licensed components. 342 | 343 | How to Use This License 344 | ----------------------- 345 | 346 | To use this license, place in each of the components of your work both 347 | an explicit copyright notice including your name and the year the work 348 | was authored and/or last substantially modified. Include also a 349 | statement that the distribution and/or modification of that 350 | component is constrained by the conditions in this license. 351 | 352 | Here is an example of such a notice and statement: 353 | 354 | %% pig.dtx 355 | %% Copyright 2005 M. Y. Name 356 | % 357 | % This work may be distributed and/or modified under the 358 | % conditions of the LaTeX Project Public License, either version 1.3 359 | % of this license or (at your option) any later version. 360 | % The latest version of this license is in 361 | % http://www.latex-project.org/lppl.txt 362 | % and version 1.3 or later is part of all distributions of LaTeX 363 | % version 2005/12/01 or later. 364 | % 365 | % This work has the LPPL maintenance status `maintained'. 366 | % 367 | % The Current Maintainer of this work is M. Y. Name. 368 | % 369 | % This work consists of the files pig.dtx and pig.ins 370 | % and the derived file pig.sty. 371 | 372 | Given such a notice and statement in a file, the conditions 373 | given in this license document would apply, with the `Work' referring 374 | to the three files `pig.dtx', `pig.ins', and `pig.sty' (the last being 375 | generated from `pig.dtx' using `pig.ins'), the `Base Interpreter' 376 | referring to any `LaTeX-Format', and both `Copyright Holder' and 377 | `Current Maintainer' referring to the person `M. Y. Name'. 378 | 379 | If you do not want the Maintenance section of LPPL to apply to your 380 | Work, change `maintained' above into `author-maintained'. 381 | However, we recommend that you use `maintained', as the Maintenance 382 | section was added in order to ensure that your Work remains useful to 383 | the community even when you can no longer maintain and support it 384 | yourself. 385 | 386 | Derived Works That Are Not Replacements 387 | --------------------------------------- 388 | 389 | Several clauses of the LPPL specify means to provide reliability and 390 | stability for the user community. They therefore concern themselves 391 | with the case that a Derived Work is intended to be used as a 392 | (compatible or incompatible) replacement of the original Work. If 393 | this is not the case (e.g., if a few lines of code are reused for a 394 | completely different task), then clauses 6b and 6d shall not apply. 395 | 396 | 397 | Important Recommendations 398 | ------------------------- 399 | 400 | Defining What Constitutes the Work 401 | 402 | The LPPL requires that distributions of the Work contain all the 403 | files of the Work. It is therefore important that you provide a 404 | way for the licensee to determine which files constitute the Work. 405 | This could, for example, be achieved by explicitly listing all the 406 | files of the Work near the copyright notice of each file or by 407 | using a line such as: 408 | 409 | % This work consists of all files listed in manifest.txt. 410 | 411 | in that place. In the absence of an unequivocal list it might be 412 | impossible for the licensee to determine what is considered by you 413 | to comprise the Work and, in such a case, the licensee would be 414 | entitled to make reasonable conjectures as to which files comprise 415 | the Work. 416 | 417 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | wrapstuff 2 | ========= 3 | 4 | The `wrapstuff` package provides another implementation of text wrapping. 5 | Its implementation benefits from the paragraph hooks available since 6 | LaTeX 2021-06-01. 7 | 8 | Basic Usage 9 | ----------- 10 | The package only provides a user environment `wrapstuff`. 11 | ```LaTeX 12 | \begin{wrapstuff}[] 13 | 14 | \end{wrapstuff} 15 |
16 | ``` 17 | You can read the package manual (in both English and Chinese) for some explanations. 18 | 19 | Contributing 20 | ------------ 21 | The package is still highly experimental and not fully tested. 22 | [Issues](https://github.com/qinglee/wrapstuff/issues) and 23 | [pull requests](https://github.com/qinglee/wrapstuff/pulls) 24 | are always welcome. 25 | -------------------------------------------------------------------------------- /build.lua: -------------------------------------------------------------------------------- 1 | 2 | module = "wrapstuff" 3 | 4 | packtdszip = false 5 | tdsroot = "latex" 6 | 7 | supportdir = "./support" 8 | textfiledir = "./build/unpacked" 9 | unpackexe = "luatex" 10 | 11 | sourcefiles = {"wrapstuff.dtx"} 12 | unpackfiles = {"wrapstuff.dtx"} 13 | installfiles = {"*.sty"} 14 | unpacksuppfiles = {"wrapstuff.id"} 15 | 16 | dofile("./support/build-config.lua") 17 | -------------------------------------------------------------------------------- /support/build-config.lua: -------------------------------------------------------------------------------- 1 | -- Common settings for ctex-kit development repo, used by l3build script 2 | 3 | supportdir = supportdir or "../support" 4 | unpackexe = unpackexe or "luatex" 5 | gitverfiles = gitverfiles or unpackfiles 6 | unpackexe = unpackexe or "luatex" 7 | typesetexe = typesetexe or "xelatex" 8 | makeindexexe = makeindexexe or "zhmakeindex" 9 | makeindexopts = makeindexopts or "-q" 10 | checkopts = checkopts or "-halt-on-error" 11 | typesetopts = typesetopts or "-halt-on-error" 12 | binaryfiles = binaryfiles or {"*.pdf", "*.zip", "*.luc", "*.tec", "*.tfm", "*.tar.bz2"} 13 | 14 | kpse.set_program_name("kpsewhich") 15 | local lookup = kpse.lookup 16 | 17 | local md5sum = require("md5").sum 18 | function file_md5 (file) 19 | local f = io.open(file, "rb") 20 | if f then 21 | local data = f:read("*all") 22 | f:close() 23 | return data and md5sum(data) 24 | end 25 | end 26 | 27 | typesetruns = typesetruns or 5 28 | typeset = function (file,dir,exe) 29 | local dir = dir or "." 30 | local name = jobname(file) 31 | local path_name = dir .. "/" .. name 32 | local aux, bbl = path_name .. ".aux", path_name .. ".bbl" 33 | local glo, idx, hd = path_name .. ".glo", path_name .. ".idx", path_name .. ".hd" 34 | local aux_md5, bbl_md5, glo_md5, idx_md5, hd_md5 35 | local prev_aux_md5, prev_bbl_md5, prev_glo_md5, prev_idx_md5, prev_hd_md5 36 | local errorlevel 37 | local cnt = 0 38 | local typeset_flag = true 39 | while typeset_flag and cnt < typesetruns do 40 | cnt = cnt + 1 41 | errorlevel = tex(file,dir,exe) 42 | if errorlevel ~= 0 then return errorlevel end 43 | errorlevel = biber(name,dir) 44 | + bibtex(name,dir) 45 | + makeindex(name,dir,".glo",".gls",".glg",glossarystyle) 46 | + makeindex(name,dir,".idx",".ind",".ilg",indexstyle) 47 | if errorlevel ~= 0 then return errorlevel end 48 | prev_aux_md5, prev_bbl_md5 = aux_md5, bbl_md5 49 | prev_glo_md5, prev_idx_md5, prev_hd_md5 = glo_md5, idx_md5, hd_md5 50 | aux_md5, bbl_md5 = file_md5(aux), file_md5(bbl) 51 | glo_md5, idx_md5, hd_md5 = file_md5(glo), file_md5(idx), file_md5(hd) 52 | typeset_flag = aux_md5 ~= prev_aux_md5 or bbl_md5 ~= prev_bbl_md5 53 | or glo_md5 ~= prev_glo_md5 54 | or idx_md5 ~= prev_idx_md5 55 | or hd_md5 ~= prev_hd_md5 56 | end 57 | return 0 58 | end 59 | 60 | dtxchecksum = require(lookup("dtxchecksum.lua", {path=supportdir})).checksum 61 | function checksum() 62 | if not is_unpacked then unpack() end 63 | unpack = null_function 64 | for _,i in ipairs(typesetsuppfiles) do 65 | cp(i, supportdir, localdir) 66 | end 67 | for _,glob in ipairs(typesetfiles) do 68 | for _,f in ipairs(filelist(".", glob)) do 69 | if f:sub(-4) == ".dtx" then 70 | dtxchecksum(f, localdir) 71 | end 72 | end 73 | end 74 | end 75 | 76 | target_list = target_list or { } 77 | 78 | target_list.checksum = { desc = "Adjust \\CheckSum{...}", func = checksum } 79 | 80 | shellescape = os.type == "windows" 81 | and function (s) return s end 82 | or function (s) 83 | s = s:gsub([[\]], [[\\]]) 84 | s = s:gsub([[%$]], [[\$]]) 85 | return s 86 | end 87 | 88 | git_id_info = { } 89 | 90 | function extract_git_version() 91 | mkdir(supportdir) 92 | for _,i in ipairs(gitverfiles) do 93 | for _,j in ipairs({currentdir,supportdir}) do 94 | for _,k in ipairs(filelist(j, i)) do 95 | local idfile = normalize_path(supportdir .. "/" .. jobname(k) .. ".id") 96 | local file = normalize_path(j .. "/" .. k) 97 | local cmdline = shellescape([[git log -1 --pretty=format:"$Id: ]] 98 | .. k .. [[ %h %ai %an <%ae> $" ]] .. file) 99 | local f = assert(io.popen(cmdline, "r")) 100 | local id = f:read("*all") 101 | f:close() 102 | git_id_info[k] = id 103 | f = assert(io.open(idfile, "wb")) 104 | f:write(id, "\n") 105 | f:close() 106 | end 107 | end 108 | end 109 | end 110 | 111 | function expand_git_version() 112 | local sourcedir = tdsdir .. "/source/" .. moduledir 113 | local texdir = tdsdir .. "/tex/" .. moduledir 114 | for _,i in ipairs(gitverfiles) do 115 | for _,j in ipairs({sourcedir,texdir}) do 116 | for _,k in ipairs(filelist(j, i)) do 117 | replace_git_id(j, k) 118 | end 119 | end 120 | end 121 | end 122 | 123 | function replace_git_id (path, file) 124 | local f = assert(io.open(path .. "/" .. file, "rb")) 125 | local s = f:read("*all") 126 | f:close() 127 | local id = assert(git_id_info[file]) 128 | local s, n = s:gsub([[(\GetIdInfo)%b$$]], "%1" .. id) 129 | if n > 0 then 130 | f = assert(io.open(path .. "/" .. file, "wb")) 131 | f:write(s) 132 | f:close() 133 | cp(file, path, ctandir .. "/" .. ctanpkg) 134 | end 135 | end 136 | 137 | function update_tag(file, content, tagname, tagdate) 138 | local content, date = content, tagdate:gsub("%-", "/") 139 | if file:match("%.dtx$") then 140 | content = content:gsub("({\\ExplFileDate})%b{}", "%1{" .. tagname .."}") 141 | content = content:gsub("(%[)%d%d%d%d/%d%d/%d%d v%S+", "%1" .. date .. " v" .. tagname) 142 | end 143 | return content 144 | end 145 | 146 | null_function = function() return 0 end 147 | 148 | local insert = table.insert 149 | 150 | function saveall(names) 151 | local names, opt_engine = names, options.engine 152 | local t, engines = { }, { } 153 | if opt_engine then 154 | for _,i in ipairs(opt_engine) do engines[i] = true end 155 | end 156 | local lvts = names and { } 157 | if names then 158 | local uniq = { } 159 | local glob = "*%s*.tlg" 160 | for _,i in ipairs(names) do 161 | for _,j in ipairs(filelist(testfiledir, glob:format(i))) do 162 | if not uniq[j] then 163 | uniq[j] = true 164 | insert(lvts, j) 165 | end 166 | end 167 | end 168 | end 169 | for _,file in ipairs(lvts or filelist(testfiledir, "*.tlg")) do 170 | local base = jobname(file) 171 | local lvt, tex = base:match([[^(.+)%.(%w+)$]]) 172 | local lvt = lvt or base 173 | local tex = tex or stdengine 174 | if not t[tex] then t[tex] = { } end 175 | insert(t[tex], lvt) 176 | end 177 | if next(t) then 178 | checkinit() 179 | checkinit = null_function 180 | for _, tex in ipairs(checkengines) do 181 | local lvts = t[tex] 182 | if lvts and (not next(engines) or engines[tex]) then 183 | options.engine = { tex } 184 | save(lvts) 185 | end 186 | end 187 | end 188 | end 189 | 190 | target_list.saveall = { desc = "Saves all test validation log", func = saveall } 191 | 192 | doc_prehook = doc_prehook or null_function 193 | doc_posthook = doc_posthook or null_function 194 | unhooked_doc = doc 195 | doc = function (...) 196 | doc_prehook() 197 | checksum() 198 | local retval = unhooked_doc(...) 199 | doc_posthook() 200 | return retval 201 | end 202 | target_list.doc.func = doc 203 | 204 | unpack_prehook = unpack_prehook or null_function 205 | unpack_posthook = unpack_posthook or null_function 206 | unhooked_bundleunpack = bundleunpack 207 | bundleunpack = function (...) 208 | extract_git_version() 209 | unpack_prehook() 210 | local retval = unhooked_bundleunpack(...) 211 | is_unpacked = true 212 | unpack_posthook() 213 | return retval 214 | end 215 | target_list.bundleunpack.func = bundleunpack 216 | 217 | install_files_prehook = install_files_prehook or null_function 218 | install_files_posthook = install_files_posthook or null_function 219 | unhooked_install_files = install_files 220 | install_files = function (...) 221 | install_files_bool = true 222 | install_files_prehook() 223 | local retval = unhooked_install_files(...) 224 | install_files_posthook() 225 | return retval 226 | end 227 | 228 | copyctan_prehook = copyctan_prehook or null_function 229 | copyctan_posthook = copyctan_posthook or null_function 230 | unhooked_copyctan = copyctan 231 | copyctan = function (...) 232 | copyctan_prehook() 233 | local retval = unhooked_copyctan(...) 234 | expand_git_version() 235 | copyctan_posthook() 236 | return retval 237 | end 238 | 239 | -------------------------------------------------------------------------------- /support/dtxchecksum.lua: -------------------------------------------------------------------------------- 1 | -- 2 | -- This is file `dtxchecksum.lua', 3 | -- 4 | -- Copyright (C) 2015 by Qing Lee 5 | -------------------------------------------------------------------- 6 | -- 7 | -- This work may be distributed and/or modified under the 8 | -- conditions of the LaTeX Project Public License, either 9 | -- version 1.3c of this license or (at your option) any later 10 | -- version. This version of this license is in 11 | -- http://www.latex-project.org/lppl/lppl-1-3c.txt 12 | -- and the latest version of this license is in 13 | -- http://www.latex-project.org/lppl.txt 14 | -- and version 1.3 or later is part of all distributions of 15 | -- LaTeX version 2005/12/01 or later. 16 | -- 17 | -- This work has the LPPL maintenance status `maintained'. 18 | -- 19 | -- The Current Maintainer of this work is Qing Lee. 20 | -- 21 | -- This work consists of this file. 22 | -- 23 | -------------------------------------------------------------------- 24 | -- 25 | 26 | dtxchecksum = dtxchecksum or {} 27 | local dtxchecksum = dtxchecksum 28 | dtxchecksum.module = { 29 | name = "dtxchecksum", 30 | version = "0", 31 | date = "2015/05/18", 32 | description = "Correction of \\CheckSum{...} entry in dtx file", 33 | author = "Qing Lee", 34 | copyright = "Qing Lee", 35 | license = "LPPL v1.3c" 36 | } 37 | 38 | local os, print, error = os, print, error 39 | 40 | local checksumexe = dtxchecksum.exe or "xelatex" 41 | local checksumopt = dtxchecksum.opt or ( checksumexe == "xelatex" and "-no-pdf" or "-draftmode") 42 | 43 | local ltxdocfile = dtxchecksum.cfgfile or "l3doc.cfg" 44 | local ltxdoccfg = dtxchecksum.doccfg or ( checksumexe == "xelatex" and [[\AtBeginDocument{\XeTeXinterchartokenstate=\z@}]] 45 | or "" ) 46 | 47 | local kpathsea = kpse.new(checksumexe) 48 | 49 | local cfg = [[ 50 | \typeout{* version for dtxchecksum *} 51 | \AtEndOfClass{% 52 | \DontCheckModules 53 | \DisableCrossrefs 54 | \def\DisableCrossrefs{\@bsphack\@esphack}% 55 | \let\EnableCrossrefs\DisableCrossrefs 56 | \let\CodelineIndex\relax 57 | \let\PageIndex\relax 58 | \let\CodelineNumbered\relax 59 | \let\PrintChanges\relax 60 | \let\PrintIndex\relax 61 | \let\tableofcontents\relax 62 | \PassOptionsToPackage{bookmarks=false}{hyperref}% 63 | \expandafter\xdef\csname ver@hypdoc.sty\endcsname{}% 64 | \expandafter\xdef\csname ver@bmhydoc.sty\endcsname{}% 65 | \nofiles 66 | \hfuzz\maxdimen 67 | \pretolerance10000 % 68 | \tolerance10000 % 69 | \csname DisableDocumentation\endcsname 70 | \usepackage{syntonly}% 71 | \AtBeginDocument{\syntaxonly} 72 | ]] .. ltxdoccfg .. [[ 73 | } 74 | \endinput 75 | ]] 76 | 77 | local os_null, os_copy, os_rmdir 78 | if os.type == "windows" then 79 | os_null = "nul" 80 | function os_copy (src, dest) 81 | os.execute("copy /y " .. src .. " " .. dest .. " > " .. os_null) 82 | end 83 | function os_rmdir (dir) 84 | os.execute("rmdir /s /q " .. dir) 85 | end 86 | else 87 | os_null = "/dev/null" 88 | function os_copy (src, dest) 89 | os.execute("cp -f " .. src .. " " .. dest) 90 | end 91 | function os_rmdir (dir) 92 | os.execute("rm -rf " .. dir) 93 | end 94 | end 95 | 96 | local function stripext (file) 97 | return file:match ("^(.*)%.") or file 98 | end 99 | 100 | local function typeset (dir, dtx) 101 | local f = assert(io.open(dir .. "/" .. ltxdocfile, "w")) 102 | f:write(cfg) 103 | f:close() 104 | os_copy(dtx, dir) 105 | print("*** Running " .. checksumexe .. " for checksum generation ...") 106 | os.execute(checksumexe .. " -interaction=batchmode -output-directory=" .. dir .. " " 107 | .. checksumopt .. " " .. dir .. "/" .. dtx .. " > " .. os_null) 108 | end 109 | 110 | local function find_checksum (logfile) 111 | print("*** Looking for checksum statement ...") 112 | local f = assert(io.open(logfile, "r"), "Cannot open log file " .. logfile .. "!") 113 | local file = f:read("*all") 114 | f:close() 115 | if file:find("%* Checksum passed %*") then 116 | return true, false 117 | end 118 | local old, new = file:match("Checksum not passed %((%d+)<>(%d+)%)") 119 | if old and new then 120 | return true, true, old, new 121 | end 122 | local new = file:match("The checksum should be (%d+)!") 123 | if new then 124 | return true, true, 0, new 125 | end 126 | end 127 | 128 | local function fix_checksum (dir, dtx, old, new) 129 | print("==> Checksum not passed (" .. old .. "<>" .. new .. ").") 130 | print("*** Fixing Checksum ...") 131 | local f = assert(io.open(dir .. "/" .. dtx , "rb")) 132 | local file = f:read("*all") 133 | f:close() 134 | local s, fixed = file:gsub("(\\CheckSum%s*{%s*)" .. old .. "(%s*})", "%1" .. new .. "%2") 135 | local f = assert(io.open(dtx , "wb")) 136 | f:write(s) 137 | f:close() 138 | if fixed == 0 then 139 | error("\"\\CheckSum{...}\" not found!") 140 | end 141 | if fixed > 1 then 142 | error("More than one \"\\CheckSum\" command found!") 143 | end 144 | end 145 | 146 | function dtxchecksum.checksum (dtx, texinputs) 147 | local tempdir = assert(os.tmpdir(), "Cannot create the temporary directory!") 148 | local kpse_texinputs, os_texinputs 149 | if texinputs then 150 | if os.selfdir:find([[miktex\bin$]]) then 151 | checksumopt = "-include-directory=" .. texinputs .. " " .. checksumopt 152 | else 153 | kpse_texinputs = kpathsea:var_value("TEXINPUTS") 154 | os_texinputs = kpse_texinputs and texinputs .. "//;" .. kpse_texinputs 155 | or texinputs .. "//" 156 | os.setenv("TEXINPUTS", os_texinputs) 157 | end 158 | end 159 | typeset(tempdir, dtx) 160 | local logfile = tempdir .. "/" .. stripext(dtx) .. ".log" 161 | local found, changed, old, new = find_checksum(logfile) 162 | assert(found, "Checksum statement not found in log file!") 163 | if changed then 164 | fix_checksum(tempdir, dtx, old, new) 165 | else 166 | print("*** Checksum passed.") 167 | end 168 | os_rmdir(tempdir) 169 | if os_texinputs then 170 | os.setenv("TEXINPUTS", kpse_texinputs) 171 | end 172 | end 173 | 174 | return dtxchecksum 175 | -------------------------------------------------------------------------------- /wrapstuff.dtx: -------------------------------------------------------------------------------- 1 | % \iffalse meta-comment 2 | % !TeX program = XeLaTeX 3 | % !TeX encoding = UTF-8 4 | %<*internal> 5 | \iffalse 6 | % 7 | %<*readme> 8 | wrapstuff 9 | ========= 10 | 11 | The `wrapstuff` package provides another implementation of text wrapping. 12 | Its implementation benefits from the paragraph hooks available since 13 | LaTeX 2021-06-01. 14 | 15 | Basic Usage 16 | ----------- 17 | The package only provides a user environment `wrapstuff`. 18 | 19 | \begin{wrapstuff}[] 20 | 21 | \end{wrapstuff} 22 |
23 | 24 | You can read the package manual (in both English and Chinese) for some explanations. 25 | 26 | Contributing 27 | ------------ 28 | The package is still highly experimental and not fully tested. 29 | [Issues](https://github.com/qinglee/wrapstuff/issues) and 30 | [pull requests](https://github.com/qinglee/wrapstuff/pulls) 31 | are always welcome. 32 | 33 | Copyright and Licence 34 | --------------------- 35 | 36 | Copyright (C) 2022 by Qing Lee 37 | ----------------------------------------------------------------- 38 | 39 | This work may be distributed and/or modified under the 40 | conditions of the LaTeX Project Public License, either 41 | version 1.3c of this license or (at your option) any later 42 | version. This version of this license is in 43 | http://www.latex-project.org/lppl/lppl-1-3c.txt 44 | and the latest version of this license is in 45 | http://www.latex-project.org/lppl.txt 46 | and version 1.3 or later is part of all distributions of 47 | LaTeX version 2005/12/01 or later. 48 | 49 | This work has the LPPL maintenance status "maintained". 50 | 51 | The Current Maintainer of this work is Qing Lee. 52 | 53 | This package consists of the file wrapstuff.dtx, 54 | and the derived files wrapstuff.pdf, 55 | wrapstuff.sty, 56 | wrapstuff.ins and 57 | README.md (this file). 58 | % 59 | %<*internal> 60 | \fi 61 | \begingroup 62 | \def\temp{LaTeX2e} 63 | \expandafter\endgroup\ifx\temp\fmtname\else 64 | \csname fi\endcsname 65 | % 66 | %<*install> 67 | 68 | \input ctxdocstrip % 69 | 70 | \preamble 71 | 72 | Copyright (C) 2022 by Qing Lee 73 | ----------------------------------------------------------------- 74 | 75 | This work may be distributed and/or modified under the 76 | conditions of the LaTeX Project Public License, either 77 | version 1.3c of this license or (at your option) any later 78 | version. This version of this license is in 79 | http://www.latex-project.org/lppl/lppl-1-3c.txt 80 | and the latest version of this license is in 81 | http://www.latex-project.org/lppl.txt 82 | and version 1.3 or later is part of all distributions of 83 | LaTeX version 2005/12/01 or later. 84 | 85 | This work has the LPPL maintenance status "maintained". 86 | 87 | The Current Maintainer of this work is Qing Lee. 88 | 89 | ----------------------------------------------------------------- 90 | 91 | \endpreamble 92 | 93 | \postamble 94 | 95 | This work consists of the file wrapstuff.dtx, 96 | and the derived files wrapstuff.pdf, 97 | wrapstuff.sty, 98 | wrapstuff.ins and 99 | README.md. 100 | \endpostamble 101 | 102 | \generate 103 | { 104 | % 105 | %<*internal> 106 | \usedir{source/latex/wrapstuff} 107 | \file{wrapstuff.ins} {\from{\jobname.dtx}{install}} 108 | % 109 | %<*install> 110 | \usedir{tex/latex/wrapstuff} 111 | \file{wrapstuff.sty} {\from{\jobname.dtx}{package}} 112 | \nopreamble\nopostamble 113 | \usedir{doc/latex/wrapstuff} 114 | \file{README.md} {\from{\jobname.dtx}{readme}} 115 | } 116 | 117 | \endbatchfile 118 | % 119 | %<*internal> 120 | \fi 121 | % 122 | %\NeedsTeXFormat{LaTeX2e}[2021-06-01] 123 | %\@ifundefined{ExplLoaderFileDate}{\RequirePackage{expl3}}{} 124 | %<+package>\GetIdInfo$Id$ 125 | % {Wrapping text around stuff} 126 | %\ProvidesExplPackage{\ExplFileName} 127 | % {\ExplFileDate}{0.3}{\ExplFileDescription} 128 | %<*driver> 129 | \documentclass{ctxdoc} 130 | \usepackage{wrapstuff} 131 | \usepackage{graphicx} 132 | \usepackage{zhlipsum} 133 | \usepackage{bookmark} 134 | \ExplSyntaxOn 135 | \makeatletter 136 | \DeclareDocumentCommand \gitsha { m } 137 | { 138 | \href { https \c_colon_str //github.com/qinglee/wrapstuff/commit/#1 } 139 | { rev. ~ \texttt{#1} } 140 | } 141 | \DeclareDocumentCommand \QIANZIWEN { } 142 | { 143 | 天地玄黄宇宙洪荒日月盈昃辰宿列张 144 | 寒来暑往秋收冬藏闰馀成岁律召调阳 \par 145 | 云腾致雨露结为霜金生丽水玉出昆冈 \par 146 | } 147 | \DeclareDocumentCommand \ADDSPECEIALKEY { m } 148 | { 149 | \cs_gset_eq:NN \@@_codedoc_names_typeset_save: 150 | \__codedoc_names_typeset: 151 | \cs_gset_protected:Npn \__codedoc_names_typeset: 152 | { 153 | \cs_gset_eq:NN \__codedoc_names_typeset: 154 | \@@_codedoc_names_typeset_save: 155 | \__codedoc_names_typeset: 156 | #1 \\ 157 | } 158 | } 159 | \DeclareDocumentCommand \STOPFUNCTIONLABEL { } 160 | { \cs_set_eq:NN \__codedoc_function_label:nN \use_none:nn } 161 | \DeclareDocumentCommand \IMAGE { m m } 162 | { \includegraphics [ width = \dim_eval:n {#1} ] { example-image-#2.pdf } } 163 | \tl_put_left:Nn \Example 164 | { \trivlist \item \relax } 165 | \tl_put_right:Nn \endExample 166 | { \endtrivlist } 167 | \SideBySideExampleSet { numbers = none } 168 | \ctex_patch_cmd:Nnn \@maketitle 169 | { \@title } 170 | { \patched@title } 171 | \cs_new_protected:Npn \patched@title 172 | { \exp_args:No \@@_doc_title:n { \g_@@_doc_tl } } 173 | \cs_new_protected:Npn \@@_doc_title:n #1 174 | { 175 | \prop_get:NnNTF \c_@@_doc_prop {#1} \l_tmpa_tl 176 | { \exp_after:wN \@@_doc_title:nnnn \l_tmpa_tl {#1} } 177 | { \bfseries \@title } 178 | } 179 | \cs_new_protected:Npn \@@_doc_title:nnnn #1#2#3#4 180 | { 181 | \bfseries \@title 182 | \sectionmark {#1} 183 | \skip_horizontal:N \tex_rightskip:D 184 | \hbox_overlap_left:n 185 | { 186 | \bookmark [ level = section , dest = doc@#4 ] {#1} 187 | \hyper@link { link } { doc@#2 } 188 | { \mdseries \small \sffamily \ding {43} \ #3 } 189 | } 190 | \hook_gput_next_code:nn 191 | { shipout / background } 192 | { \pdf_destination:nn { doc@#4 } { xyz } } 193 | \skip_zero:N \tex_rightskip:D 194 | } 195 | \prop_const_from_keyval:Nn \c_@@_doc_prop 196 | { 197 | en = { Basic~Usage } { zh } { 中文版本 } , 198 | zh = { 基本用法 } { en } { English~Version } 199 | } 200 | 201 | \NewDocumentCommand \docversion { m } 202 | { 203 | \tl_gset:Nx \g_@@_doc_tl {#1} 204 | \tl_gtrim_spaces:N \g_@@_doc_tl 205 | } 206 | \tl_new:N \g_@@_doc_tl 207 | \makeatother 208 | \ExplSyntaxOff 209 | \DeclareDocumentCommand \EXAMPLE { } 210 | { 211 | What power art thou, who, from below, 212 | Hast made me rise, unwillingly and slow, 213 | From beds of everlasting snow. 214 | } 215 | \ctexset { secnumdepth = part } 216 | \begin{document} 217 | \DocInput{\jobname.dtx} 218 | \IndexLayout 219 | \PrintChanges 220 | \PrintIndex 221 | \end{document} 222 | % 223 | % \fi 224 | % 225 | % \CheckSum{3127} 226 | % 227 | % \changes{v0.1}{2022/07/05}{初始版本。} 228 | % \changes{v0.1}{2022/07/20}{首次提交到 CTAN 发布。} 229 | % \changes{v0.2}{2022/07/21}{改进放置方式。} 230 | % \changes{v0.4}{2022/12/06}{补充 Jasper Habicht 翻译的英文用户使用说明。} 231 | % 232 | % \GetFileId{wrapstuff.sty} 233 | % 234 | % \title{The \pkg{wrapstuff} Package} 235 | % \author{Qing Lee\thanks{Translation by Jasper Habicht <\email{mail@jasperhabicht.de}>}} 236 | % \date{\filedate\qquad\fileversion\thanks{\gitsha{\ExplFileVersion}.}} 237 | % \docversion{en} 238 | % \maketitle 239 | % 240 | % \begin{documentation} 241 | % 242 | % \ctexset { figurename = Figure } 243 | % \STOPFUNCTIONLABEL 244 | % 245 | % The \pkg{wrapstuff} package provides an alternative way for arranging the layout of images and text. 246 | % The \pkg{wrapstuff} package tries to combine and extend the functionality of packages such as \pkg{picinpar}, \pkg{floatflt}, \pkg{wrapfig}, 247 | % \pkg{cutwin} or \pkg{wrapfig2}. 248 | % This package is compatible with the \pkg{caption} package, the \pkg{float} package and the \pkg{floatrow} package and aims at being compatible with (display) math environments as well as the various \LaTeX\ environments for typesetting tables, which it can wrap properly. 249 | % 250 | % The implementation of the \pkg{wrapstuff} package relies on the paragraph hook management provided by \LaTeX\ 2021-06-01 or later. It requires \LaTeXiii\ 2022-04-10 or later. 251 | % 252 | % \begin{function}{wrapstuff} 253 | % \begin{syntax} 254 | % \tn{begin}\{wrapstuff\}\oarg{options} 255 | % 256 | % \tn{end}\{wrapstuff\} 257 | % 258 | % \end{syntax} 259 | % The \pkg{wrapstuff} package only provides the \env{wrapstuff} environment, which will let the following paragraph wrap around its contents. For example: 260 | % \begin{Example}[frame=single,numbers=none,gobble=5] 261 | % \begin{wrapstuff}[c,top=1] 262 | % \includegraphics[width=12em]{example-image.pdf} 263 | % \end{wrapstuff} 264 | % \EXAMPLE \EXAMPLE \EXAMPLE \EXAMPLE \EXAMPLE \par 265 | % \end{Example} 266 | % \end{function} 267 | % 268 | % \begin{function}{\wrapstuffset} 269 | % \begin{syntax} 270 | % \tn{wrapstuffset} \Arg{option list} 271 | % \end{syntax} 272 | % Options to the \pkg{wrapstuff} package can be set when loading the package with the \tn{usepackage} macro as well as later using \tn{wrapstuffset}. 273 | % The following options are available: 274 | % \end{function} 275 | % 276 | % \ADDSPECEIALKEY{\textrm{\meta{n}}} 277 | % \begin{function}{top} 278 | % \begin{syntax} 279 | % top = 280 | % \end{syntax} 281 | % This option sets the line number where the wrapping should start. The option can take any non-negative integer \meta{n}. 282 | % The initial value is \num{0}. 283 | % \end{function} 284 | % 285 | % \begin{function}{width} 286 | % \begin{syntax} 287 | % width = 288 | % \end{syntax} 289 | % This option sets the width of the contents. The initial value is \qty{0}{pt}, denoting the natural width of the contents of the \env{wrapstuff} environment. 290 | % Using the initial value of \qty{0}{pt}, the contents of the \env{wrapstuff} environment can only take one logical line and may not contain |\\| for inserting line breaks or \tn{par} for separating paragraphs. 291 | % If you want to break lines or put several paragraphs into the \env{wrapstuff} environment, the option \opt{width} must be set to an appropriate dimension. 292 | % \end{function} 293 | % 294 | % \begin{function}{height} 295 | % \begin{syntax} 296 | % height = 297 | % \end{syntax} 298 | % This option sets the height of the contents. The initial value is \qty{0}{pt}, denoting the natural height of the contents of the \env{wrapstuff} environment. 299 | % \end{function} 300 | % 301 | % \begin{function}{lines} 302 | % \begin{syntax} 303 | % lines = 304 | % \end{syntax} 305 | % This option sets the number of lines of the surrounding text the contents should cover. It takes any integer. 306 | % The initial value is empty, which means that the number of lines is calculated from the contents of the \env{wrapstuff} environment. 307 | % \end{function} 308 | % 309 | % \begin{function}{linewidth} 310 | % \begin{syntax} 311 | % linewidth = 312 | % \end{syntax} 313 | % This option sets the line width of the surrounding text. The initial value is |\linewidth|. This option needs not to be changed in general. 314 | % \end{function} 315 | % 316 | % \begin{function}{l,r,c,i,o,ratio} 317 | % \begin{syntax} 318 | % l/r/c/i/o 319 | % ratio = 320 | % \end{syntax} 321 | % These options are used to set the arrangement of the contents of the \env{wrapstuff} environment relative to the surrounding text. 322 | % The options \opt{l/r/c/i/o} set the alignment of the contents of the \env{wrapstuff} environment such that it sits on the left side, the right side, in the center, on the inner side or on the outer side of the surrounding text respectively. 323 | % The option \opt{ratio} sets the ratio of the width of the part of the surrounding text that wraps around the left side. It can be set to any sensible real number within the range $[0,1]$. 324 | % The options \opt{i/o} can be used together with the option \opt{ratio}. 325 | % The initial value is |r|, which means that the contents of the \env{wrapstuff} environment sit on the right side and the surrounding text wraps around the left side. 326 | % \end{function} 327 | % 328 | % \begin{function}{column} 329 | % \begin{syntax} 330 | % column = <(true)|false|par> 331 | % \end{syntax} 332 | % This option controls whether the contents of the \env{wrapstuff} environment should be wrapped by text that is split over two columns. Setting this option to |true| only works if the option \opt{c} is set or the option \opt{ratio} is set to a value other than $0$ or $1$. 333 | % \opt{false} means that the characters of the surrounding text are typeset from the left to the right for each line. 334 | % \opt{par} sets the unit for typesetting columns to paragraphs. Compare the below example: 335 | % \end{function} 336 | % \begin{Example}[frame=single,numbers=none,gobble=5] 337 | % \begin{wrapstuff}[c,1] 338 | % \IMAGE{6em}{a} 339 | % \end{wrapstuff} 340 | % \EXAMPLE \EXAMPLE \par \EXAMPLE \EXAMPLE \par 341 | % \medskip 342 | % \begin{wrapstuff}[c,1,column=par] 343 | % \IMAGE{6em}{b} 344 | % \end{wrapstuff} 345 | % \EXAMPLE \EXAMPLE \par \EXAMPLE \EXAMPLE \par 346 | % \medskip 347 | % \begin{wrapstuff}[c,0,column=false] 348 | % \IMAGE{6em}{c} 349 | % \end{wrapstuff} 350 | % \EXAMPLE \EXAMPLE \par \EXAMPLE \EXAMPLE \par 351 | % \end{Example} 352 | % 353 | % \begin{function}{leftsep,rightsep,hsep} 354 | % \begin{syntax} 355 | % leftsep = 356 | % rightsep = 357 | % hsep = 358 | % \end{syntax} 359 | % These options set the width of the margin to the right and left of the contents of the \env{wrapstuff} environment to separate it from the surrounding text. The option \opt{hsep} sets the same value for \opt{leftsep} and \opt{rightsep}. The initial value is \qty{1}{em}. 360 | % \end{function} 361 | % 362 | % \begin{function}{abovesep,belowsep,vsep} 363 | % \begin{syntax} 364 | % abovesep = 365 | % belowsep = 366 | % vsep = 367 | % \end{syntax} 368 | % These options set the width of the margin above and below the contents of the \env{wrapstuff} environment to separate it from the surrounding text. The option \opt{vsep} sets the same value for \opt{abovesep} and \opt{belowsep}. The initial value is \qty{0}{pt}. 369 | % \end{function} 370 | % 371 | % \begin{function}{hoffset} 372 | % \begin{syntax} 373 | % hoffset = 374 | % \end{syntax} 375 | % This option sets the length of the horizontal offset the contents of the \env{wrapstuff} environment should extend over the text margin. 376 | % If the option \opt{c} is set or the option \opt{ratio} is set to a number other than $0$ or $1$, this option has no effect. 377 | % A specific value for \tn{width} can be used to set the total width of the contents of the \env{wrapstuff} environment and the relevant offset. 378 | % Setting \opt{hoffset} to the value of \tn{width} will completely shift the contents of the \env{wrapstuff} environment outside the text margin. 379 | % The initial value is \qty{0}{pt}. 380 | % \end{function} 381 | % 382 | % \begin{function}{voffset} 383 | % \begin{syntax} 384 | % voffset = 385 | % \end{syntax} 386 | % This option can be used to control the vertical positioning of the contents of the \env{wrapstuff} environment. 387 | % The initial value is \qty{0}{pt}。 388 | % \end{function} 389 | % 390 | % \begin{function}{type} 391 | % \begin{syntax} 392 | % type = 393 | % \end{syntax} 394 | % This option controls the type of the floating environment that should be used for the contents of the \env{wrapstuff} environment. The initial value is empty. 395 | % If the \tn{caption} macro is to be used inside the \env{wrapstuff} environment, the value of the \opt{type} option should be set to \opt{figure} or \opt{table} (or the type of the relevant floating environment that is used) and the \opt{width} option should be set to a specific length. 396 | % \begin{Example}[frame=single,numbers=none,gobble=5] 397 | % \begin{wrapstuff}[type=figure,width=15em] 398 | % \centering 399 | % \IMAGE{10em}{plain} 400 | % \caption{Example} 401 | % \end{wrapstuff} 402 | % \EXAMPLE \EXAMPLE \par \EXAMPLE \EXAMPLE \par 403 | % \end{Example} 404 | % \end{function} 405 | % 406 | % \begin{function}{\wrapstuffclear} 407 | % If the line count of the current paragraph of the surrounding text is not sufficient to fully enclose the contents of the \env{wrapstuff} environment, the wrapping will continue in the following paragraph. 408 | % This may lead to some unwanted outcomes. If \tn{wrapstuffclear} is used before the following paragraph, this standard behavior of continuous wrapping is turned off. 409 | % \end{function} 410 | % 411 | % \end{documentation} 412 | % 413 | % \clearpage 414 | % 415 | % \title{\pkg{wrapstuff} 宏包} 416 | % \author{李清} 417 | % \date{\filedate\qquad\fileversion\thanks{\gitsha{\ExplFileVersion}.}} 418 | % \docversion{zh} 419 | % \maketitle 420 | % 421 | % \begin{documentation} 422 | % 423 | % \pkg{wrapstuff} 宏包提供了图文绕排的另一种实现。 424 | % \pkg{wrapstuff} 尝试整合和扩展 \pkg{picinpar}、\pkg{floatflt}、\pkg{wrapfig}、 425 | % \pkg{cutwin} 和 \pkg{wrapfig2} 等同类宏包的功能。 426 | % 本宏包兼容 \pkg{caption}、\pkg{float} 和 \pkg{floatrow} 等宏包, 427 | % 并试图兼容显示(display)数学公式和各种 \LaTeX\ 列表环境,可以让他们正确绕排。 428 | % 429 | % \pkg{wrapstuff} 的实现依赖 \LaTeX\ 2021-06-01 开始提供的段落钩子, 430 | % 并依赖 \LaTeXiii\ 2022-04-10 之后的版本。 431 | % 432 | % \begin{function}{wrapstuff} 433 | % \begin{syntax} 434 | % \tn{begin}\{wrapstuff\}\oarg{选项} 435 | % <绕排内容> 436 | % \tn{end}\{wrapstuff\} 437 | % <正文> 438 | % \end{syntax} 439 | % \pkg{wrapstuff} 只提供了一个用户环境 \env{wrapstuff}, 440 | % 会在环境之后的段落开始绕排。例如 441 | % \begin{Example}[frame=single,numbers=none,gobble=5] 442 | % \begin{wrapstuff}[c,top=1] 443 | % \includegraphics[width=\dimeval{\linewidth/3}]{example-image.pdf} 444 | % \end{wrapstuff} 445 | % \zhlipsum[1][name=zhufu] 446 | % \end{Example} 447 | % \end{function} 448 | % 449 | % \begin{function}{\wrapstuffset} 450 | % \begin{syntax} 451 | % \tn{wrapstuffset} \Arg{选项列表} 452 | % \end{syntax} 453 | % \pkg{wrapstuff} 的选项可以在调用宏包时设置,也可以通过 \tn{wrapstuffset} 设置。 454 | % 选项将在下面描述。 455 | % \end{function} 456 | % 457 | % \ADDSPECEIALKEY{\textrm{\meta{n}}} 458 | % \begin{function}{top} 459 | % \begin{syntax} 460 | % top = <非负整数> 461 | % \end{syntax} 462 | % 设置在正文段落的第几行之后开始绕排,可以设置为非负整数。 463 | % 非负整数选项 \meta{n} 是设置选项 \opt{top} 为 \meta{n} 的缩写形式。 464 | % 初始值是 \num{0}。 465 | % \end{function} 466 | % 467 | % \begin{function}{width} 468 | % \begin{syntax} 469 | % width = <宽度> 470 | % \end{syntax} 471 | % 设置绕排内容的宽度,初始值为 \qty{0}{pt},代表自然宽度。 472 | % 此时,\env{wrapstuff} 环境内的内容只能有一行,不能使用 |\\| 换行或者 \tn{par} 分段。 473 | % 如果需要在环境内换行或者分段,就需要将 \opt{width} 设置成合适的宽度。 474 | % \end{function} 475 | % 476 | % \begin{function}{height} 477 | % \begin{syntax} 478 | % height = <高度> 479 | % \end{syntax} 480 | % 设置绕排内容的高度,初始值为 \qty{0}{pt},代表自然高度。 481 | % \end{function} 482 | % 483 | % \begin{function}{lines} 484 | % \begin{syntax} 485 | % lines = <正整数> 486 | % \end{syntax} 487 | % 设置绕排内容占据正文的行数,可以设置正整数。 488 | % 初始值为空,根据绕排内容的高度自动计算行数。 489 | % \end{function} 490 | % 491 | % \begin{function}{linewidth} 492 | % \begin{syntax} 493 | % linewidth = <宽度> 494 | % \end{syntax} 495 | % 设置正文段落的行宽,初始设置为 |\linewidth|,一般不需要调整。 496 | % \end{function} 497 | % 498 | % \begin{function}{l,r,c,i,o,ratio} 499 | % \begin{syntax} 500 | % l/r/c/i/o 501 | % ratio = <实数> 502 | % \end{syntax} 503 | % 这些选项用于设置绕排内容位于正文中的位置。 504 | % 选项 \opt{l/r/c/i/o} 分别设置绕排内容位于正文的左侧、右侧、中间、内侧、外侧。 505 | % 选项 \opt{ratio} 设置绕排内容左侧的正文占据行宽的比例,可以设置为 $[0,1]$ 区间中的合理实数。 506 | % 选项 \opt{i/o} 可以与 \opt{ratio} 一起使用,这时设置的是内/外侧正文的行宽比例。 507 | % 初始设置为 |r|,即位于正文的右侧。 508 | % \end{function} 509 | % 510 | % \begin{function}{column} 511 | % \begin{syntax} 512 | % column = <(true)|false|par> 513 | % \end{syntax} 514 | % 控制是否将绕排内容两侧的正文分栏显示,只有设置 |c| 选项或者 515 | % 设置 \opt{ratio} 不等于 $0$ 或者 $1$ 时才有效。 516 | % \opt{false} 表示不分栏,正文文字方向始终保持从左到右的顺序; 517 | % \opt{par} 表示以段落为单位进行分栏,如下示例。 518 | % \begin{SideBySideExample}[xrightmargin=\dimeval{20em+5mm}] 519 | % \begin{wrapstuff}[c,1] 520 | % \IMAGE{2em}{a} 521 | % \end{wrapstuff} 522 | % \QIANZIWEN 523 | % \begin{wrapstuff}[c,1,column=par] 524 | % \IMAGE{2em}{b} 525 | % \end{wrapstuff} 526 | % \QIANZIWEN 527 | % \begin{wrapstuff}[c,0,column=false] 528 | % \IMAGE{2em}{c} 529 | % \end{wrapstuff} 530 | % \QIANZIWEN 531 | % \end{SideBySideExample} 532 | % \end{function} 533 | % 534 | % \begin{function}{leftsep,rightsep,hsep} 535 | % \begin{syntax} 536 | % leftsep = <长度> 537 | % rightsep = <长度> 538 | % hsep = <长度> 539 | % \end{syntax} 540 | % 设置绕排内容与正文的左/右间距,选项 \opt{hsep} 同时设置 \opt{leftsep} 和 \opt{rightsep}。 541 | % 初始值是 \qty{1}{em}。 542 | % \end{function} 543 | % 544 | % \begin{function}{abovesep,belowsep,vsep} 545 | % \begin{syntax} 546 | % abovesep = <长度> 547 | % belowsep = <长度> 548 | % vsep = <长度> 549 | % \end{syntax} 550 | % 设置绕排内容与正文的上/下间距,选项 \opt{vsep} 同时设置 \opt{abovesep} 和 \opt{belowsep}。 551 | % 初始值是 \qty{0}{pt}。 552 | % \end{function} 553 | % 554 | % \begin{function}{hoffset} 555 | % \begin{syntax} 556 | % hoffset = <长度> 557 | % \end{syntax} 558 | % 设置绕排内容伸出正文版心的长度。 559 | % 当设置了选项 \opt{c} 或者选项 \opt{ratio} 的值位于 $(0,1)$ 时,本选项无效。 560 | % 一个特殊值 \tn{width} 用于表示绕排内容和相应间距的总宽度, 561 | % 可以将 \opt{hoffset} 设置为 \tn{width},完全伸出版心。 562 | % 初始值为 \qty{0}{pt}。 563 | % \end{function} 564 | % 565 | % \begin{function}{voffset} 566 | % \begin{syntax} 567 | % voffset = <长度> 568 | % \end{syntax} 569 | % 用于调整绕排内容的竖直位置,初始值为 \qty{0}{pt}。 570 | % \end{function} 571 | % 572 | % \begin{function}{type} 573 | % \begin{syntax} 574 | % type = <浮动体类型> 575 | % \end{syntax} 576 | % 设置绕排内容的浮动体类型,初始值为空。 577 | % 如果需要在 \env{wrapstuff} 环境中使用 \tn{caption} 命令, 578 | % 则需要设置 \opt{type} 为 \opt{figure} 或 \opt{table} 等类型, 579 | % 并需要同时设置 \opt{width} 指定宽度。 580 | % \begin{SideBySideExample}[xrightmargin=\dimeval{18em+5mm}] 581 | % \begin{wrapstuff}[type=figure,width=5em] 582 | % \centering 583 | % \IMAGE{4em}{plain} 584 | % \caption{示例} 585 | % \end{wrapstuff} 586 | % \QIANZIWEN 587 | % \end{SideBySideExample} 588 | % \end{function} 589 | % 590 | % \begin{function}{\wrapstuffclear} 591 | % 如果当前正文段落的行数不够,\pkg{wrapstuff} 的作用会延续到下一段。 592 | % 这可能会导致某些意外结果,可以在下一段之前启用命令 \tn{wrapstuffclear} 消除影响。 593 | % \end{function} 594 | % 595 | % \end{documentation} 596 | % 597 | % 598 | % \StopEventually{} 599 | % 600 | % 601 | % \begin{implementation} 602 | % 603 | % \section{代码实现} 604 | % 605 | % \begin{macrocode} 606 | %<*package> 607 | % \end{macrocode} 608 | % 609 | % \begin{macrocode} 610 | %<@@=wstf> 611 | % \end{macrocode} 612 | % 613 | % \pkg{wrapstuff} 的实现依赖 \LaTeX\ 2021-06-01 开始提供的段落钩子。 614 | % \begin{macrocode} 615 | \@ifl@t@r \fmtversion { 2021-06-01 } 616 | { } 617 | { 618 | \msg_new:nnn { wrapstuff } { latex-too-old } 619 | { 620 | You~need~to~update~your~LaTeX~to~the~latest~release. \\ 621 | Loading~wrapstuff~will~abort! 622 | } 623 | \msg_critical:nn { wrapstuff } { latex-too-old } 624 | } 625 | % \end{macrocode} 626 | % 627 | % 由于使用了 \cs{keys_precompile:nnN},需要比较新的 \LaTeXiii。 628 | % \begin{macrocode} 629 | \@ifl@t@r \ExplLoaderFileDate { 2022-04-10 } 630 | { } 631 | { 632 | \msg_new:nnn { wrapstuff } { latex3-too-old } 633 | { 634 | You~need~to~update~your~installation~of~the~bundles~ 635 | "l3kernel"~and~"l3packages". \\ 636 | Loading~wrapstuff~will~abort! 637 | } 638 | \msg_critical:nn { wrapstuff } { latex3-too-old } 639 | } 640 | % \end{macrocode} 641 | % 642 | % \begin{macrocode} 643 | \prop_gput:Nnn \g_msg_module_name_prop { wstf } { wrapstuff } 644 | % \end{macrocode} 645 | % 646 | % \begin{macro}[var]{ 647 | % \c_@@_global_tl_tl, 648 | % \c_@@_global_dim_tl, 649 | % \c_@@_global_int_tl, 650 | % \c_@@_global_bool_tl} 651 | % 一些需要全局设置的变量。 652 | % \begin{macrocode} 653 | \tl_const:Nn \c_@@_global_tl_tl 654 | { \g_@@_main_setting_tl } 655 | \tl_const:Nn \c_@@_global_dim_tl 656 | { 657 | \g_@@_hang_ht_dim 658 | \g_@@_total_ht_dim 659 | \g_@@_stuff_ht_dim 660 | \g_@@_stuff_wd_dim 661 | \g_@@_first_dp_dim 662 | \g_@@_first_sep_dim 663 | \g_@@_prevdepth_dim 664 | \g_@@_column_ht_dim 665 | \g_@@_window_ht_dim 666 | \g_@@_remaining_dim 667 | \g_@@_column_room_dim 668 | \g_@@_parshape_indent_dim 669 | \g_@@_parshape_length_dim 670 | } 671 | \tl_const:Nn \c_@@_global_int_tl 672 | { 673 | \g_@@_top_int 674 | \g_@@_column_int 675 | \g_@@_window_int 676 | } 677 | \tl_const:Nn \c_@@_global_bool_tl 678 | { 679 | \g_@@_next_bool 680 | \g_@@_leqno_bool 681 | \g_@@_column_bool 682 | \g_@@_entire_bool 683 | \g_@@_display_bool 684 | \g_@@_move_hang_bool 685 | \g_@@_next_hang_bool 686 | \g_@@_first_set_bool 687 | \g_@@_first_save_bool 688 | \g_@@_right_move_bool 689 | } 690 | % \end{macrocode} 691 | % \end{macro} 692 | % 693 | % \begin{macro}{ 694 | % \@@_tl_init:N, 695 | % \@@_dim_init:N, 696 | % \@@_int_init:N, 697 | % \@@_bool_init:N} 698 | % 全局变量的初始化,注意保存好清除和恢复的设置。 699 | % \begin{macrocode} 700 | \cs_new_protected:Npn \@@_tl_init:N #1 701 | { 702 | \tl_new:N #1 703 | \tl_gput_right:Nn \g_@@_var_clear_tl 704 | { \tl_gclear:N #1 } 705 | \tl_gput_right:Nn \g_@@_var_push_tl 706 | { \tl_gset:Nn \exp_not:N #1 { \exp_not:o {#1} } } 707 | } 708 | \cs_new_protected:Npn \@@_dim_init:N #1 709 | { 710 | \dim_new:N #1 711 | \tl_gput_right:Nn \g_@@_var_clear_tl 712 | { \dim_gzero:N #1 } 713 | \tl_gput_right:Nn \g_@@_var_push_tl 714 | { \dim_gset:Nn #1 { \dim_use:N #1 } } 715 | } 716 | \cs_new_protected:Npn \@@_int_init:N #1 717 | { 718 | \int_new:N #1 719 | \tl_gput_right:Nn \g_@@_var_clear_tl 720 | { \int_gzero:N #1 } 721 | \tl_gput_right:Nn \g_@@_var_push_tl 722 | { \int_gset:Nn #1 { \int_use:N #1 } } 723 | } 724 | \cs_new_protected:Npn \@@_bool_init:N #1 725 | { 726 | \bool_new:N #1 727 | \tl_gput_right:Nn \g_@@_var_clear_tl 728 | { \bool_gset_false:N #1 } 729 | \tl_gput_right:Nn \g_@@_var_push_tl 730 | { 731 | \bool_if:NTF #1 732 | { \bool_gset_true:N #1 } 733 | { \bool_gset_false:N #1 } 734 | } 735 | } 736 | \tl_new:N \g_@@_var_clear_tl 737 | \tl_new:N \g_@@_var_push_tl 738 | \tl_map_function:NN \c_@@_global_tl_tl \@@_tl_init:N 739 | \tl_map_function:NN \c_@@_global_dim_tl \@@_dim_init:N 740 | \tl_map_function:NN \c_@@_global_int_tl \@@_int_init:N 741 | \tl_map_function:NN \c_@@_global_bool_tl \@@_bool_init:N 742 | % \end{macrocode} 743 | % \cs{g_@@_top_int} 的初始值是 $-1$。 744 | % \begin{macrocode} 745 | \int_gdecr:N \g_@@_top_int 746 | \tl_gput_right:Nn \g_@@_var_clear_tl 747 | { \int_gdecr:N \g_@@_top_int } 748 | % \end{macrocode} 749 | % \end{macro} 750 | % 751 | % \begin{macro}{ 752 | % \@@_clear:, 753 | % \@@_clear_variable:, 754 | % \@@_clear_kludge:, 755 | % \@@_clear_stuff_box:} 756 | % \begin{macrocode} 757 | \cs_new_protected_nopar:Npn \@@_clear: 758 | { 759 | \@@_clear_para_hook: 760 | \@@_clear_kludge: 761 | \@@_clear_variable: 762 | } 763 | \cs_new_protected_nopar:Npn \@@_clear_variable: 764 | { 765 | \tl_use:N \g_@@_var_clear_tl 766 | \box_gclear:N \g_@@_stuff_box 767 | } 768 | \cs_new_protected_nopar:Npn \@@_clear_kludge: 769 | { 770 | \bool_if:NTF \g_@@_next_bool 771 | { 772 | \skip_vertical:n 773 | { \tex_baselineskip:D * \g_@@_window_int } 774 | } 775 | { 776 | \box_if_empty:NF \g_@@_stuff_box 777 | { \@@_clear_stuff_box: } 778 | } 779 | } 780 | \cs_new_protected_nopar:Npn \@@_clear_stuff_box: 781 | { 782 | \@@_ignore_depth: 783 | \skip_set:Nn \l_@@_last_skip 784 | { \box_dp:N \strutbox } 785 | \skip_vertical:N \l_@@_last_skip 786 | \box_use_drop:N \g_@@_stuff_box 787 | \skip_vertical:N \l_@@_last_skip 788 | \@@_ignore_depth: 789 | } 790 | % \end{macrocode} 791 | % \end{macro} 792 | % 793 | % \begin{macro}{ 794 | % \@@_status_push:, 795 | % \@@_status_pop:, 796 | % \@@_status_restore:, 797 | % \@@_status_clear:} 798 | % 全局变量的保存与恢复。 799 | % \begin{macrocode} 800 | \cs_new_protected_nopar:Npn \@@_status_push: 801 | { 802 | \tl_clear:N \l_@@_status_tl 803 | \int_gincr:N \g_@@_status_int 804 | \exp_args:Ne \@@_status_push_aux:n 805 | { \int_use:N \g_@@_status_int } 806 | \seq_gpush:No \g_@@_status_seq { \l_@@_status_tl } 807 | } 808 | \cs_new_protected:Npn \@@_status_push_aux:n #1 809 | { 810 | \@@_push_cs:nN {#1} \@@_para_before: 811 | \@@_push_cs:nN {#1} \@@_para_begin: 812 | \@@_push_cs:nN {#1} \@@_para_end: 813 | \@@_push_cs:nN {#1} \@@_display_hook: 814 | \@@_push_box:N \g_@@_stuff_box 815 | \@@_push_var: 816 | } 817 | \cs_new_protected:Npn \@@_push_cs:nN #1#2 818 | { 819 | \exp_args:NNc \@@_push_cs_aux:NN #2 820 | { @@_ #1 _ \token_to_str:N #2 } 821 | } 822 | \cs_new_protected:Npn \@@_push_cs_aux:NN #1#2 823 | { 824 | \cs_gset_eq:NN #2#1 825 | \tl_put_right:Nn \l_@@_status_tl 826 | { 827 | \cs_gset_eq:NN #1#2 828 | \cs_undefine:N #2 829 | } 830 | } 831 | \cs_new_protected:Npn \@@_push_box:N #1 832 | { 833 | \hbox_gset:Nn \g_@@_stauts_box 834 | { 835 | \hbox_unpack_drop:N \g_@@_stauts_box 836 | \box_use:N #1 837 | } 838 | \tl_put_right:Nn \l_@@_status_tl 839 | { \@@_pop_box:N #1 } 840 | } 841 | \cs_new_protected:Npn \@@_pop_box:N #1 842 | { 843 | \hbox_gset:Nw \g_@@_stauts_box 844 | \hbox_unpack_drop:N \g_@@_stauts_box 845 | \box_gset_to_last:N #1 846 | \@@_if_last_hlist:TF 847 | { \hbox_gset_end: } 848 | { 849 | \hbox_gset_end: 850 | \box_gclear:N \g_@@_stauts_box 851 | } 852 | } 853 | \cs_new_protected_nopar:Npn \@@_push_var: 854 | { 855 | \tl_put_right:Nx \l_@@_status_tl 856 | { \g_@@_var_push_tl } 857 | } 858 | \cs_new_protected_nopar:Npn \@@_status_pop: 859 | { 860 | \seq_gpop:NNT \g_@@_status_seq \l_@@_status_tl 861 | { 862 | \int_gdecr:N \g_@@_status_int 863 | \tl_use:N \l_@@_status_tl 864 | } 865 | } 866 | \cs_new_protected_nopar:Npn \@@_status_restore: 867 | { 868 | \@@_status_push: 869 | \@@_clear_para_hook: 870 | \@@_clear_display_hook: 871 | \@@_clear_variable: 872 | \group_insert_after:N \@@_status_pop: 873 | } 874 | \cs_new_protected_nopar:Npn \@@_status_clear: 875 | { 876 | \bool_if:NT \g_@@_next_bool 877 | { 878 | \@@_clear_para_hook: 879 | \@@_clear_variable: 880 | } 881 | } 882 | \tl_new:N \l_@@_status_tl 883 | \box_new:N \g_@@_stauts_box 884 | \int_new:N \g_@@_status_int 885 | \seq_new:N \g_@@_status_seq 886 | % \end{macrocode} 887 | % \end{macro} 888 | % 889 | % \changes{v0.2}{2022/07/21}{兼容 \tn{parbox} 与 \env{minipage} 等使用环境。} 890 | % 891 | % \begin{macro}{\wrapstuff@parboxrestore,\@arrayparboxrestore} 892 | % 在 \LaTeX\ 的 \cs{parbox} 和 \env{minipage} 等环境中恢复正常的段落状态。 893 | % \tn{wrapstuff@parboxrestore} 的初始值是在分组后清除活动的段落钩子和相关全局变量, 894 | % 只有在 \env{wrapstuff@par} 环境内部才等于 \cs{@@_status_restore:}, 895 | % 保存和恢复相关状态。 896 | % \begin{macrocode} 897 | \cs_new_protected_nopar:Npn \wrapstuff@parboxrestore 898 | { \group_insert_after:N \@@_status_clear: } 899 | \cs_new_protected_nopar:Npn \@@_parbox_restore: 900 | { 901 | \cs_set_eq:NN 902 | \wrapstuff@parboxrestore 903 | \@@_status_restore: 904 | } 905 | \g@addto@macro \@arrayparboxrestore 906 | { \wrapstuff@parboxrestore } 907 | % \end{macrocode} 908 | % \end{macro} 909 | % 910 | % \begin{macro}[TF]{ 911 | % \@@_if_last_none:, 912 | % \@@_if_last_hlist:, 913 | % \@@_if_last_whatsit:, 914 | % \@@_if_last_glue:, 915 | % \@@_if_last_kern:, 916 | % \@@_if_last_penalty:} 917 | % 一些 \hologo{eTeX} 结点判定函数。 918 | % \begin{macrocode} 919 | \group_begin: 920 | \cs_set:Npn \@@_tmp:nn #1 921 | { 922 | \exp_args:Ncc \@@_tmp_aux:NNn 923 | { @@_if_last_ #1 : } 924 | { c_@@_ #1 _node } 925 | } 926 | \cs_set:Npn \@@_tmp_aux:NNn #1#2#3 927 | { 928 | \int_const:Nn #2 {#3} 929 | \prg_new_conditional:Npnn #1 { T , F , TF } 930 | { 931 | \if_int_compare:w \tex_lastnodetype:D = #2 932 | \prg_return_true: \else: \prg_return_false: \fi: 933 | } 934 | } 935 | \@@_tmp:nn { none } { -1 } 936 | \@@_tmp:nn { hlist } { 1 } 937 | \@@_tmp:nn { whatsit } { 9 } 938 | \@@_tmp:nn { glue } { 11 } 939 | \@@_tmp:nn { kern } { 12 } 940 | \@@_tmp:nn { penalty } { 13 } 941 | \group_end: 942 | % \end{macrocode} 943 | % \end{macro} 944 | % 945 | % \begin{macro}{\@@_gadd_hook:nn, \@@_package_hook:nn} 946 | % \begin{macrocode} 947 | \cs_new_protected:Npn \@@_gadd_hook:nn #1 948 | { \hook_gput_code:nnn {#1} { wrapstuff } } 949 | \cs_new_protected:Npn \@@_package_hook:nn #1 950 | { \hook_gput_code:nnn { package/#1/after } { wrapstuff } } 951 | % \end{macrocode} 952 | % \end{macro} 953 | % 954 | % \begin{macro}{\@@_para_raw_end:} 955 | % 将 \cs{para_raw_end:} 放在分组中是为了保持 \tn{parshape}。 956 | % \begin{macrocode} 957 | \cs_new_protected_nopar:Npn \@@_para_raw_end: 958 | { \group_begin: \para_raw_end: \group_end: } 959 | % \end{macrocode} 960 | % \end{macro} 961 | % 962 | % \begin{macro}{\@@_gadd_ht:Nn} 963 | % \begin{macrocode} 964 | \cs_new_protected:Npn \@@_gadd_ht:Nn #1#2 965 | { \box_gset_ht:Nn #1 { \box_ht:N #1 + \dim_eval:n {#2} } } 966 | % \end{macrocode} 967 | % \end{macro} 968 | % 969 | % \begin{macro}{wrapstuff} 970 | % 主要功能环境接口。 971 | % \begin{macrocode} 972 | \NewDocumentEnvironment { wrapstuff } { O { } } 973 | { 974 | \@@_clear: 975 | \int_set:Nn \l_@@_top_int { -1 } 976 | \tl_if_blank:nTF {#1} 977 | { \tl_clear:N \l_@@_main_kv_tl } 978 | { 979 | \keys_set_filter:nnnN { wrapstuff } 980 | { main , ratio } 981 | {#1} \l_@@_main_kv_tl 982 | } 983 | \tl_set:Nx \l_@@_type_tl { \l_@@_type_tl } 984 | \dim_set:Nn \l_@@_width_dim { \l_@@_width_tl } 985 | \dim_set:Nn \l_@@_height_dim { \l_@@_height_tl } 986 | \hbox_gset:Nw \g_@@_stuff_box 987 | \dim_compare:nNnTF \l_@@_width_dim > \c_zero_dim 988 | { \@@_minipage_begin: } 989 | { \@@_hbox_begin: } 990 | } 991 | { 992 | \dim_compare:nNnTF \l_@@_width_dim > \c_zero_dim 993 | { \@@_minipage_end: } 994 | { \@@_hbox_end: } 995 | \@@_set_vsep: 996 | \@@_attach_label: 997 | \tl_if_empty:NTF \l_@@_main_kv_tl 998 | { \tl_gclear:N \g_@@_main_setting_tl } 999 | { \@@_save_main_setting: } 1000 | \@@_set_top_line: 1001 | \dim_gset:Nn \g_@@_stuff_wd_dim 1002 | { \box_wd:N \g_@@_stuff_box } 1003 | \dim_gset:Nn \g_@@_stuff_ht_dim 1004 | { \box_ht_plus_dp:N \g_@@_stuff_box } 1005 | \dim_gset_eq:NN 1006 | \g_@@_remaining_dim 1007 | \g_@@_stuff_ht_dim 1008 | \@@_next_para: 1009 | } 1010 | \@@_gadd_hook:nn { env/wrapstuff/before } { \par } 1011 | \cs_new_protected_nopar:Npn \@@_minipage_begin: 1012 | { 1013 | \@@_floatrow_hook: 1014 | \dim_compare:nNnTF \l_@@_height_dim > \c_zero_dim 1015 | { \begin { minipage } [b] [ \l_@@_height_dim ] [c] { \l_@@_width_dim } } 1016 | { \begin { minipage } [b] { \l_@@_width_dim } } 1017 | \tl_if_empty:NF \l_@@_type_tl 1018 | { \@@_set_float: } 1019 | } 1020 | \cs_new_protected_nopar:Npn \@@_minipage_end: 1021 | { 1022 | \end { minipage } 1023 | \hbox_gset_end: 1024 | \@@_float_pos_hook: 1025 | } 1026 | \cs_new_protected_nopar:Npn \@@_hbox_begin: 1027 | { \tex_ignorespaces:D } 1028 | \cs_new_protected_nopar:Npn \@@_hbox_end: 1029 | { 1030 | \tex_unskip:D 1031 | \hbox_gset_end: 1032 | \dim_compare:nNnT \l_@@_height_dim > \c_zero_dim 1033 | { \@@_gset_height: } 1034 | } 1035 | \cs_new_protected_nopar:Npn \@@_gset_height: 1036 | { 1037 | \hbox_gset:Nn \g_@@_stuff_box 1038 | { 1039 | \box_move_up:nn 1040 | { 1041 | ( \l_@@_height_dim 1042 | - \box_ht:N \g_@@_stuff_box 1043 | + \box_dp:N \g_@@_stuff_box 1044 | ) / 2 1045 | } 1046 | { \box_use_drop:N \g_@@_stuff_box } 1047 | } 1048 | \box_gset_ht:Nn \g_@@_stuff_box { \l_@@_height_dim } 1049 | \box_gset_dp:Nn \g_@@_stuff_box { \c_zero_dim } 1050 | } 1051 | \cs_new_protected_nopar:Npn \@@_set_vsep: 1052 | { 1053 | \@@_gadd_ht:Nn \g_@@_stuff_box { \l_@@_abovesep_tl } 1054 | \dim_set:Nn \l_@@_shift_dim { \l_@@_belowsep_tl } 1055 | \dim_compare:nNnF \l_@@_shift_dim = \c_zero_dim 1056 | { \@@_set_belowsep: } 1057 | } 1058 | \cs_new_protected_nopar:Npn \@@_set_belowsep: 1059 | { 1060 | \hbox_gset:Nn \g_@@_stuff_box 1061 | { 1062 | \box_move_up:nn 1063 | { \l_@@_shift_dim + \box_dp:N \g_@@_stuff_box } 1064 | { \box_use_drop:N \g_@@_stuff_box } 1065 | } 1066 | \box_gset_dp:Nn \g_@@_stuff_box { \c_zero_dim } 1067 | } 1068 | \tl_new:N \l_@@_main_kv_tl 1069 | \box_new:N \g_@@_stuff_box 1070 | \dim_new:N \l_@@_shift_dim 1071 | \dim_new:N \l_@@_width_dim 1072 | \dim_new:N \l_@@_height_dim 1073 | % \end{macrocode} 1074 | % \end{macro} 1075 | % 1076 | % \changes{v0.2}{2022/07/26}{优化重新编译警告。} 1077 | % 1078 | % \begin{macro}{\@@_attach_label:, \@@_write_label:,\@@_rerun_check:} 1079 | % \begin{macrocode} 1080 | \cs_new_protected_nopar:Npn \@@_attach_label: 1081 | { 1082 | \stepcounter { wrapstuff } 1083 | \hbox_gset:Nn \g_@@_stuff_box 1084 | { 1085 | \@@_write_label: 1086 | \box_use_drop:N \g_@@_stuff_box 1087 | } 1088 | } 1089 | \cs_new_protected_nopar:Npn \@@_write_label: 1090 | { 1091 | \exp_args:Nee \@@_write_label_aux:nn 1092 | { \@@_counter:n { wrapstuff } } 1093 | { \@@_counter:n { page } } 1094 | } 1095 | \cs_new_protected:Npx \@@_write_label_aux:nn #1#2 1096 | { 1097 | \prop_gput_if_new:Nnn \exp_not:N \g_@@_page_prop {#1} {#2} 1098 | \iow_shipout_x:Nn \exp_not:N \@auxout 1099 | { 1100 | \c_backslash_str wrapstuff@label 1101 | {#1} 1102 | { \exp_not:N \wrapstuff@counter { page } } 1103 | } 1104 | } 1105 | \newcounter { wrapstuff } 1106 | \cs_new:Npn \@@_counter:n #1 1107 | { \int_value:w \value {#1} } 1108 | \cs_new_eq:NN \wrapstuff@counter \@@_counter:n 1109 | \cs_new_protected_nopar:Npn \wrapstuff@label 1110 | { \prop_gput:Nnn \g_@@_page_prop } 1111 | \@@_gadd_hook:nn { begindocument } 1112 | { 1113 | \legacy_if:nTF { @filesw } 1114 | { 1115 | \iow_now:Nx \@mainaux 1116 | { 1117 | \c_backslash_str providecommand 1118 | \c_backslash_str wrapstuff@label [2] { } 1119 | } 1120 | } 1121 | { \cs_gset_eq:NN \@@_write_label: \@@_empty: } 1122 | } 1123 | \@@_gadd_hook:nn { enddocument/afterlastpage } 1124 | { 1125 | \legacy_if:nT { @filesw } 1126 | { \prop_gclear:N \g_@@_page_prop } 1127 | } 1128 | \@@_gadd_hook:nn { enddocument/info } 1129 | { 1130 | \prop_if_empty:NF \g_@@_rerun_prop 1131 | { \@@_rerun_check: } 1132 | } 1133 | \cs_new_protected_nopar:Npn \@@_rerun_check: 1134 | { 1135 | \prop_map_inline:Nn \g_@@_rerun_prop 1136 | { 1137 | \prop_get:NnN \g_@@_page_prop { ##1 } \l_@@_page_tl 1138 | \int_if_even:nF { \l_@@_page_tl - ##2 } 1139 | { \prop_map_break:n { \@@_rerun_warning: } } 1140 | } 1141 | } 1142 | \cs_new_protected_nopar:Npn \@@_rerun_warning: 1143 | { \msg_warning:nn { wstf } { rerun-required } } 1144 | \msg_new:nnn { wstf } { rerun-required } 1145 | { 1146 | Page(s)~may~have~changed.\\ 1147 | Rerun~to~get~i/o~setting~right. 1148 | } 1149 | \tl_new:N \l_@@_page_tl 1150 | \prop_new:N \g_@@_page_prop 1151 | \prop_new:N \g_@@_rerun_prop 1152 | % \end{macrocode} 1153 | % \end{macro} 1154 | % 1155 | % \begin{macro}{\@@_save_main_setting:} 1156 | % \begin{macrocode} 1157 | \cs_new_protected_nopar:Npn \@@_save_main_setting: 1158 | { 1159 | \exp_args:Nnno 1160 | \keys_set_filter:nnnN { wrapstuff } 1161 | { main } 1162 | { \l_@@_main_kv_tl } \l_@@_main_kv_tl 1163 | \bool_if:NTF \l_@@_swap_bool 1164 | { \@@_swap_ratio: } 1165 | { \@@_set_ratio:N \l_@@_ratio_fp } 1166 | \tl_if_empty:NF \l_@@_main_kv_tl 1167 | { \@@_save_main_setting_aux: } 1168 | } 1169 | \cs_new_protected:Npn \@@_set_ratio:N #1 1170 | { 1171 | \tl_gset:Nx \g_@@_main_setting_tl 1172 | { \fp_set:Nn \exp_not:N \l_@@_ratio_fp { \fp_use:N #1 } } 1173 | } 1174 | \cs_new_protected:Npn \@@_set_ratio:n #1 1175 | { 1176 | \tl_gset:Nx \g_@@_main_setting_tl 1177 | { \fp_set:Nn \exp_not:N \l_@@_ratio_fp { \fp_eval:n {#1} } } 1178 | } 1179 | \cs_new_protected_nopar:Npn \@@_save_main_setting_aux: 1180 | { 1181 | \exp_args:Nno 1182 | \keys_precompile:nnN 1183 | { wrapstuff } 1184 | { \l_@@_main_kv_tl } \l_@@_main_kv_tl 1185 | \tl_gconcat:NNN 1186 | \g_@@_main_setting_tl 1187 | \g_@@_main_setting_tl 1188 | \l_@@_main_kv_tl 1189 | } 1190 | % \end{macrocode} 1191 | % \end{macro} 1192 | % 1193 | % \begin{macro}{\@@_set_top_line:} 1194 | % \begin{macrocode} 1195 | \cs_new_protected_nopar:Npn \@@_set_top_line: 1196 | { 1197 | \int_compare:nNnF \l_@@_top_int < \c_zero_int 1198 | { 1199 | \tl_gput_right:Nx \g_@@_main_setting_tl 1200 | { 1201 | \int_set:Nn \l_@@_top_int 1202 | { \int_use:N \l_@@_top_int } 1203 | } 1204 | } 1205 | } 1206 | % \end{macrocode} 1207 | % \end{macro} 1208 | % 1209 | % \begin{macro}{\@@_swap_ratio:} 1210 | % \begin{macrocode} 1211 | \cs_new_protected_nopar:Npn \@@_swap_ratio: 1212 | { 1213 | \exp_args:Ne \@@_swap_ratio_aux:n 1214 | { \@@_counter:n { wrapstuff } } 1215 | } 1216 | \cs_new_protected:Npn \@@_swap_ratio_aux:n #1 1217 | { 1218 | \fp_compare:nF 1219 | { \c_zero_fp < \l_@@_ratio_fp < \c_one_fp } 1220 | { \fp_zero:N \l_@@_ratio_fp } 1221 | \prop_get:NnNF \g_@@_page_prop {#1} \l_@@_page_tl 1222 | { \tl_set:Nx \l_@@_page_tl { \@@_counter:n { page } } } 1223 | \int_if_odd:nTF { \l_@@_page_tl } 1224 | { \bool_if:NTF \l_@@_inner_bool } 1225 | { \bool_if:NTF \l_@@_outer_bool } 1226 | { \@@_set_ratio:N \l_@@_ratio_fp } 1227 | { \@@_set_ratio:n { \c_one_fp - \l_@@_ratio_fp } } 1228 | \prop_gput:Nno \g_@@_rerun_prop {#1} { \l_@@_page_tl } 1229 | } 1230 | \bool_new:N \l_@@_swap_bool 1231 | \bool_new:N \l_@@_inner_bool 1232 | \bool_new:N \l_@@_outer_bool 1233 | % \end{macrocode} 1234 | % \end{macro} 1235 | % 1236 | % \begin{macro}{\@@_next_para:} 1237 | % 将 \env{wrapstuff} 环境之后的段落放入内部环境 \env{wrapstuff@par} 中。 1238 | % 为了控制钩子执行顺序,需要使用 |wrapstuff| 标签, 1239 | % 而不用更为方便的 \cs{hook_gput_next_code:nn} 实现。 1240 | % \begin{macrocode} 1241 | \@@_gadd_hook:nn { para/before } { \@@_para_before: } 1242 | \@@_gadd_hook:nn { para/after } { \@@_para_after: } 1243 | \@@_gadd_hook:nn { para/begin } { \@@_para_begin: } 1244 | \@@_gadd_hook:nn { para/end } { \@@_para_end: } 1245 | \cs_new_protected_nopar:Npn \@@_next_para: 1246 | { 1247 | \cs_gset_eq:NN \@@_para_before: \@@_env_before: 1248 | \cs_gset_eq:NN \@@_para_begin: \@@_env_begin: 1249 | \cs_gset_eq:NN \@@_para_end: \@@_env_end: 1250 | } 1251 | \cs_new_protected_nopar:Npn \@@_env_before: 1252 | { \dim_gset_eq:NN \g_@@_prevdepth_dim \tex_prevdepth:D } 1253 | \cs_new_protected_nopar:Npn \@@_env_begin: 1254 | { \begin { wrapstuff@par } } 1255 | \cs_new_protected_nopar:Npn \@@_env_end: 1256 | { \end { wrapstuff@par } } 1257 | \cs_new_protected_nopar:Npn \@@_clear_para_hook: 1258 | { 1259 | \cs_gset_eq:NN \@@_para_before: \@@_empty: 1260 | \cs_gset_eq:NN \@@_para_after: \@@_empty: 1261 | \cs_gset_eq:NN \@@_para_begin: \@@_empty: 1262 | \cs_gset_eq:NN \@@_para_end: \@@_empty: 1263 | } 1264 | \cs_new_protected_nopar:Npn \@@_empty: 1265 | { } 1266 | \cs_new_eq:NN \@@_para_before: \@@_empty: 1267 | \cs_new_eq:NN \@@_para_after: \@@_empty: 1268 | \cs_new_eq:NN \@@_para_begin: \@@_empty: 1269 | \cs_new_eq:NN \@@_para_end: \@@_empty: 1270 | % \end{macrocode} 1271 | % \end{macro} 1272 | % 1273 | % \begin{macro}[int]{wrapstuff@par} 1274 | % 内部环境,实现主要功能。 1275 | % \begin{macrocode} 1276 | \NewDocumentEnvironment { wrapstuff@par } { } 1277 | { 1278 | \tl_use:N \g_@@_main_setting_tl 1279 | \dim_set:Nn \l_@@_leftsep_dim { \l_@@_leftsep_tl } 1280 | \dim_set:Nn \l_@@_rightsep_dim { \l_@@_rightsep_tl } 1281 | \dim_set:Nn \l_@@_voffset_dim { \l_@@_voffset_tl } 1282 | \dim_set:Nn \l_@@_line_dim { \l_@@_linewidth_tl } 1283 | \dim_set:Nn \l_@@_min_dim { \box_dp:N \strutbox } 1284 | \dim_set_eq:NN \l_@@_main_width_dim \l_@@_line_dim 1285 | \dim_sub:Nn \l_@@_line_dim 1286 | { \tex_leftskip:D + \tex_rightskip:D } 1287 | \dim_set:Nn \l_@@_window_dim 1288 | { \l_@@_line_dim - \g_@@_stuff_wd_dim } 1289 | \fp_compare:nNnTF \l_@@_ratio_fp > \c_zero_fp 1290 | { 1291 | \fp_compare:nNnTF \l_@@_ratio_fp < \c_one_fp 1292 | { \@@_set_window: } 1293 | { \@@_set_hang_right: } 1294 | } 1295 | { \@@_set_hang_left: } 1296 | \int_compare:nNnTF \g_@@_window_int > \c_zero_int 1297 | { 1298 | \int_set_eq:NN \l_@@_window_int \g_@@_window_int 1299 | \int_zero:N \l_@@_top_int 1300 | } 1301 | { \@@_set_lines: } 1302 | \bool_if:NTF \l_@@_hang_bool 1303 | { 1304 | \dim_set_eq:NN \l_@@_display_dim \l_@@_window_dim 1305 | \int_set_eq:NN \l_@@_window_line_int \l_@@_window_int 1306 | } 1307 | { 1308 | \dim_set_eq:NN \l_@@_display_dim \l_@@_l_dim 1309 | \int_set:Nn \l_@@_window_int { \l_@@_window_int * 2 } 1310 | \int_set:Nn \l_@@_window_line_int 1311 | { 1312 | \bool_if:NTF \g_@@_column_bool 1313 | { \l_@@_window_int / 2 + \g_@@_column_int } 1314 | { \l_@@_window_int } 1315 | } 1316 | } 1317 | \cs_gset_eq:NN \@@_para_before: \@@_empty: 1318 | \cs_gset_eq:NN \@@_para_begin: \@@_empty: 1319 | \@@_save_parshape: 1320 | \@@_parbox_restore: 1321 | \vbox_set:Nw \l_@@_body_box 1322 | \@@_set_prevdepth:N \g_@@_prevdepth_dim 1323 | \@@_save_tex_skip: 1324 | \@@_tex_parameter: 1325 | \@@_restore_parshape: 1326 | \@@_display_parameter: 1327 | \@@_make_main_parshape: 1328 | \para_raw_noindent: 1329 | } 1330 | { 1331 | \@@_save_hangfrom: 1332 | \@@_save_tex_skip: 1333 | \@@_group_kludge: 1334 | \@@_tex_parameter: 1335 | \@@_make_main_parshape: 1336 | \para_raw_end: 1337 | \int_gset_eq:NN \g_@@_line_int \tex_prevgraf:D 1338 | \vbox_set_end: 1339 | \@@_adjust_tex_skip: 1340 | \cs_gset_eq:NN \@@_para_end: \@@_empty: 1341 | \cs_gset_eq:NN \@@_para_after: \@@_empty: 1342 | \int_compare:nNnTF \g_@@_line_int > \l_@@_top_int 1343 | { \@@_build_par: } 1344 | { \@@_put_par: } 1345 | } 1346 | \box_new:N \l_@@_body_box 1347 | \box_new:N \l_@@_window_box 1348 | \int_new:N \l_@@_window_int 1349 | \int_new:N \g_@@_line_int 1350 | \int_new:N \l_@@_window_line_int 1351 | \dim_new:N \l_@@_l_dim 1352 | \dim_new:N \l_@@_r_dim 1353 | \dim_new:N \l_@@_min_dim 1354 | \dim_new:N \l_@@_line_dim 1355 | \dim_new:N \l_@@_window_dim 1356 | \dim_new:N \l_@@_display_dim 1357 | \dim_new:N \l_@@_voffset_dim 1358 | \dim_new:N \l_@@_leftsep_dim 1359 | \dim_new:N \l_@@_rightsep_dim 1360 | \dim_new:N \l_@@_main_width_dim 1361 | \bool_new:N \l_@@_hang_bool 1362 | % \end{macrocode} 1363 | % \end{macro} 1364 | % 1365 | % \begin{macro}{\@@_set_hang_left:, \@@_set_hang_right:, \@@_set_window:,} 1366 | % \begin{macrocode} 1367 | \cs_new_protected_nopar:Npn \@@_set_hang_left: 1368 | { 1369 | \bool_set_true:N \l_@@_hang_bool 1370 | \@@_set_hoffset:N \l_@@_rightsep_dim 1371 | \dim_zero:N \l_@@_l_dim 1372 | \dim_set_eq:NN \l_@@_r_dim \l_@@_window_dim 1373 | \cs_set_eq:NN \@@_build_box: \@@_build_hang: 1374 | } 1375 | \cs_new_protected_nopar:Npn \@@_set_hang_right: 1376 | { 1377 | \bool_set_true:N \l_@@_hang_bool 1378 | \@@_set_hoffset:N \l_@@_leftsep_dim 1379 | \dim_zero:N \l_@@_r_dim 1380 | \dim_set_eq:NN \l_@@_l_dim \l_@@_window_dim 1381 | \cs_set_eq:NN \@@_build_box: \@@_build_hang: 1382 | } 1383 | \cs_new_protected_nopar:Npn \@@_set_window: 1384 | { 1385 | \bool_set_false:N \l_@@_hang_bool 1386 | \dim_sub:Nn \l_@@_window_dim 1387 | { \l_@@_leftsep_dim + \l_@@_rightsep_dim } 1388 | \dim_set:Nn \l_@@_l_dim 1389 | { \@@_ratio:Nn \l_@@_ratio_fp { \l_@@_window_dim } } 1390 | \dim_set:Nn \l_@@_r_dim 1391 | { \l_@@_window_dim - \l_@@_l_dim } 1392 | \bool_if:NTF \l_@@_column_bool 1393 | { \cs_set_eq:NN \@@_build_box: \@@_build_column: } 1394 | { \cs_set_eq:NN \@@_build_box: \@@_build_block: } 1395 | } 1396 | % \end{macrocode} 1397 | % \end{macro} 1398 | % 1399 | % \changes{v0.2}{2022/07/24}{修复 \opt{hoffset} 选项。} 1400 | % 1401 | % \begin{macro}{\@@_set_hoffset:N} 1402 | % \begin{macrocode} 1403 | \cs_new_protected:Npn \@@_set_hoffset:N #1 1404 | { 1405 | \dim_sub:Nn \l_@@_window_dim {#1} 1406 | \group_begin: 1407 | \dim_set:Nn \l_@@_width_dim { #1 + \g_@@_stuff_wd_dim } 1408 | \cs_set_eq:NN \width \l_@@_width_dim 1409 | \exp_args:NNNx \group_end: 1410 | \dim_add:Nn \l_@@_window_dim 1411 | { \dim_eval:n { \l_@@_hoffset_tl } } 1412 | } 1413 | % \end{macrocode} 1414 | % \end{macro} 1415 | % 1416 | % \begin{macro}{\@@_set_lines:, \@@_window_init:} 1417 | % \begin{macrocode} 1418 | \cs_new_protected_nopar:Npn \@@_set_lines: 1419 | { 1420 | \bool_if:NTF \g_@@_next_bool 1421 | { \tl_clear:N \l_@@_lines_tl } 1422 | { \tl_set:Nx \l_@@_lines_tl { \l_@@_lines_tl } } 1423 | \int_set:Nn \l_@@_window_int 1424 | { 1425 | \tl_if_empty:NTF \l_@@_lines_tl 1426 | { \@@_unit:n { \g_@@_remaining_dim + \l_@@_min_dim } } 1427 | { \l_@@_lines_tl } 1428 | } 1429 | \bool_if:NF \g_@@_next_bool 1430 | { \@@_window_init: } 1431 | \int_compare:nNnTF \g_@@_top_int < \c_zero_int 1432 | { 1433 | \int_compare:nNnT \l_@@_top_int < \c_zero_int 1434 | { \int_zero:N \l_@@_top_int } 1435 | } 1436 | { \int_set_eq:NN \l_@@_top_int \g_@@_top_int } 1437 | } 1438 | \cs_new_protected_nopar:Npn \@@_window_init: 1439 | { 1440 | \int_gset_eq:NN \g_@@_column_int \l_@@_window_int 1441 | \dim_gset:Nn \g_@@_window_ht_dim 1442 | { \tex_baselineskip:D * \g_@@_column_int } 1443 | \tl_if_empty:NF \l_@@_lines_tl 1444 | { 1445 | \dim_gset:Nn \g_@@_remaining_dim 1446 | { \g_@@_window_ht_dim - \box_ht:N \strutbox } 1447 | \dim_gset_eq:NN \g_@@_stuff_ht_dim \g_@@_remaining_dim 1448 | } 1449 | } 1450 | % \end{macrocode} 1451 | % \end{macro} 1452 | % 1453 | % \begin{macro}{\@@_make_main_parshape:} 1454 | % 主要处理用于标题悬挂的 \tn{@hangfrom} 和用于列表环境的 \tn{parshape}。 1455 | % \begin{macrocode} 1456 | \cs_new_protected_nopar:Npn \@@_make_main_parshape: 1457 | { 1458 | \dim_compare:nNnTF \g_@@_hangindent_dim > \c_zero_dim 1459 | { 1460 | \int_compare:nNnTF \g_@@_hangafter_int = \c_one_int 1461 | { \@@_make_hangfrom: } 1462 | { \@@_make_main_parshape_aux: } 1463 | } 1464 | { \@@_make_main_parshape_aux: } 1465 | } 1466 | \cs_new_protected_nopar:Npn \@@_make_main_parshape_aux: 1467 | { 1468 | \bool_gset_false:N \g_@@_hangfrom_bool 1469 | \tex_parshape:D 1470 | \int_eval:n { \l_@@_top_int + 1 } ~ 1471 | \prg_replicate:nn 1472 | { \l_@@_top_int } 1473 | { \g_@@_parshape_indent_dim \g_@@_parshape_length_dim } 1474 | \c_zero_dim \c_max_dim 1475 | } 1476 | \cs_new_protected_nopar:Npn \@@_save_parshape: 1477 | { 1478 | \int_gset_eq:NN \g_@@_parshape_int \tex_parshape:D 1479 | \int_compare:nNnTF \g_@@_parshape_int = \c_one_int 1480 | { 1481 | \dim_gset:Nn \g_@@_parshape_indent_dim 1482 | { \tex_parshapeindent:D \c_one_int } 1483 | \dim_gset:Nn \g_@@_parshape_length_dim 1484 | { \tex_parshapelength:D \c_one_int } 1485 | } 1486 | { 1487 | \int_gzero:N \g_@@_parshape_int 1488 | \dim_gzero:N \g_@@_parshape_indent_dim 1489 | \dim_gset_eq:NN \g_@@_parshape_length_dim \l_@@_main_width_dim 1490 | \int_gset_eq:NN \g_@@_hangafter_int \tex_hangafter:D 1491 | \dim_gset_eq:NN \g_@@_hangindent_dim \tex_hangindent:D 1492 | } 1493 | } 1494 | \cs_new_protected_nopar:Npn \@@_restore_parshape: 1495 | { 1496 | \int_compare:nNnTF \g_@@_parshape_int = \c_one_int 1497 | { 1498 | \tex_parshape:D \g_@@_parshape_int 1499 | \g_@@_parshape_indent_dim 1500 | \g_@@_parshape_length_dim 1501 | } 1502 | { \@@_restore_hangfrom: } 1503 | } 1504 | \cs_new_protected_nopar:Npn \@@_parshape_kern: 1505 | { 1506 | \dim_compare:nNnT \l_@@_l_dim = \c_zero_dim 1507 | { 1508 | \dim_compare:nNnF \g_@@_parshape_indent_dim = \c_zero_dim 1509 | { \tex_kern:D - \g_@@_parshape_indent_dim } 1510 | } 1511 | } 1512 | \cs_new_protected_nopar:Npn \@@_make_hangfrom: 1513 | { 1514 | \bool_if:NTF \l_@@_hang_bool 1515 | { \@@_make_hangfrom_aux: } 1516 | { \@@_make_main_parshape_aux: } 1517 | } 1518 | \cs_new_protected_nopar:Npn \@@_make_hangfrom_aux: 1519 | { 1520 | \@@_restore_hangfrom: 1521 | \int_zero:N \tex_parshape:D 1522 | \bool_gset_true:N \g_@@_hangfrom_bool 1523 | \dim_set_eq:NN \tex_hsize:D \l_@@_window_dim 1524 | } 1525 | \cs_new_protected_nopar:Npn \@@_save_hangfrom: 1526 | { 1527 | \int_gset_eq:NN \g_@@_hangafter_int \tex_hangafter:D 1528 | \dim_gset_eq:NN \g_@@_hangindent_dim \tex_hangindent:D 1529 | } 1530 | \cs_new_protected_nopar:Npn \@@_restore_hangfrom: 1531 | { 1532 | \int_set_eq:NN \tex_hangafter:D \g_@@_hangafter_int 1533 | \dim_set_eq:NN \tex_hangindent:D \g_@@_hangindent_dim 1534 | } 1535 | \bool_new:N \g_@@_hangfrom_bool 1536 | \int_new:N \g_@@_parshape_int 1537 | \int_new:N \g_@@_hangafter_int 1538 | \dim_new:N \g_@@_hangindent_dim 1539 | % \end{macrocode} 1540 | % \end{macro} 1541 | % 1542 | % \begin{macro}{\@@_group_kludge:} 1543 | % \LaTeX\ 的 \tn{list} 环境中,为了保持 \tn{parshape},\tn{par} 被重定义为 |{\@@par}|。 1544 | % \begin{macrocode} 1545 | \cs_new_protected_nopar:Npn \@@_group_kludge: 1546 | { 1547 | \scan_stop: 1548 | \int_compare:nNnTF \tex_currentgrouptype:D = \c_one_int 1549 | { 1550 | \c_group_end_token 1551 | \cs_gset_eq:NN \@@_group_begin: \c_group_begin_token 1552 | } 1553 | { \cs_gset_eq:NN \@@_group_begin: \@@_empty: } 1554 | \legacy_if:nTF { @noitemarg } 1555 | { \cs_gset_eq:NN \@@_set_itemarg: \@noitemargtrue } 1556 | { \cs_gset_eq:NN \@@_set_itemarg: \@@_empty: } 1557 | } 1558 | \cs_new_eq:NN \@@_set_itemarg: \@@_empty: 1559 | \cs_new_eq:NN \@@_group_begin: \@@_empty: 1560 | \@@_gadd_hook:nn { env/wrapstuff@par/after } 1561 | { 1562 | \@@_set_itemarg: 1563 | \@@_group_begin: 1564 | } 1565 | % \end{macrocode} 1566 | % \end{macro} 1567 | % 1568 | % \begin{macro}{\@@_ratio:Nn, \@@_unit:n} 1569 | % \begin{macrocode} 1570 | \cs_new:Npn \@@_ratio:Nn #1#2 1571 | { \fp_to_dim:n { #1 \dim_to_fp:n {#2} } } 1572 | \cs_new:Npn \@@_unit:n #1 1573 | { 1574 | \int_eval:n 1575 | { 1576 | \exp_last_unbraced:Ne \@@_unit_aux:w 1577 | { \dim_to_decimal_in_unit:nn {#1} { \tex_baselineskip:D } } 1578 | \s_stop 1579 | } 1580 | } 1581 | \cs_new:Npn \@@_unit_aux:w #1 . #2 \s_stop 1582 | { #1 + 1 } 1583 | % \end{macrocode} 1584 | % \end{macro} 1585 | % 1586 | % \begin{macro}{\@@_save_tex_skip:,\@@_tex_parameter:} 1587 | % \begin{macrocode} 1588 | \cs_new_protected_nopar:Npn \@@_save_tex_skip: 1589 | { 1590 | \skip_gset_eq:NN \g_@@_left_skip \tex_leftskip:D 1591 | \skip_gset_eq:NN \g_@@_right_skip \tex_rightskip:D 1592 | \skip_gset_eq:NN \g_@@_parfill_skip \tex_parfillskip:D 1593 | \skip_gset_eq:NN \g_@@_baseline_skip \tex_baselineskip:D 1594 | \skip_gset:Nn \g_@@_main_left_skip { - \tex_leftskip:D } 1595 | } 1596 | \cs_new_protected_nopar:Npn \@@_adjust_tex_skip: 1597 | { 1598 | \@@_adjust_skip:N \g_@@_left_skip 1599 | \@@_adjust_skip:N \g_@@_right_skip 1600 | \@@_adjust_skip:N \g_@@_parfill_skip 1601 | } 1602 | \cs_new_protected:Npn \@@_adjust_skip:N #1 1603 | { \skip_gsub:Nn #1 { \dim_eval:n {#1} } } 1604 | \cs_new_protected_nopar:Npn \@@_tex_parameter: 1605 | { 1606 | \int_zero:N \tex_clubpenalty:D 1607 | \int_zero:N \tex_widowpenalty:D 1608 | \int_zero:N \tex_interlinepenalty:D 1609 | \int_zero:N \tex_displaywidowpenalty:D 1610 | \int_zero:N \tex_clubpenalties:D 1611 | \int_zero:N \tex_widowpenalties:D 1612 | \int_zero:N \tex_interlinepenalties:D 1613 | \int_zero:N \tex_displaywidowpenalties:D 1614 | \skip_set_eq:NN \tex_leftskip:D \g_@@_left_skip 1615 | \skip_set_eq:NN \tex_rightskip:D \g_@@_right_skip 1616 | \skip_set_eq:NN \tex_parfillskip:D \g_@@_parfill_skip 1617 | \skip_set_eq:NN \tex_baselineskip:D \g_@@_baseline_skip 1618 | } 1619 | \skip_new:N \g_@@_left_skip 1620 | \skip_new:N \g_@@_right_skip 1621 | \skip_new:N \g_@@_parfill_skip 1622 | \skip_new:N \g_@@_baseline_skip 1623 | \skip_new:N \g_@@_main_left_skip 1624 | % \end{macrocode} 1625 | % \end{macro} 1626 | % 1627 | % \begin{macro}{\@@_display_parameter:} 1628 | % \begin{macrocode} 1629 | \cs_new_protected_nopar:Npn \@@_display_parameter: 1630 | { 1631 | \bool_gset_false:N \g_@@_display_bool 1632 | \tex_everydisplay:D \exp_after:wN 1633 | { 1634 | \tex_the:D \tex_everydisplay:D 1635 | \@@_display_hook: 1636 | } 1637 | } 1638 | \cs_new_protected_nopar:Npn \@@_display_hook: 1639 | { 1640 | \@@_test_leqno: 1641 | \dim_compare:nNnF \tex_displaywidth:D < \c_max_dim 1642 | { 1643 | \bool_gset_true:N \g_@@_display_bool 1644 | \dim_set_eq:NN \tex_displaywidth:D \l_@@_display_dim 1645 | } 1646 | } 1647 | \cs_new_eq:NN \@@_test_leqno: \@@_empty: 1648 | \cs_new_protected_nopar:Npn \@@_clear_display_hook: 1649 | { \cs_gset_eq:NN \@@_display_hook: \@@_empty: } 1650 | % \end{macrocode} 1651 | % \end{macro} 1652 | % 1653 | % \begin{macro}{\@@_split_parameter:} 1654 | % \begin{macrocode} 1655 | \cs_new_protected_nopar:Npn \@@_split_parameter: 1656 | { 1657 | \skip_zero:N \tex_splittopskip:D 1658 | \dim_set_eq:NN \tex_vfuzz:D \c_max_dim 1659 | \int_set_eq:NN \tex_vbadness:D \c_max_int 1660 | } 1661 | % \end{macrocode} 1662 | % \end{macro} 1663 | % 1664 | % \begin{macro}{\@@_build_par:} 1665 | % \begin{macrocode} 1666 | \cs_new_protected_nopar:Npn \@@_build_par: 1667 | { 1668 | \bool_if:NTF \g_@@_hangfrom_bool 1669 | { \@@_build_box: } 1670 | { \@@_build_par_aux: } 1671 | \box_if_empty:NTF \l_@@_window_box 1672 | { \@@_put_next_par: } 1673 | { \@@_put_box: } 1674 | } 1675 | \cs_new_protected_nopar:Npn \@@_build_par_aux: 1676 | { 1677 | \@@_extract_display_hbox:NN \l_@@_body_box \l_@@_bottom_box 1678 | \int_compare:nNnT \l_@@_top_int > \c_zero_int 1679 | { \@@_put_body_box: } 1680 | \box_if_empty:NTF \l_@@_bottom_box 1681 | { 1682 | \box_if_empty:NF \g_@@_display_box 1683 | { \@@_build_display_box: } 1684 | } 1685 | { \@@_build_body_box: } 1686 | } 1687 | \box_new:N \l_@@_bottom_box 1688 | % \end{macrocode} 1689 | % \end{macro} 1690 | % 1691 | % \begin{macro}{\@@_put_par:} 1692 | % \begin{macrocode} 1693 | \cs_new_protected_nopar:Npn \@@_put_par: 1694 | { 1695 | \int_gset:Nn \g_@@_top_int 1696 | { \l_@@_top_int - \g_@@_line_int } 1697 | \int_gzero:N \g_@@_window_int 1698 | \@@_put_body_box: 1699 | \skip_zero:N \tex_parskip:D 1700 | \para_raw_noindent: 1701 | \@@_next_para: 1702 | } 1703 | % \end{macrocode} 1704 | % \end{macro} 1705 | % 1706 | % \begin{macro}{\@@_put_body_box:} 1707 | % \begin{macrocode} 1708 | \cs_new_protected_nopar:Npn \@@_put_body_box: 1709 | { 1710 | \@@_para_raw_end: 1711 | \dim_compare:nNnTF { \box_wd:N \l_@@_body_box } < \c_max_dim 1712 | { \@@_put_body_aux:N \l_@@_body_box } 1713 | { 1714 | \@@_extract_hbox:NN \l_@@_body_box \l_@@_bottom_box 1715 | \@@_put_body_aux:N \l_@@_body_box 1716 | \box_set_eq_drop:NN \l_@@_body_box \l_@@_bottom_box 1717 | } 1718 | \@@_para_raw_end: 1719 | } 1720 | \cs_new_protected_nopar:Npn \@@_put_body_aux:N #1 1721 | { 1722 | \dim_gset:Nn \g_@@_prevdepth_dim { \box_dp:N #1 } 1723 | \dim_compare:nNnT \g_@@_prevdepth_dim = \c_zero_dim 1724 | { \@@_extract_depth:N #1 } 1725 | \vbox_unpack_drop:N #1 1726 | \@@_set_prevdepth:N \g_@@_prevdepth_dim 1727 | } 1728 | \cs_new_protected_nopar:Npn \@@_extract_depth:N #1 1729 | { 1730 | \vbox_set:Nn \l_@@_last_box 1731 | { 1732 | \vbox_unpack:N #1 1733 | \@@_if_last_hlist:F 1734 | { 1735 | \tex_unskip:D \tex_unpenalty:D 1736 | \tex_unskip:D \tex_unpenalty:D 1737 | } 1738 | \@@_if_last_hlist:T 1739 | { 1740 | \box_set_to_last:N \l_@@_last_box 1741 | \dim_gset:Nn \g_@@_prevdepth_dim 1742 | { \box_dp:N \l_@@_last_box } 1743 | } 1744 | } 1745 | } 1746 | % \end{macrocode} 1747 | % \end{macro} 1748 | % 1749 | % \begin{macro}{\@@_put_next_par:} 1750 | % \begin{macrocode} 1751 | \cs_new_protected_nopar:Npn \@@_put_next_par: 1752 | { 1753 | \int_gzero:N \g_@@_top_int 1754 | \int_gzero:N \g_@@_window_int 1755 | \skip_zero:N \tex_parskip:D 1756 | \para_raw_noindent: 1757 | \@@_next_para: 1758 | } 1759 | % \end{macrocode} 1760 | % \end{macro} 1761 | % 1762 | % \begin{macro}{\@@_build_display_box:} 1763 | % \begin{macrocode} 1764 | \cs_new_protected_nopar:Npn \@@_build_display_box: 1765 | { 1766 | \bool_set_true:N \l_@@_display_bool 1767 | \bool_if:NTF \g_@@_amsmath_bool 1768 | { \@@_build_display_amsmath: } 1769 | { \@@_build_display_normal: } 1770 | \box_if_empty:NTF \l_@@_body_box 1771 | { \@@_build_display_auxi: } 1772 | { \@@_build_display_auxii: } 1773 | } 1774 | \cs_new_protected_nopar:Npn \@@_build_display_amsmath: 1775 | { 1776 | \group_begin: 1777 | \vbox_gset:Nn \g_@@_equation_box 1778 | { 1779 | \@@_break: 1780 | \vbox_unpack_drop:N \g_@@_display_box 1781 | \skip_gset_eq:NN \g_@@_pos_skip \tex_lastskip:D 1782 | \tex_unskip:D 1783 | \int_gset_eq:NN \g_@@_pos_int \tex_lastpenalty:D 1784 | \tex_unpenalty:D 1785 | \skip_gadd:Nn \g_@@_pos_skip { \tex_lastskip:D } 1786 | \tex_unskip:D 1787 | \tex_unpenalty:D 1788 | } 1789 | \@@_split_parameter: 1790 | \vbox_set_split_to_ht:NNn \l_@@_last_box \g_@@_equation_box 1791 | { \c_zero_dim } 1792 | \group_end: 1793 | \box_gset_wd:Nn \g_@@_equation_box { \l_@@_display_dim } 1794 | \vbox_gset:Nn \g_@@_display_box 1795 | { 1796 | \tex_penalty:D \g_@@_display_pre_int 1797 | \skip_vertical:N \g_@@_display_pre_skip 1798 | } 1799 | \skip_gset_eq:NN \g_@@_pre_skip \g_@@_display_pre_skip 1800 | } 1801 | \cs_new_protected_nopar:Npn \@@_build_display_normal: 1802 | { 1803 | \vbox_gset:Nn \g_@@_display_box 1804 | { 1805 | \vbox_unpack_drop:N \g_@@_display_box 1806 | \skip_gset_eq:NN \g_@@_pos_skip \tex_lastskip:D 1807 | \tex_unskip:D 1808 | \int_gset_eq:NN \g_@@_pos_int \tex_lastpenalty:D 1809 | \tex_unpenalty:D 1810 | \box_gset_to_last:N \g_@@_equation_box 1811 | \skip_gset_eq:NN \g_@@_pre_skip \tex_lastskip:D 1812 | \tex_unskip:D 1813 | \skip_gadd:Nn \g_@@_pre_skip { \tex_lastskip:D } 1814 | \tex_unskip:D 1815 | \skip_vertical:N \g_@@_pre_skip 1816 | } 1817 | } 1818 | \cs_new_protected_nopar:Npn \@@_build_display_auxi: 1819 | { 1820 | \bool_if:NTF \g_@@_amsmath_bool 1821 | { \box_set_eq_drop:NN \l_@@_window_box \g_@@_equation_box } 1822 | { 1823 | \hbox_set_to_wd:Nnn \l_@@_window_box 1824 | { \l_@@_display_dim } 1825 | { 1826 | \tex_hss:D 1827 | \@@_adjust_equation: 1828 | \box_use_drop:N \g_@@_equation_box 1829 | \tex_hss:D 1830 | } 1831 | } 1832 | \dim_gset:Nn \g_@@_ht_dim { \box_ht:N \l_@@_window_box } 1833 | \dim_add:Nn \l_@@_voffset_dim 1834 | { \box_ht:N \g_@@_display_box / 2 } 1835 | } 1836 | \cs_new_protected_nopar:Npn \@@_build_display_auxii: 1837 | { 1838 | \box_if_horizontal:NTF \l_@@_body_box 1839 | { 1840 | \box_set_eq:NN \l_@@_bottom_box \l_@@_body_box 1841 | \@@_build_display_auxiii: 1842 | } 1843 | { 1844 | \@@_extract_hbox:NN \l_@@_body_box \l_@@_bottom_box 1845 | \str_if_eq:eeTF 1846 | { 1847 | \dim_eval:n { \box_ht:N \l_@@_body_box } 1848 | \dim_eval:n { \box_dp:N \l_@@_body_box } 1849 | \dim_eval:n { \box_ht:N \l_@@_bottom_box } 1850 | \dim_eval:n { \box_dp:N \l_@@_bottom_box } 1851 | } 1852 | { \c_@@_zero_pt_str } 1853 | { 1854 | \vbox_unpack_drop:N \l_@@_body_box 1855 | \box_clear:N \l_@@_bottom_box 1856 | \@@_build_display_auxi: 1857 | } 1858 | { \@@_build_display_auxiii: } 1859 | } 1860 | } 1861 | \str_const:Nx \c_@@_zero_pt_str 1862 | { 1863 | \dim_use:N \c_zero_dim 1864 | \dim_use:N \c_zero_dim 1865 | \dim_use:N \c_zero_dim 1866 | \dim_use:N \c_zero_dim 1867 | } 1868 | \cs_new_protected_nopar:Npn \@@_build_display_auxiii: 1869 | { 1870 | \bool_set_true:N \l_@@_attach_equation_bool 1871 | \box_gclear:N \g_@@_display_box 1872 | \bool_if:NF \g_@@_amsmath_bool 1873 | { \@@_adjust_equation: } 1874 | \@@_build_body_box: 1875 | } 1876 | \bool_new:N \l_@@_display_bool 1877 | \bool_new:N \l_@@_attach_equation_bool 1878 | % \end{macrocode} 1879 | % \end{macro} 1880 | % 1881 | % \changes{v0.2}{2022/07/23}{改进对显示数学公式的处理。} 1882 | % 1883 | % \begin{macro}{\@@_attach_left:N,\@@_attach_right:N} 1884 | % \begin{macrocode} 1885 | \cs_new_protected:Npn \@@_attach_left:N #1 1886 | { 1887 | \@@_attach_equation:Nn #1 1888 | { \g_@@_parshape_indent_dim } 1889 | } 1890 | \cs_new_protected:Npn \@@_attach_right:N #1 1891 | { 1892 | \@@_attach_equation:Nn #1 1893 | { 1894 | \l_@@_line_dim 1895 | - \l_@@_display_dim 1896 | + \g_@@_parshape_indent_dim 1897 | } 1898 | } 1899 | \cs_new_protected:Npn \@@_attach_equation:Nn #1#2 1900 | { 1901 | \vbox_set:Nn \l_@@_last_box 1902 | { 1903 | \vbox_unpack:N #1 1904 | \box_set_to_last:N \l_@@_last_box 1905 | \bool_if:NTF \g_@@_amsmath_bool 1906 | { \@@_attach_equation_amsmath:Nn } 1907 | { \@@_attach_equation_normal:Nn } 1908 | \l_@@_last_box {#2} 1909 | } 1910 | } 1911 | \cs_new_protected:Npn \@@_attach_equation_amsmath:Nn #1#2 1912 | { 1913 | \vbox_gset:Nn \g_@@_equation_box 1914 | { 1915 | \@@_nobreak: 1916 | \skip_vertical:n 1917 | { 1918 | \g_@@_display_pre_skip 1919 | + \g_@@_display_pre_dim 1920 | - \box_dp:N #1 1921 | } 1922 | \box_move_right:nn {#2} 1923 | { \box_use_drop:N \g_@@_equation_box } 1924 | } 1925 | } 1926 | \cs_new_protected:Npn \@@_attach_equation_normal:Nn #1#2 1927 | { 1928 | \vbox_set:Nn \l_@@_last_box 1929 | { 1930 | \@@_tex_parameter: 1931 | \dim_set_eq:NN \tex_hsize:D \l_@@_display_dim 1932 | \para_raw_noindent: 1933 | \hbox_unpack_drop:N #1 \tex_unskip:D 1934 | \@@_insert_equation: 1935 | \para_raw_end: 1936 | \skip_gset_eq:NN \g_@@_pos_skip \tex_lastskip:D 1937 | \tex_unskip:D 1938 | \int_gset_eq:NN \g_@@_pos_int \tex_lastpenalty:D 1939 | \tex_unpenalty:D 1940 | \box_set_to_last:N \l_@@_last_box 1941 | \skip_set_eq:NN \l_@@_last_skip \tex_lastskip:D 1942 | \tex_unskip:D 1943 | \skip_add:Nn \l_@@_last_skip { \tex_lastskip:D } 1944 | \vbox_gset:Nn \g_@@_equation_box 1945 | { 1946 | \@@_nobreak: 1947 | \skip_vertical:N \l_@@_last_skip 1948 | \box_move_right:nn {#2} 1949 | { 1950 | \hbox_to_wd:nn 1951 | { \l_@@_display_dim } 1952 | { 1953 | \tex_hss:D 1954 | \box_use_drop:N \l_@@_last_box 1955 | \tex_hss:D 1956 | } 1957 | } 1958 | } 1959 | } 1960 | } 1961 | \cs_new_protected_nopar:Npn \@@_insert_equation: 1962 | { 1963 | \c_math_toggle_token \c_math_toggle_token 1964 | \dim_compare:nNnTF \tex_displaywidth:D = \l_@@_display_dim 1965 | { \box_use_drop:N \g_@@_equation_box } 1966 | { 1967 | \bool_if:NTF \g_@@_eqnum_bool 1968 | { \@@_repack_equation: } 1969 | { \box_use_drop:N \g_@@_equation_box } 1970 | } 1971 | \c_math_toggle_token \c_math_toggle_token 1972 | } 1973 | \cs_new_protected_nopar:Npn \@@_repack_equation: 1974 | { 1975 | \box_gclear:N \g_@@_equation_box 1976 | \box_use_drop:N \g_@@_eqbody_box 1977 | \bool_if:NTF \g_@@_leqno_bool 1978 | { \tex_leqno:D } 1979 | { \tex_eqno:D } 1980 | \box_use_drop:N \g_@@_eqnum_box 1981 | } 1982 | \cs_new_protected_nopar:Npn \@@_adjust_equation: 1983 | { 1984 | \@@_test_eqnum: 1985 | \bool_if:NT \g_@@_eqnum_bool 1986 | { \@@_adjust_equation_width: } 1987 | } 1988 | \cs_new_protected_nopar:Npn \@@_test_eqnum: 1989 | { 1990 | \hbox_set:Nn \l_@@_last_box 1991 | { 1992 | \bool_gset_false:N \g_@@_eqnum_bool 1993 | \hbox_unpack:N \g_@@_equation_box 1994 | \@@_if_last_hlist:F { \use_none_delimit_by_s_stop:w } 1995 | \box_gset_to_last:N \g_@@_eqnum_box 1996 | \@@_if_last_kern:F { \use_none_delimit_by_s_stop:w } 1997 | \tex_unkern:D 1998 | \@@_if_last_hlist:F { \use_none_delimit_by_s_stop:w } 1999 | \box_gset_to_last:N \g_@@_eqbody_box 2000 | \@@_if_last_none:F { \use_none_delimit_by_s_stop:w } 2001 | \bool_gset_true:N \g_@@_eqnum_bool 2002 | \use_none_delimit_by_s_stop:w \s_stop 2003 | } 2004 | } 2005 | \cs_new_protected_nopar:Npn \@@_adjust_equation_width: 2006 | { 2007 | \bool_if:NTF \g_@@_leqno_bool 2008 | { \@@_adjust_leqno: } 2009 | { 2010 | \box_gset_wd:Nn \g_@@_equation_box 2011 | { \box_wd:N \g_@@_eqbody_box } 2012 | } 2013 | } 2014 | \cs_new_protected_nopar:Npn \@@_adjust_leqno: 2015 | { 2016 | \box_set_eq_drop:NN \l_@@_last_box \g_@@_eqnum_box 2017 | \box_gset_eq_drop:NN \g_@@_eqnum_box \g_@@_eqbody_box 2018 | \box_gset_eq_drop:NN \g_@@_eqbody_box \l_@@_last_box 2019 | \hbox_gset:Nn \g_@@_equation_box 2020 | { 2021 | \skip_horizontal:n 2022 | { 2023 | \box_wd:N \g_@@_eqbody_box 2024 | - \box_wd:N \g_@@_equation_box 2025 | } 2026 | \box_use_drop:N \g_@@_equation_box 2027 | } 2028 | } 2029 | \box_new:N \g_@@_eqbody_box 2030 | \box_new:N \g_@@_eqnum_box 2031 | \box_new:N \g_@@_equation_box 2032 | \int_new:N \g_@@_pos_int 2033 | \skip_new:N \g_@@_pos_skip 2034 | \bool_new:N \g_@@_eqnum_bool 2035 | % \end{macrocode} 2036 | % \end{macro} 2037 | % 2038 | % \begin{macro}{\@@_add_pos_kludge:} 2039 | % \begin{macrocode} 2040 | \cs_new_protected_nopar:Npn \@@_add_pos_kludge: 2041 | { 2042 | \dim_gset:Nn \g_@@_prevdepth_dim 2043 | { \box_dp:N \l_@@_window_box } 2044 | \bool_gset_false:N \g_@@_equation_dp_bool 2045 | \bool_if:NTF \g_@@_next_bool 2046 | { 2047 | \tex_vadjust:D 2048 | { 2049 | \box_if_empty:NF \g_@@_equation_box 2050 | { \@@_output_equation_box: } 2051 | \@@_nobreak: 2052 | \bool_if:NT \l_@@_display_bool 2053 | { \skip_vertical:N \g_@@_pos_skip } 2054 | } 2055 | } 2056 | { 2057 | \bool_if:NT \l_@@_display_bool 2058 | { 2059 | \tex_vadjust:D 2060 | { 2061 | \box_if_empty:NF \g_@@_equation_box 2062 | { \@@_output_equation_box: } 2063 | \tex_penalty:D \g_@@_pos_int 2064 | \skip_vertical:N \g_@@_pos_skip 2065 | } 2066 | } 2067 | } 2068 | \int_gzero:N \g_@@_pos_int 2069 | \skip_gzero:N \g_@@_pos_skip 2070 | } 2071 | \cs_new_protected_nopar:Npn \@@_output_equation_box: 2072 | { 2073 | \cs_gset_eq:NN 2074 | \@@_para_after: 2075 | \@@_set_equation_depth: 2076 | \bool_gset_true:N \g_@@_equation_dp_bool 2077 | \dim_gset:Nn \g_@@_prevdepth_dim 2078 | { \box_dp:N \g_@@_equation_box } 2079 | \vbox_unpack_drop:N \g_@@_equation_box 2080 | } 2081 | \cs_new_protected_nopar:Npn \@@_set_equation_depth: 2082 | { 2083 | \cs_gset_eq:NN \@@_para_after: \@@_empty: 2084 | \bool_gset_false:N \g_@@_equation_dp_bool 2085 | \@@_set_prevdepth:N \g_@@_prevdepth_dim 2086 | } 2087 | \bool_new:N \g_@@_equation_dp_bool 2088 | % \end{macrocode} 2089 | % \end{macro} 2090 | % 2091 | % \begin{macro}{\@@_build_body_box:} 2092 | % \begin{macrocode} 2093 | \cs_new_protected_nopar:Npn \@@_build_body_box: 2094 | { 2095 | \box_set_eq:NN \l_@@_save_body_box \l_@@_bottom_box 2096 | \@@_build_window: 2097 | \int_compare:nNnTF \g_@@_line_int > \l_@@_window_line_int 2098 | { \@@_extract_hbox:NN \l_@@_body_box \l_@@_bottom_box } 2099 | { \box_clear:N \l_@@_bottom_box } 2100 | \box_if_empty:NF \l_@@_bottom_box 2101 | { \bool_set_false:N \l_@@_attach_equation_bool } 2102 | \box_clear:N \l_@@_window_box 2103 | \@@_build_box: 2104 | } 2105 | \box_new:N \l_@@_save_body_box 2106 | % \end{macrocode} 2107 | % \end{macro} 2108 | % 2109 | % \begin{macro}{\@@_build_body_box:} 2110 | % \begin{macrocode} 2111 | \cs_new_protected_nopar:Npn \@@_build_window: 2112 | { 2113 | \vbox_set:Nn \l_@@_body_box 2114 | { 2115 | \dim_zero:N \tex_emergencystretch:D 2116 | \dim_set_eq:NN \tex_hfuzz:D \c_max_dim 2117 | \dim_set_eq:NN \tex_vfuzz:D \c_max_dim 2118 | \int_set_eq:NN \tex_hbadness:D \c_max_int 2119 | \int_set_eq:NN \tex_vbadness:D \c_max_int 2120 | \int_set:Nn \tex_tolerance:D { 1000 } 2121 | \para_raw_noindent: 2122 | \hbox_unpack_drop:N \l_@@_bottom_box 2123 | \@@_tex_parameter: 2124 | \@@_make_parshape: 2125 | \@@_interline_penalties: 2126 | \para_raw_end: 2127 | \int_gset_eq:NN \g_@@_line_int \tex_prevgraf:D 2128 | } 2129 | } 2130 | % \end{macrocode} 2131 | % \end{macro} 2132 | % 2133 | % \begin{macro}{\@@_make_parshape:} 2134 | % \begin{macrocode} 2135 | \cs_new_protected_nopar:Npn \@@_make_parshape: 2136 | { 2137 | \tex_parshape:D 2138 | \int_eval:n { \l_@@_window_line_int + 1 } ~ 2139 | \bool_if:NTF \l_@@_hang_bool 2140 | { 2141 | \prg_replicate:nn 2142 | { \l_@@_window_int } 2143 | { \c_zero_dim \l_@@_window_dim } 2144 | } 2145 | { 2146 | \bool_if:NTF \l_@@_column_bool 2147 | { 2148 | \prg_replicate:nn 2149 | { \l_@@_window_int / 2 } 2150 | { \c_zero_dim \l_@@_l_dim } 2151 | \prg_replicate:nn 2152 | { 2153 | \bool_if:NTF \g_@@_column_bool 2154 | { \g_@@_column_int } 2155 | { \l_@@_window_int / 2 } 2156 | } 2157 | { \c_zero_dim \l_@@_r_dim } 2158 | } 2159 | { 2160 | \prg_replicate:nn 2161 | { \l_@@_window_int / 2 } 2162 | { 2163 | \c_zero_dim \l_@@_l_dim 2164 | \c_zero_dim \l_@@_r_dim 2165 | } 2166 | } 2167 | } 2168 | \c_zero_dim \c_max_dim 2169 | } 2170 | % \end{macrocode} 2171 | % \end{macro} 2172 | % 2173 | % \begin{macro}{\@@_interline_penalties:} 2174 | % \begin{macrocode} 2175 | \cs_new_protected_nopar:Npn \@@_interline_penalties: 2176 | { 2177 | \bool_if:NF \l_@@_hang_bool 2178 | { 2179 | \bool_if:NTF \l_@@_column_bool 2180 | { \@@_column_penalties: } 2181 | { \@@_block_penalties: } 2182 | } 2183 | } 2184 | \cs_new_protected_nopar:Npn \@@_column_penalties: 2185 | { 2186 | \tex_interlinepenalties:D 2187 | \int_eval:n { \l_@@_window_int / 2 + \c_one_int } ~ 2188 | \prg_replicate:nn 2189 | { \l_@@_window_int / 2 - \c_one_int } 2190 | { \c_@@_nobreak_int } 2191 | \c_@@_break_int 2192 | \c_zero_int 2193 | } 2194 | \cs_new_protected_nopar:Npn \@@_block_penalties: 2195 | { 2196 | \tex_interlinepenalties:D \l_@@_window_int 2197 | \prg_replicate:nn 2198 | { \l_@@_window_int - \c_one_int } 2199 | { \c_@@_break_int } 2200 | \c_zero_int 2201 | } 2202 | % \end{macrocode} 2203 | % \end{macro} 2204 | % 2205 | % \begin{macro}{\@@_break:,\@@_nobreak:} 2206 | % \begin{macrocode} 2207 | \cs_new_protected_nopar:Npn \@@_break: 2208 | { \tex_penalty:D \c_@@_break_int } 2209 | \cs_new_protected_nopar:Npn \@@_nobreak: 2210 | { \tex_penalty:D \c_@@_nobreak_int } 2211 | \int_const:Nn \c_@@_break_int { -10000 } 2212 | \int_const:Nn \c_@@_nobreak_int { 10000 } 2213 | % \end{macrocode} 2214 | % \end{macro} 2215 | % 2216 | % \changes{v0.2}{2022/07/22}{提高稳定性。} 2217 | % 2218 | % \begin{macro}{\@@_build_box:, \@@_build_block:} 2219 | % \begin{macrocode} 2220 | \cs_new_protected_nopar:Npn \@@_build_block: 2221 | { 2222 | \vbox_set:Nn \l_@@_window_box 2223 | { 2224 | \@@_split_parameter: 2225 | \skip_set_eq:NN \tex_baselineskip:D \g_@@_baseline_skip 2226 | \@@_build_line: 2227 | } 2228 | } 2229 | \cs_new_protected_nopar:Npn \@@_build_line: 2230 | { 2231 | \vbox_set_split_to_ht:NNn \l_@@_l_box \l_@@_body_box 2232 | { \g_@@_baseline_skip } 2233 | \vbox_set_split_to_ht:NNn \l_@@_r_box \l_@@_body_box 2234 | { \g_@@_baseline_skip } 2235 | \@@_build_line_repack: 2236 | \box_if_empty:NTF \l_@@_body_box 2237 | { \@@_put_last_line: } 2238 | { 2239 | \@@_put_line_box: 2240 | \@@_build_line: 2241 | } 2242 | } 2243 | \cs_new_protected_nopar:Npn \@@_build_line_repack: 2244 | { 2245 | \vbox_set:Nn \l_@@_l_box 2246 | { \vbox_unpack_drop:N \l_@@_l_box } 2247 | \box_if_empty:NF \l_@@_r_box 2248 | { 2249 | \vbox_set:Nn \l_@@_r_box 2250 | { \vbox_unpack_drop:N \l_@@_r_box } 2251 | } 2252 | \@@_save_first_ht: 2253 | } 2254 | \cs_new_protected_nopar:Npn \@@_put_last_line: 2255 | { 2256 | \bool_if:NT \l_@@_attach_equation_bool 2257 | { \@@_attach_left:N \l_@@_l_box } 2258 | \@@_put_line_box: 2259 | } 2260 | \cs_new_protected_nopar:Npn \@@_put_line_box: 2261 | { 2262 | \hbox_to_wd:nn { \l_@@_line_dim } 2263 | { 2264 | \box_use_drop:N \l_@@_l_box 2265 | \tex_hfil:D 2266 | \box_use_drop:N \l_@@_r_box 2267 | } 2268 | } 2269 | \cs_new_protected_nopar:Npn \@@_save_first_ht: 2270 | { 2271 | \dim_gset:Nn \g_@@_ht_dim 2272 | { 2273 | \dim_max:nn 2274 | { \box_ht:N \l_@@_l_box } 2275 | { \box_ht:N \l_@@_r_box } 2276 | } 2277 | \cs_set_eq:NN \@@_save_first_ht: \@@_empty: 2278 | } 2279 | \dim_new:N \g_@@_ht_dim 2280 | \box_new:N \l_@@_l_box 2281 | \box_new:N \l_@@_r_box 2282 | % \end{macrocode} 2283 | % \end{macro} 2284 | % 2285 | % \begin{macro}{\@@_build_column_fuzzy:} 2286 | % \begin{macrocode} 2287 | \cs_new_protected_nopar:Npn \@@_build_column_fuzzy: 2288 | { 2289 | \hbox_set_to_wd:Nnn \l_@@_window_box 2290 | { \l_@@_line_dim } 2291 | { 2292 | \@@_split_parameter: 2293 | \@@_build_column_aux: 2294 | \box_if_empty:NT \l_@@_bottom_box 2295 | { \@@_build_column_fuzzy_aux: } 2296 | \@@_repack_left_box: 2297 | \bool_if:NT \l_@@_attach_equation_bool 2298 | { \@@_attach_left:N \l_@@_l_box } 2299 | \box_use:N \l_@@_l_box 2300 | \tex_hfil:D 2301 | \box_move_up:nn 2302 | { \box_ht:N \l_@@_l_box - \box_ht:N \l_@@_r_box } 2303 | { \box_use_drop:N \l_@@_r_box } 2304 | } 2305 | } 2306 | \cs_new_protected_nopar:Npn \@@_build_column_aux: 2307 | { 2308 | \vbox_set_split_to_ht:NNn \l_@@_l_box \l_@@_body_box 2309 | { \box_ht:N \l_@@_body_box / 2 } 2310 | \vbox_set_top:Nn \l_@@_l_box 2311 | { \vbox_unpack_drop:N \l_@@_l_box } 2312 | \box_set_eq_drop:NN \l_@@_r_box \l_@@_body_box 2313 | } 2314 | \cs_new_protected_nopar:Npn \@@_build_column_fuzzy_aux: 2315 | { 2316 | \dim_compare:nNnTF 2317 | { 2318 | \box_ht_plus_dp:N \l_@@_r_box - 2319 | \box_ht_plus_dp:N \l_@@_l_box 2320 | } 2321 | > 2322 | { \l_@@_min_dim } 2323 | { 2324 | \box_if_empty:NF \l_@@_last_l_box 2325 | { 2326 | \box_set_eq_drop:NN \l_@@_l_box \l_@@_last_l_box 2327 | \box_set_eq_drop:NN \l_@@_r_box \l_@@_last_r_box 2328 | } 2329 | } 2330 | { \@@_rebuild_window: } 2331 | } 2332 | \cs_new_protected_nopar:Npn \@@_rebuild_window: 2333 | { 2334 | \int_compare:nNnT \l_@@_window_int > { 2 } 2335 | { \@@_rebuild_window_aux: } 2336 | } 2337 | \cs_new_protected_nopar:Npn \@@_rebuild_window_aux: 2338 | { 2339 | \int_sub:Nn \l_@@_window_int { 2 } 2340 | \box_set_eq_drop:NN \l_@@_last_l_box \l_@@_l_box 2341 | \box_set_eq_drop:NN \l_@@_last_r_box \l_@@_r_box 2342 | \box_set_eq:NN \l_@@_bottom_box \l_@@_save_body_box 2343 | \int_set_eq:NN \l_@@_window_line_int \l_@@_window_int 2344 | \@@_build_window: 2345 | \@@_build_column_aux: 2346 | \@@_build_column_fuzzy_aux: 2347 | } 2348 | \box_new:N \l_@@_last_l_box 2349 | \box_new:N \l_@@_last_r_box 2350 | % \end{macrocode} 2351 | % \end{macro} 2352 | % 2353 | % \begin{macro}{\@@_build_column_strict:} 2354 | % \begin{macrocode} 2355 | \cs_new_protected_nopar:Npn \@@_build_column_strict: 2356 | { 2357 | \group_begin: 2358 | \@@_split_parameter: 2359 | \@@_build_column_aux: 2360 | \box_if_empty:NTF \l_@@_r_box 2361 | { \@@_build_column_strict_auxi: } 2362 | { 2363 | \box_if_empty:NTF \l_@@_bottom_box 2364 | { \@@_build_column_strict_auxii: } 2365 | { 2366 | \bool_if:NTF \g_@@_column_bool 2367 | { \@@_build_column_strict_auxiii: } 2368 | { \@@_build_column_strict_auxiv: } 2369 | } 2370 | } 2371 | \group_end: 2372 | \box_set_eq_drop:NN \l_@@_window_box \g_@@_window_box 2373 | } 2374 | \cs_new_protected_nopar:Npn \@@_build_column_strict_auxi: 2375 | { 2376 | \@@_repack_left_box: 2377 | \bool_if:NT \l_@@_attach_equation_bool 2378 | { \@@_attach_left:N \l_@@_l_box } 2379 | \box_gset_eq_drop:NN \g_@@_window_box \l_@@_l_box 2380 | \bool_gset_true:N \g_@@_column_bool 2381 | \bool_if:NF \g_@@_first_save_bool 2382 | { 2383 | \bool_gset_true:N \g_@@_first_save_bool 2384 | \dim_gset:Nn \g_@@_first_sep_dim 2385 | { \tex_baselineskip:D - \g_@@_ht_dim } 2386 | \dim_gset_eq:NN \g_@@_first_dp_dim \g_@@_prevdepth_dim 2387 | } 2388 | \int_case:nnT { \g_@@_window_int } 2389 | { 2390 | { \c_zero_int } { } 2391 | { \g_@@_line_int } { } 2392 | } 2393 | { \@@_column_move_entire_aux: } 2394 | } 2395 | \cs_new_protected_nopar:Npn \@@_column_move_entire_aux: 2396 | { 2397 | \bool_gset_true:N \g_@@_entire_bool 2398 | \bool_gset_true:N \g_@@_next_hang_bool 2399 | } 2400 | \cs_new_protected_nopar:Npn \@@_column_move_entire: 2401 | { 2402 | \dim_gsub:Nn \g_@@_first_sep_dim 2403 | { \box_dp:N \l_@@_window_box } 2404 | \bool_gset_false:N \g_@@_entire_bool 2405 | \dim_gzero:N \g_@@_column_ht_dim 2406 | \dim_gset_eq:NN \g_@@_prevdepth_dim \g_@@_first_dp_dim 2407 | \@@_column_right_move_set:nn 2408 | { \g_@@_stuff_ht_dim } 2409 | { \g_@@_window_ht_dim } 2410 | \int_gset_eq:NN \g_@@_window_int \g_@@_column_int 2411 | } 2412 | \cs_new_protected:Npn \@@_column_right_move_set:nn #1#2 2413 | { 2414 | \bool_gset_true:N \g_@@_right_move_bool 2415 | \bool_gset_true:N \g_@@_first_set_bool 2416 | \tl_gput_right:Nn \g_@@_main_setting_tl 2417 | { 2418 | \bool_if:NTF \g_@@_first_set_bool 2419 | { 2420 | \bool_gset_false:N \g_@@_first_set_bool 2421 | \bool_set_true:N \l_@@_first_move_bool 2422 | } 2423 | { \bool_set_false:N \l_@@_first_move_bool } 2424 | \fp_zero:N \l_@@_ratio_fp 2425 | } 2426 | \@@_make_next_stuff:nn 2427 | { \l_@@_line_dim - \l_@@_r_dim - \l_@@_rightsep_dim } 2428 | {#1} 2429 | \dim_gset:Nn \g_@@_column_room_dim {#2} 2430 | \int_gzero:N \g_@@_top_int 2431 | } 2432 | \cs_new_protected_nopar:Npn \@@_build_column_strict_auxii: 2433 | { 2434 | \bool_gset_false:N \g_@@_entire_bool 2435 | \@@_repack_left_box: 2436 | \bool_if:NT \l_@@_attach_equation_bool 2437 | { \@@_attach_right:N \l_@@_r_box } 2438 | \dim_gset:Nn \g_@@_hang_ht_dim 2439 | { 2440 | \g_@@_stuff_ht_dim - \tex_baselineskip:D * 2441 | \@@_unit:n { \box_ht_plus_dp:N \l_@@_r_box } 2442 | - \box_ht_plus_dp:N \g_@@_equation_box 2443 | - \g_@@_pos_skip 2444 | } 2445 | \dim_compare:nNnTF \g_@@_hang_ht_dim > \c_zero_dim 2446 | { \@@_column_move_right: } 2447 | { \@@_column_put_right: } 2448 | \box_gset_ht:Nn \g_@@_window_box { \box_ht:N \l_@@_l_box } 2449 | \box_gset_dp:Nn \g_@@_window_box { \box_dp:N \l_@@_l_box } 2450 | } 2451 | \cs_new_protected_nopar:Npn \@@_column_move_right: 2452 | { 2453 | \int_compare:nNnTF \g_@@_window_int > \c_zero_int 2454 | { 2455 | \dim_gset:Nn \g_@@_column_room_dim 2456 | { 2457 | \g_@@_window_ht_dim 2458 | - \g_@@_first_sep_dim 2459 | - \box_ht_plus_dp:N \l_@@_r_box 2460 | - \box_ht_plus_dp:N \g_@@_equation_box 2461 | } 2462 | \@@_next_hang_para: 2463 | } 2464 | { 2465 | \dim_gset:Nn \g_@@_column_room_dim 2466 | { 2467 | \box_ht:N \l_@@_l_box 2468 | - \box_ht_plus_dp:N \l_@@_r_box 2469 | - \box_ht_plus_dp:N \g_@@_equation_box 2470 | } 2471 | \dim_gset:Nn \g_@@_first_sep_dim 2472 | { \tex_baselineskip:D - \g_@@_ht_dim } 2473 | \bool_gset_true:N \g_@@_right_move_bool 2474 | \bool_gset_true:N \g_@@_next_hang_bool 2475 | } 2476 | \hbox_gset_to_wd:Nnn \g_@@_window_box 2477 | { \l_@@_line_dim } 2478 | { 2479 | \box_use:N \l_@@_l_box 2480 | \tex_hfil:D 2481 | \box_move_up:nn 2482 | { \g_@@_column_room_dim } 2483 | { \box_use:N \l_@@_r_box } 2484 | } 2485 | \dim_gset:Nn \g_@@_column_ht_dim 2486 | { 2487 | \box_ht_plus_dp:N \l_@@_r_box 2488 | + \box_ht_plus_dp:N \g_@@_equation_box 2489 | + \g_@@_pos_skip 2490 | } 2491 | } 2492 | \cs_new_protected_nopar:Npn \@@_column_put_right: 2493 | { 2494 | \hbox_gset_to_wd:Nnn \g_@@_window_box 2495 | { \l_@@_line_dim } 2496 | { 2497 | \box_use:N \l_@@_l_box 2498 | \tex_hfil:D 2499 | \box_move_up:nn 2500 | { 2501 | \int_compare:nNnTF \g_@@_window_int > \c_zero_int 2502 | { \g_@@_window_ht_dim - \g_@@_first_sep_dim } 2503 | { \box_ht:N \l_@@_l_box } 2504 | - \box_ht:N \l_@@_r_box 2505 | } 2506 | { \box_use:N \l_@@_r_box } 2507 | } 2508 | \skip_gzero:N \g_@@_pos_skip 2509 | } 2510 | \cs_new_protected_nopar:Npn \@@_next_hang_para: 2511 | { 2512 | \bool_if:NTF \g_@@_entire_bool 2513 | { \@@_column_move_entire: } 2514 | { 2515 | \@@_column_right_move_set:nn 2516 | { \g_@@_hang_ht_dim } 2517 | { \g_@@_column_room_dim } 2518 | \int_gzero:N \g_@@_window_int 2519 | } 2520 | \bool_gset_false:N \g_@@_next_hang_bool 2521 | } 2522 | \cs_new_protected_nopar:Npn \@@_build_column_strict_auxiii: 2523 | { 2524 | \bool_gset_false:N \g_@@_column_bool 2525 | \@@_repack_left_box: 2526 | \hbox_gset_to_wd:Nnn \g_@@_window_box 2527 | { \l_@@_line_dim } 2528 | { 2529 | \box_use:N \l_@@_l_box 2530 | \tex_hfil:D 2531 | \box_use:N \l_@@_r_box 2532 | } 2533 | \box_gset_ht:Nn \g_@@_window_box 2534 | { \box_ht:N \l_@@_l_box } 2535 | } 2536 | \cs_new_protected_nopar:Npn \@@_build_column_strict_auxiv: 2537 | { 2538 | \@@_repack_left_box: 2539 | \hbox_gset_to_wd:Nnn \g_@@_window_box 2540 | { \l_@@_line_dim } 2541 | { 2542 | \box_use:N \l_@@_l_box 2543 | \tex_hfil:D 2544 | \box_move_up:nn 2545 | { \box_ht:N \l_@@_l_box - \box_ht:N \l_@@_r_box } 2546 | { \box_use_drop:N \l_@@_r_box } 2547 | } 2548 | } 2549 | \cs_new_protected_nopar:Npn \@@_repack_left_box: 2550 | { 2551 | \dim_gset:Nn \g_@@_ht_dim { \box_ht:N \l_@@_l_box } 2552 | \vbox_set:Nn \l_@@_l_box 2553 | { \vbox_unpack_drop:N \l_@@_l_box } 2554 | } 2555 | \box_new:N \g_@@_window_box 2556 | \bool_new:N \l_@@_first_move_bool 2557 | % \end{macrocode} 2558 | % \end{macro} 2559 | % 2560 | % \begin{macro}{\@@_build_box:,\@@_build_column:} 2561 | % \begin{macrocode} 2562 | \bool_new:N \l_@@_column_bool 2563 | \cs_new_eq:NN \@@_build_column: \@@_build_column_strict: 2564 | \cs_new_eq:NN \@@_build_box: \@@_build_column: 2565 | % \end{macrocode} 2566 | % \end{macro} 2567 | % 2568 | % \begin{macro}{\@@_build_hang:} 2569 | % \begin{macrocode} 2570 | \cs_new_protected_nopar:Npn \@@_build_hang: 2571 | { 2572 | \bool_if:NTF \g_@@_hangfrom_bool 2573 | { \@@_build_hangfrom: } 2574 | { 2575 | \vbox_set_top:Nn \l_@@_window_box 2576 | { \vbox_unpack:N \l_@@_body_box } 2577 | \dim_gset:Nn \g_@@_ht_dim { \box_ht:N \l_@@_window_box } 2578 | } 2579 | \box_set_eq_drop:NN \l_@@_window_box \l_@@_body_box 2580 | \bool_if:NT \l_@@_attach_equation_bool 2581 | { \@@_build_hang_attach: } 2582 | \dim_compare:nNnT \g_@@_column_room_dim > \c_zero_dim 2583 | { \@@_build_hang_move: } 2584 | } 2585 | \cs_new_protected_nopar:Npn \@@_build_hang_attach: 2586 | { 2587 | \dim_compare:nNnTF \l_@@_r_dim = \c_zero_dim 2588 | { \@@_attach_left:N \l_@@_window_box } 2589 | { \@@_attach_right:N \l_@@_window_box } 2590 | } 2591 | \cs_new_protected_nopar:Npn \@@_build_hang_move: 2592 | { 2593 | \dim_set:Nn \l_@@_shift_dim 2594 | { 2595 | \dim_max:nn 2596 | { \box_ht:N \l_@@_window_box } 2597 | { \tex_baselineskip:D * \g_@@_line_int } 2598 | + \box_ht_plus_dp:N \g_@@_equation_box 2599 | + \tex_parskip:D 2600 | } 2601 | \dim_gsub:Nn \g_@@_column_room_dim { \l_@@_shift_dim } 2602 | \dim_compare:nNnTF \g_@@_column_room_dim > \c_zero_dim 2603 | { 2604 | \box_if_empty:NTF \l_@@_bottom_box 2605 | { \bool_if:NT \g_@@_right_move_bool { \@@_set_next_hang: } } 2606 | } 2607 | { \use:n } 2608 | { 2609 | \bool_gset_false:N \g_@@_move_hang_bool 2610 | \bool_gset_false:N \g_@@_right_move_bool 2611 | } 2612 | } 2613 | \cs_new_protected_nopar:Npn \@@_set_next_hang: 2614 | { 2615 | \bool_if:NF \g_@@_move_hang_bool 2616 | { 2617 | \bool_gset_true:N \g_@@_move_hang_bool 2618 | \dim_gset_eq:NN \g_@@_hang_ht_dim \g_@@_remaining_dim 2619 | } 2620 | \dim_gsub:Nn \g_@@_hang_ht_dim { \l_@@_shift_dim } 2621 | \@@_column_right_move_set:nn 2622 | { \g_@@_hang_ht_dim } 2623 | { \g_@@_column_room_dim } 2624 | \int_gzero:N \g_@@_window_int 2625 | } 2626 | % \end{macrocode} 2627 | % \end{macro} 2628 | % 2629 | % \begin{macro}{\@@_build_hangfrom:} 2630 | % \begin{macrocode} 2631 | \cs_new_protected_nopar:Npn \@@_build_hangfrom: 2632 | { 2633 | \group_begin: 2634 | \vbox_gset:Nn \g_@@_window_box 2635 | { 2636 | \@@_break: 2637 | \vbox_unpack:N \l_@@_body_box 2638 | } 2639 | \@@_split_parameter: 2640 | \vbox_set_split_to_ht:NNn \l_@@_last_box \g_@@_window_box 2641 | { \c_zero_dim } 2642 | \dim_gset:Nn \g_@@_ht_dim 2643 | { 2644 | \g_@@_baseline_skip 2645 | - \g_@@_prevdepth_dim 2646 | - \box_ht:N \l_@@_body_box 2647 | + \box_ht:N \g_@@_window_box 2648 | } 2649 | \group_end: 2650 | \box_set_eq_drop:NN \l_@@_body_box \g_@@_window_box 2651 | } 2652 | % \end{macrocode} 2653 | % \end{macro} 2654 | % 2655 | % \changes{v0.3}{2022/07/31}{修复 stuff 深度不为零时的垂直对齐问题。} 2656 | % 2657 | % \begin{macro}{\@@_put_box:} 2658 | % \begin{macrocode} 2659 | \cs_new_protected_nopar:Npn \@@_put_box: 2660 | { 2661 | \@@_para_raw_end: 2662 | \dim_compare:nNnTF \g_@@_prevdepth_dim > \c_@@_ignore_depth_dim 2663 | { \@@_add_vskip: } 2664 | { \@@_set_vskip: } 2665 | \skip_set_eq:NN \l_@@_par_skip \tex_parskip:D 2666 | \skip_zero:N \tex_parskip:D 2667 | \dim_set:Nn \l_@@_window_ht_dim 2668 | { \box_ht_plus_dp:N \l_@@_window_box } 2669 | \bool_if:NTF \g_@@_right_move_bool 2670 | { \@@_put_box_aux: } 2671 | { 2672 | \box_if_empty:NTF \l_@@_bottom_box 2673 | { \@@_put_next_test: } 2674 | { \@@_put_box_aux: } 2675 | } 2676 | } 2677 | \dim_new:N \l_@@_window_ht_dim 2678 | \skip_new:N \l_@@_par_skip 2679 | \cs_new_protected_nopar:Npn \@@_put_next_test: 2680 | { 2681 | \box_if_empty:NF \g_@@_equation_box 2682 | { 2683 | \dim_add:Nn \l_@@_window_ht_dim 2684 | { \box_ht_plus_dp:N \g_@@_equation_box + \g_@@_pos_skip } 2685 | } 2686 | \dim_compare:nNnTF 2687 | { \g_@@_remaining_dim + \g_@@_pos_skip } > \l_@@_window_ht_dim 2688 | { \@@_set_next: } 2689 | { \@@_put_box_aux: } 2690 | } 2691 | \cs_new_protected_nopar:Npn \@@_put_box_aux: 2692 | { 2693 | \@@_output_window_box: 2694 | \box_if_empty:NTF \l_@@_bottom_box 2695 | { \@@_put_trailer_box: } 2696 | { \@@_put_bottom_box: } 2697 | } 2698 | \cs_new_protected_nopar:Npn \@@_put_trailer_box: 2699 | { 2700 | \bool_if:NTF \g_@@_next_hang_bool 2701 | { 2702 | \@@_next_hang_para: 2703 | \@@_next_para_trailer: 2704 | } 2705 | { 2706 | \bool_if:NTF \g_@@_right_move_bool 2707 | { \@@_next_para_trailer: } 2708 | { 2709 | \@@_add_pos_kludge: 2710 | \@@_put_pos_box: 2711 | \@@_clear_variable: 2712 | } 2713 | } 2714 | } 2715 | \cs_new_protected_nopar:Npn \@@_put_bottom_box: 2716 | { 2717 | \@@_para_raw_end: 2718 | \para_raw_noindent: 2719 | \hbox_unpack_drop:N \l_@@_bottom_box 2720 | \box_if_empty:NF \g_@@_equation_box 2721 | { \@@_insert_equation: } 2722 | \@@_put_pos_box: 2723 | \@@_clear_variable: 2724 | } 2725 | \cs_new_protected_nopar:Npn \@@_output_window_box: 2726 | { 2727 | \@@_hbox:n 2728 | { 2729 | \@@_put_window_box: 2730 | \bool_if:NF \g_@@_next_bool 2731 | { \@@_output_stuff_box: } 2732 | } 2733 | } 2734 | \cs_new_protected_nopar:Npn \@@_put_pos_box: 2735 | { 2736 | \box_if_empty:NF \g_@@_pos_box 2737 | { \@@_output_pos_box: } 2738 | } 2739 | \cs_new_protected_nopar:Npn \@@_output_pos_box: 2740 | { 2741 | \@@_if_last_none:F 2742 | { \@@_output_pos_box_aux: } 2743 | \hbox_unpack_drop:N \g_@@_pos_box 2744 | } 2745 | \cs_new_protected_nopar:Npn \@@_output_pos_box_aux: 2746 | { 2747 | \@@_para_raw_end: 2748 | \bool_if:NT \g_@@_equation_dp_bool 2749 | { \@@_set_equation_depth: } 2750 | \para_raw_noindent: 2751 | } 2752 | \cs_new_protected:Npn \@@_hbox:n #1 2753 | { 2754 | \para_raw_noindent: 2755 | \hbox_gset:Nn \g_@@_last_box {#1} 2756 | \box_gset_wd:Nn \g_@@_last_box { \l_@@_line_dim } 2757 | \box_use_drop:N \g_@@_last_box 2758 | } 2759 | \cs_new_protected_nopar:Npn \@@_put_window_box: 2760 | { 2761 | \dim_compare:nNnF \l_@@_l_dim > \c_zero_dim 2762 | { \skip_horizontal:n { \l_@@_line_dim - \l_@@_r_dim } } 2763 | \box_use:N \l_@@_window_box 2764 | } 2765 | \cs_new_protected_nopar:Npn \@@_output_stuff_box: 2766 | { 2767 | \hbox_gset:Nn \g_@@_stuff_box 2768 | { 2769 | \@@_parshape_kern: 2770 | \box_move_up:nn 2771 | { 2772 | \box_dp:N \g_@@_stuff_box 2773 | + \box_ht:N \l_@@_window_box 2774 | - ( \l_@@_window_ht_dim 2775 | + \box_ht_plus_dp:N \g_@@_stuff_box ) / 2 2776 | + \l_@@_voffset_dim 2777 | } 2778 | { \box_use_drop:N \g_@@_stuff_box } 2779 | } 2780 | \box_gset_ht:Nn \g_@@_stuff_box { \c_zero_dim } 2781 | \box_gset_dp:Nn \g_@@_stuff_box { \c_zero_dim } 2782 | \skip_horizontal:n 2783 | { 2784 | \dim_compare:nNnTF \l_@@_r_dim > \c_zero_dim 2785 | { 2786 | \dim_compare:nNnTF 2787 | { \box_wd:N \l_@@_window_box } 2788 | < 2789 | { \l_@@_window_dim } 2790 | { \l_@@_leftsep_dim } 2791 | { 2792 | - \l_@@_r_dim 2793 | - \l_@@_rightsep_dim 2794 | - \g_@@_stuff_wd_dim 2795 | } 2796 | } 2797 | { \l_@@_leftsep_dim } 2798 | } 2799 | \box_use_drop:N \g_@@_stuff_box 2800 | } 2801 | % \end{macrocode} 2802 | % \end{macro} 2803 | % 2804 | % \begin{macro}{\@@_add_vskip:} 2805 | % \begin{macrocode} 2806 | \cs_new_protected_nopar:Npn \@@_add_vskip: 2807 | { 2808 | \box_if_empty:NTF \g_@@_display_box 2809 | { \@@_add_vskip_auxi: } 2810 | { \@@_add_vskip_display: } 2811 | } 2812 | \cs_new_protected_nopar:Npn \@@_add_vskip_display: 2813 | { 2814 | \bool_set_true:N \l_@@_display_pre_bool 2815 | \vbox_unpack_drop:N \g_@@_display_box 2816 | \@@_ignore_depth: 2817 | } 2818 | \cs_new_protected_nopar:Npn \@@_add_vskip_auxi: 2819 | { 2820 | \dim_compare:nNnTF \tex_pagegoal:D < \c_max_dim 2821 | { \@@_add_vskip_auxii: } 2822 | { 2823 | \bool_if:NTF \g_@@_next_bool 2824 | { \@@_add_vskip_auxii: } 2825 | { \@@_add_vskip_auxiii: } 2826 | } 2827 | } 2828 | \cs_new_protected_nopar:Npn \@@_add_vskip_auxii: 2829 | { 2830 | \@@_add_vskip_auxiv: 2831 | \bool_if:NTF \l_@@_first_move_bool 2832 | { \@@_first_move_skip: } 2833 | { \skip_vertical:N \g_@@_pre_skip } 2834 | \@@_ignore_depth: 2835 | } 2836 | \cs_new_protected_nopar:Npn \@@_add_vskip_auxiii: 2837 | { 2838 | \@@_add_vskip_auxiv: 2839 | \skip_vertical:N \g_@@_pre_skip 2840 | \dim_compare:nNnTF \tex_topskip:D > \g_@@_ht_dim 2841 | { 2842 | \skip_sub:Nn \tex_topskip:D { \g_@@_ht_dim } 2843 | \tex_hrule:D height \c_zero_dim \scan_stop: 2844 | } 2845 | { \@@_ignore_depth: } 2846 | } 2847 | \cs_new_protected_nopar:Npn \@@_add_vskip_auxiv: 2848 | { 2849 | \skip_gset:Nn \g_@@_pre_skip 2850 | { 2851 | \g_@@_baseline_skip 2852 | - \g_@@_prevdepth_dim 2853 | - \g_@@_ht_dim 2854 | } 2855 | \dim_compare:nNnT \g_@@_pre_skip < \tex_lineskiplimit:D 2856 | { \skip_gset_eq:NN \g_@@_pre_skip \tex_lineskip:D } 2857 | } 2858 | \cs_new_protected_nopar:Npn \@@_first_move_skip: 2859 | { 2860 | \skip_vertical:n 2861 | { 2862 | \g_@@_first_sep_dim 2863 | - \g_@@_window_ht_dim 2864 | - \tex_parskip:D 2865 | \dim_compare:nNnT \g_@@_column_ht_dim > \c_zero_dim 2866 | { + \g_@@_column_ht_dim + \g_@@_pre_skip } 2867 | } 2868 | } 2869 | \skip_new:N \g_@@_pre_skip 2870 | \bool_new:N \l_@@_display_pre_bool 2871 | % \end{macrocode} 2872 | % \end{macro} 2873 | % 2874 | % \begin{macro}{\@@_set_vskip:} 2875 | % \begin{macrocode} 2876 | \cs_new_protected_nopar:Npn \@@_set_vskip: 2877 | { 2878 | \box_if_empty:NTF \g_@@_display_box 2879 | { 2880 | \skip_gset:Nn \g_@@_pre_skip 2881 | { \g_@@_baseline_skip - \g_@@_ht_dim } 2882 | } 2883 | { \@@_add_vskip_display: } 2884 | } 2885 | % \end{macrocode} 2886 | % \end{macro} 2887 | % 2888 | % \begin{macro}{\@@_ignore_depth:,\@@_set_prevdepth:N} 2889 | % \begin{macrocode} 2890 | \cs_new_protected_nopar:Npn \@@_ignore_depth: 2891 | { \dim_set_eq:NN \tex_prevdepth:D \c_@@_ignore_depth_dim } 2892 | \cs_new_protected_nopar:Npn \@@_set_prevdepth:N 2893 | { \dim_set_eq:NN \tex_prevdepth:D } 2894 | \dim_const:Nn \c_@@_ignore_depth_dim { -1000pt } 2895 | % \end{macrocode} 2896 | % \end{macro} 2897 | % 2898 | % \begin{macro}{\@@_set_next:} 2899 | % \begin{macrocode} 2900 | \cs_new_protected_nopar:Npn \@@_set_next: 2901 | { 2902 | \dim_set:Nn \l_@@_height_dim 2903 | { 2904 | \bool_if:NT \g_@@_next_bool { \l_@@_par_skip } 2905 | + \g_@@_pre_skip 2906 | + \l_@@_window_ht_dim 2907 | } 2908 | \dim_gadd:Nn \g_@@_total_ht_dim { \l_@@_height_dim } 2909 | \dim_set:Nn \l_@@_shift_dim 2910 | { \g_@@_remaining_dim - \l_@@_height_dim } 2911 | \dim_compare:nNnTF 2912 | { - \l_@@_shift_dim } < \l_@@_min_dim 2913 | { \@@_set_next_para: } 2914 | { \@@_set_next_output: } 2915 | } 2916 | \cs_new_protected_nopar:Npn \@@_set_next_para: 2917 | { 2918 | \int_gset:Nn \g_@@_window_int 2919 | { 2920 | \dim_compare:nNnTF \l_@@_shift_dim > \c_zero_dim 2921 | { \@@_unit:n { \l_@@_shift_dim } } 2922 | { \c_one_int } 2923 | } 2924 | \@@_set_next_verify: 2925 | \@@_output_window_box: 2926 | \@@_make_next_stuff:nn 2927 | { \g_@@_stuff_wd_dim } 2928 | { \l_@@_shift_dim } 2929 | \int_gzero:N \g_@@_top_int 2930 | \@@_next_para_trailer: 2931 | } 2932 | \cs_new_protected_nopar:Npn \@@_set_next_output: 2933 | { 2934 | \@@_output_window_box: 2935 | \@@_add_pos_kludge: 2936 | \@@_put_pos_box: 2937 | \@@_clear_variable: 2938 | } 2939 | \cs_new_protected_nopar:Npn \@@_set_next_verify: 2940 | { 2941 | \dim_set:Nn \l_@@_height_dim 2942 | { \g_@@_window_ht_dim - \g_@@_total_ht_dim - \l_@@_min_dim } 2943 | \dim_while_do:nNnn 2944 | { \tex_baselineskip:D * \g_@@_window_int + \l_@@_par_skip } 2945 | < 2946 | { \l_@@_height_dim } 2947 | { \int_gincr:N \g_@@_window_int } 2948 | \bool_if:NF \g_@@_next_bool 2949 | { 2950 | \dim_add:Nn \l_@@_window_ht_dim 2951 | { \tex_baselineskip:D * \g_@@_window_int + \l_@@_par_skip } 2952 | } 2953 | } 2954 | % \end{macrocode} 2955 | % \end{macro} 2956 | % 2957 | % \begin{macro}{\@@_next_para_trailer:} 2958 | % \begin{macrocode} 2959 | \cs_new_protected_nopar:Npn \@@_next_para_trailer: 2960 | { 2961 | \@@_add_pos_kludge: 2962 | \box_if_empty:NTF \g_@@_pos_box 2963 | { \@@_next_para: } 2964 | { 2965 | \@@_env_begin: 2966 | \hbox_unpack_drop:N \g_@@_pos_box 2967 | \@@_env_end: 2968 | } 2969 | } 2970 | % \end{macrocode} 2971 | % \end{macro} 2972 | % 2973 | % \begin{macro}{\@@_make_next_stuff:nn} 2974 | % \begin{macrocode} 2975 | \cs_new_protected:Npn \@@_make_next_stuff:nn #1#2 2976 | { 2977 | \bool_gset_true:N \g_@@_next_bool 2978 | \dim_gset:Nn \g_@@_stuff_wd_dim {#1} 2979 | \dim_gset:Nn \g_@@_remaining_dim {#2} 2980 | } 2981 | % \end{macrocode} 2982 | % \end{macro} 2983 | % 2984 | % \begin{macro}{\@@_extract_hbox:NN} 2985 | % \begin{macrocode} 2986 | \cs_new_protected:Npn \@@_extract_display_hbox:NN #1 2987 | { 2988 | \box_gclear:N \g_@@_pos_box 2989 | \vbox_set:Nn #1 2990 | { 2991 | \vbox_unpack_drop:N #1 2992 | \bool_if:NTF \g_@@_display_bool 2993 | { \@@_test_display_math: } 2994 | { \box_gclear:N \g_@@_display_box } 2995 | \box_if_empty:NTF \g_@@_display_box 2996 | { 2997 | \bool_gset_false:N \g_@@_amsmath_bool 2998 | \@@_extract_last_hbox:N \g_@@_last_box 2999 | } 3000 | { \box_gclear:N \g_@@_last_box } 3001 | } 3002 | \box_if_empty:NF \g_@@_display_box 3003 | { \dim_gset:Nn \g_@@_display_pre_dim { \box_dp:N #1 } } 3004 | \@@_extract_hbox_aux:N 3005 | } 3006 | \cs_new_protected:Npn \@@_extract_hbox:NN #1 3007 | { 3008 | \vbox_set:Nn #1 3009 | { 3010 | \vbox_unpack_drop:N #1 3011 | \@@_extract_last_hbox:N \g_@@_last_box 3012 | } 3013 | \@@_extract_hbox_aux:N 3014 | } 3015 | \cs_new_protected:Npn \@@_extract_hbox_aux:N #1 3016 | { 3017 | \box_if_empty:NTF \g_@@_last_box 3018 | { \box_clear:N #1 } 3019 | { \@@_repack_hbox:N #1 } 3020 | } 3021 | \cs_new_protected:Npn \@@_repack_hbox:N #1 3022 | { 3023 | \hbox_set:Nn #1 3024 | { 3025 | \skip_if_eq:nnF 3026 | { \g_@@_main_left_skip } { \c_zero_skip } 3027 | { \skip_horizontal:N \g_@@_main_left_skip } 3028 | \hbox_unpack_drop:N \g_@@_last_box 3029 | \tex_unskip:D \tex_unskip:D \tex_unpenalty:D 3030 | } 3031 | } 3032 | \cs_new_protected:Npn \@@_extract_last_hbox:N #1 3033 | { 3034 | \@@_if_last_hlist:TF 3035 | { 3036 | \box_gset_to_last:N #1 3037 | \tex_unskip:D 3038 | } 3039 | { \box_gclear:N #1 } 3040 | } 3041 | \box_new:N \g_@@_last_box 3042 | \box_new:N \g_@@_display_box 3043 | \dim_new:N \g_@@_display_pre_dim 3044 | % \end{macrocode} 3045 | % \end{macro} 3046 | % 3047 | % \begin{macro}{\@@_test_display_math:} 3048 | % \begin{macrocode} 3049 | \cs_new_protected_nopar:Npn \@@_test_display_math: 3050 | { 3051 | \@@_if_last_hlist:T { \@@_extract_pos_hbox: } 3052 | \box_clear:N \l_@@_add_box 3053 | \box_gclear:N \g_@@_display_box 3054 | \skip_gzero:N \g_@@_last_skip 3055 | \skip_gzero:N \g_@@_display_pre_skip 3056 | \bool_gset_false:N \g_@@_amsmath_bool 3057 | \@@_add_last_skip:w 3058 | \@@_add_last_penalty:w 3059 | \@@_add_last_box:w 3060 | \@@_add_last_skip:w 3061 | \@@_add_last_skip:w 3062 | \@@_add_last_penalty:w 3063 | \@@_add_last_finalise:w \s_stop 3064 | } 3065 | \cs_new_protected_nopar:Npn \@@_extract_pos_hbox: 3066 | { 3067 | \box_gset_to_last:N \g_@@_last_box 3068 | \@@_repack_hbox:N \l_@@_last_box 3069 | \box_gset_eq_drop:NN \g_@@_pos_box \l_@@_last_box 3070 | \tex_unskip:D 3071 | } 3072 | \box_new:N \l_@@_add_box 3073 | \box_new:N \g_@@_pos_box 3074 | % \end{macrocode} 3075 | % \end{macro} 3076 | % 3077 | % \begin{macro}{\@@_add_last_stop:w} 3078 | % \begin{macrocode} 3079 | \cs_new_protected_nopar:Npn \@@_add_last_stop:w 3080 | { 3081 | \vbox_unpack_drop:N \l_@@_add_box 3082 | \use_none_delimit_by_s_stop:w 3083 | } 3084 | % \end{macrocode} 3085 | % \end{macro} 3086 | % 3087 | % \begin{macro}{\@@_add_last_skip:w} 3088 | % \begin{macrocode} 3089 | \cs_new_protected_nopar:Npn \@@_add_last_skip:w 3090 | { 3091 | \@@_if_last_glue:TF 3092 | { 3093 | \skip_set_eq:NN \l_@@_last_skip \tex_lastskip:D 3094 | \vbox_set:Nn \l_@@_add_box 3095 | { 3096 | \skip_vertical:N \l_@@_last_skip 3097 | \vbox_unpack_drop:N \l_@@_add_box 3098 | } 3099 | \tex_unskip:D 3100 | \skip_gadd:Nn \g_@@_last_skip { \l_@@_last_skip } 3101 | } 3102 | { \@@_skip_stop:w } 3103 | } 3104 | \skip_new:N \l_@@_last_skip 3105 | \skip_new:N \g_@@_last_skip 3106 | \cs_new_eq:NN \@@_skip_stop:w \@@_add_last_stop:w 3107 | % \end{macrocode} 3108 | % \end{macro} 3109 | % 3110 | % \begin{macro}{\@@_add_last_penalty:w} 3111 | % \begin{macrocode} 3112 | \cs_new_protected_nopar:Npn \@@_add_last_penalty:w 3113 | { 3114 | \@@_if_last_penalty:TF 3115 | { 3116 | \int_set_eq:NN \l_@@_last_int \tex_lastpenalty:D 3117 | \vbox_set:Nn \l_@@_add_box 3118 | { 3119 | \tex_penalty:D \l_@@_last_int 3120 | \vbox_unpack_drop:N \l_@@_add_box 3121 | } 3122 | \tex_unpenalty:D 3123 | \skip_gset_eq:NN \g_@@_pre_skip \g_@@_last_skip 3124 | \skip_gzero:N \g_@@_last_skip 3125 | } 3126 | { \@@_penalty_stop:w } 3127 | } 3128 | \int_new:N \l_@@_last_int 3129 | \cs_new_eq:NN \@@_penalty_stop:w \@@_add_last_stop:w 3130 | % \end{macrocode} 3131 | % \end{macro} 3132 | % 3133 | % \begin{macro}{\@@_add_last_box:w} 3134 | % \begin{macrocode} 3135 | \cs_new_protected_nopar:Npn \@@_add_last_box:w 3136 | { 3137 | \@@_if_last_hlist:TF 3138 | { 3139 | \skip_gzero:N \g_@@_last_skip 3140 | \box_set_to_last:N \l_@@_last_box 3141 | \vbox_set:Nn \l_@@_add_box 3142 | { 3143 | \box_use_drop:N \l_@@_last_box 3144 | \vbox_unpack_drop:N \l_@@_add_box 3145 | } 3146 | } 3147 | { \@@_box_stop:w } 3148 | } 3149 | \box_new:N \l_@@_last_box 3150 | \cs_new_eq:NN \@@_box_stop:w \@@_add_last_stop:w 3151 | % \end{macrocode} 3152 | % \end{macro} 3153 | % 3154 | % \begin{macro}{\@@_add_last_finalise:w} 3155 | % \begin{macrocode} 3156 | \cs_new_protected_nopar:Npn \@@_add_last_finalise:w 3157 | { 3158 | \int_gset_eq:NN \g_@@_display_pre_int \l_@@_last_int 3159 | \skip_gadd:Nn \g_@@_display_pre_skip { \g_@@_pre_skip } 3160 | \int_case:nnTF { \tex_lastnodetype:D } 3161 | { 3162 | { \c_@@_hlist_node } { } 3163 | { \c_@@_none_node } { } 3164 | { \c_@@_whatsit_node } { } 3165 | } 3166 | { \box_gset_eq_drop:NN \g_@@_display_box \l_@@_add_box } 3167 | { \vbox_unpack_drop:N \l_@@_add_box } 3168 | \use_none_delimit_by_s_stop:w 3169 | } 3170 | \int_new:N \g_@@_display_pre_int 3171 | \skip_new:N \g_@@_display_pre_skip 3172 | % \end{macrocode} 3173 | % \end{macro} 3174 | % 3175 | % \begin{macro}{\@@_amsmath_boot:w,\@@_amsmath_recursion:w,\@@_amsmath_multline:w} 3176 | % \pkg{amsmath} 的 \env{align} 等数学环境内部是一个 \tn{halign} 环境,结构不一样,需要另外处理。 3177 | % \begin{macrocode} 3178 | \cs_new_protected_nopar:Npn \@@_amsmath_boot:w 3179 | { 3180 | \@@_add_last_skip:w 3181 | \@@_add_last_penalty:w 3182 | \cs_set_eq:NN \@@_box_stop:w \@@_add_last_stop:w 3183 | \@@_add_last_box:w 3184 | \bool_gset_true:N \g_@@_amsmath_bool 3185 | \cs_set_eq:NN \@@_skip_stop:w \@@_amsmath_multline:w 3186 | \cs_set_eq:NN \@@_penalty_stop:w \@@_amsmath_stop:NN 3187 | \@@_amsmath_recursion:w 3188 | } 3189 | \cs_new_protected_nopar:Npn \@@_amsmath_recursion:w 3190 | { 3191 | \@@_add_last_skip:w 3192 | \@@_add_last_skip:w 3193 | \@@_add_last_penalty:w 3194 | \@@_add_last_box:w 3195 | \@@_amsmath_recursion:w 3196 | } 3197 | \cs_new_protected:Npn \@@_amsmath_stop:NN #1#2 3198 | { 3199 | \cs_set_eq:NN \@@_skip_stop:w \@@_add_last_stop:w 3200 | \cs_set_eq:NN \@@_penalty_stop:w \@@_add_last_stop:w 3201 | } 3202 | \bool_new:N \g_@@_amsmath_bool 3203 | % \end{macrocode} 3204 | % \end{macro} 3205 | % 3206 | % \begin{macro}{\@@_amsmath_multline:w} 3207 | % \env{multline} 环境的结构与其他环境不一样。\pkg{amsmath} 的 \tn{@display@init} 定义为 3208 | % \begin{verbatim} 3209 | % \def\@display@init#1{% 3210 | % \global\dt@ptrue \spread@equation 3211 | % \everycr{% 3212 | % \noalign{% 3213 | % #1% 3214 | % \ifdt@p 3215 | % \global\dt@pfalse 3216 | % \vskip-\lineskiplimit 3217 | % \vskip\normallineskiplimit 3218 | % \else 3219 | % \penalty\@eqpen \global\dspbrk@lvl\m@ne 3220 | % \fi 3221 | % }% 3222 | % }% 3223 | % } 3224 | % \end{verbatim} 3225 | % \env{align} 等环境的开头 \tn{ifdt@p} 为真,会插入两个 \tn{vskip}, 3226 | % 但是 \env{multline} 定义中的 \tn{mmeasure@} 没有重定义 \tn{everycr}, 3227 | % 上述定义中的 \tn{dt@pfalse} 被执行,导致环境开头被加入了 \tn{penalty}, 3228 | % 不确定是有意为之还是疏忽^^A 3229 | % \footnote{\url{https://github.com/latex3/latex2e/issues/793}}。 3230 | % \begin{macrocode} 3231 | \cs_new_protected_nopar:Npn \@@_amsmath_multline:w 3232 | { 3233 | \@@_amsmath_stop:NN ? ? 3234 | \@@_add_last_penalty:w 3235 | \skip_gset_eq:NN \g_@@_display_pre_skip 3236 | \g_@@_pre_skip 3237 | \@@_add_last_skip:w 3238 | \@@_add_last_penalty:w 3239 | \@@_add_last_finalise:w 3240 | } 3241 | % \end{macrocode} 3242 | % \end{macro} 3243 | % 3244 | % \begin{macro}{\@@_amsmath_leqno:} 3245 | % \pkg{amsmath} 的 \opt{leqno} 是直接用 \cs{tex_leqno:D} 实现的,与 \LaTeX\ 的实现不一样。 3246 | % \begin{macrocode} 3247 | \cs_new_protected_nopar:Npn \@@_amsmath_leqno: 3248 | { 3249 | \legacy_if:nTF { tagsleft@ } 3250 | { \bool_gset_true:N \g_@@_leqno_bool } 3251 | { \bool_gset_false:N \g_@@_leqno_bool } 3252 | } 3253 | % \end{macrocode} 3254 | % \end{macro} 3255 | % 3256 | % \begin{macrocode} 3257 | \@@_package_hook:nn { amsmath } 3258 | { 3259 | \cs_gset_eq:NN \@@_box_stop:w 3260 | \@@_amsmath_boot:w 3261 | \cs_gset_eq:NN \@@_test_leqno: 3262 | \@@_amsmath_leqno: 3263 | } 3264 | % \end{macrocode} 3265 | % 3266 | % \begin{macro}{\@@_set_float:} 3267 | % \begin{macrocode} 3268 | \cs_new_protected_nopar:Npn \@@_set_float: 3269 | { 3270 | \cs_set_eq:NN \@captype \l_@@_type_tl 3271 | \@@_float_pre_hook: 3272 | \@@_caption_hook: 3273 | \@floatboxreset 3274 | } 3275 | % \end{macrocode} 3276 | % \end{macro} 3277 | % 3278 | % \begin{macro}{\@@_float_pre_hook:, \@@_float_pos_hook:} 3279 | % \begin{macrocode} 3280 | \cs_new_eq:NN \@@_float_pre_hook: \@@_empty: 3281 | \cs_new_eq:NN \@@_float_pos_hook: \@@_empty: 3282 | \@@_package_hook:nn { float } 3283 | { 3284 | \bool_new:N \g_@@_float_pos_bool 3285 | \cs_gset_protected_nopar:Npn \@@_float_pre_hook: 3286 | { \exp_args:No \@@_float_pre_aux:n { \l_@@_type_tl } } 3287 | \cs_new_protected:Npn \@@_float_pre_aux:n #1 3288 | { 3289 | \cs_if_exist_use:cTF { fst@ #1 } 3290 | { 3291 | \@float@setevery {#1} 3292 | \bool_gset_true:N \g_@@_float_pos_bool 3293 | } 3294 | { \bool_gset_false:N \g_@@_float_pos_bool } 3295 | } 3296 | \cs_gset_protected_nopar:Npn \@@_float_pos_hook: 3297 | { 3298 | \bool_if:NT \g_@@_float_pos_bool 3299 | { \exp_args:No \@@_float_pos_aux:n { \l_@@_type_tl } } 3300 | } 3301 | \cs_new_protected:Npn \@@_float_pos_aux:n #1 3302 | { 3303 | \hbox_gset:Nn \g_@@_stuff_box 3304 | { 3305 | \use:c { fst@ #1 } 3306 | \cs_set_eq:NN \@currbox \g_@@_stuff_box 3307 | \vbox_gset:Nn \g_@@_stuff_box 3308 | { \box_use_drop:N \g_@@_stuff_box } 3309 | \exp_args:Ne \float@makebox 3310 | { \dim_eval:n { \box_wd:N \g_@@_stuff_box } } 3311 | } 3312 | } 3313 | } 3314 | % \end{macrocode} 3315 | % \end{macro} 3316 | % 3317 | % \begin{macro}{\@@_floatrow_hook:} 3318 | % \begin{macrocode} 3319 | \cs_new_eq:NN \@@_floatrow_hook: \@@_empty: 3320 | \@@_package_hook:nn { floatrow } 3321 | { 3322 | \cs_gset_protected_nopar:Npn \@@_floatrow_hook: 3323 | { 3324 | \cs_set_eq:NN \@captype \l_@@_type_tl 3325 | \killfloatstyle 3326 | \FR@redefs 3327 | \dim_zero:N \FBc@wd 3328 | \exp_args:Ne \flrow@setlist 3329 | { 3330 | { \l_@@_type_tl } 3331 | { wrapfloat } 3332 | { wrap \l_@@_type_tl } 3333 | } 3334 | \FRifFBOX \@@@@setframe \relax \@@@@FStrue 3335 | \hbox_gset:Nw \g_@@_stuff_box 3336 | \tl_set:Nx \FBB@wd { \dim_use:N \l_@@_width_dim } 3337 | \FB@fs@wd 3338 | \dim_set:Nn \l_@@_width_dim { \FBo@wd } 3339 | } 3340 | \cs_gset_protected_nopar:Npn \@@_float_pre_hook: 3341 | { \the \FR@everyfloat } 3342 | \cs_gset_protected_nopar:Npn \@@_float_pos_hook: 3343 | { 3344 | \legacy_if:nTF { FBbuild } 3345 | { 3346 | \cs_set_eq:NN \@currbox \g_@@_stuff_box 3347 | \vbox_gset:Nn \g_@@_stuff_box 3348 | { \box_use_drop:N \g_@@_stuff_box } 3349 | \flrow@FB { \l_@@_width_dim } 3350 | } 3351 | { 3352 | \cs_undefine:N \flrow@typ@tmpset 3353 | \box_use_drop:N \g_@@_stuff_box 3354 | } 3355 | \hbox_gset_end: 3356 | } 3357 | } 3358 | % \end{macrocode} 3359 | % \end{macro} 3360 | % 3361 | % \begin{macro}{\@@_caption_hook:} 3362 | % \begin{macrocode} 3363 | \cs_new_eq:NN \@@_caption_hook: \@@_empty: 3364 | \@@_package_hook:nn { caption } 3365 | { 3366 | \cs_gset_protected_nopar:Npn \@@_caption_hook: 3367 | { \exp_args:No \@@_caption_aux:n { \l_@@_type_tl } } 3368 | \cs_new_protected:Npn \@@_caption_aux:n #1 3369 | { 3370 | \caption@settype {#1} 3371 | \caption@clearmargin 3372 | \caption@setoptions { wrap #1 } 3373 | } 3374 | } 3375 | % \end{macrocode} 3376 | % \end{macro} 3377 | % 3378 | % \begin{macro}{top} 3379 | % \begin{macrocode} 3380 | \keys_define:nn { wrapstuff } 3381 | { 3382 | abovesep .tl_set:N = \l_@@_abovesep_tl , 3383 | belowsep .tl_set:N = \l_@@_belowsep_tl , 3384 | leftsep .tl_set:N = \l_@@_leftsep_tl , 3385 | rightsep .tl_set:N = \l_@@_rightsep_tl , 3386 | linewidth .tl_set:N = \l_@@_linewidth_tl , 3387 | lines .tl_set:N = \l_@@_lines_tl , 3388 | width .tl_set:N = \l_@@_width_tl , 3389 | height .tl_set:N = \l_@@_height_tl , 3390 | hoffset .tl_set:N = \l_@@_hoffset_tl , 3391 | voffset .tl_set:N = \l_@@_voffset_tl , 3392 | type .tl_set:N = \l_@@_type_tl , 3393 | ratio .fp_set:N = \l_@@_ratio_fp , 3394 | top .int_set:N = \l_@@_top_int , 3395 | i .code:n = \@@_swap_true:N \c_true_bool , 3396 | o .code:n = \@@_swap_true:N \c_false_bool , 3397 | l .code:n = \@@_swap_false:N \c_zero_fp , 3398 | r .code:n = \@@_swap_false:N \c_one_fp , 3399 | c .code:n = \@@_swap_false:N \c_@@_c_fp , 3400 | column .choice: , 3401 | column/true .code:n = 3402 | { 3403 | \bool_set_true:N \l_@@_column_bool 3404 | \cs_set_eq:NN \@@_build_column: 3405 | \@@_build_column_strict: 3406 | } , 3407 | column/par .code:n = 3408 | { 3409 | \bool_set_true:N \l_@@_column_bool 3410 | \cs_set_eq:NN \@@_build_column: 3411 | \@@_build_column_fuzzy: 3412 | } , 3413 | column/false .code:n = 3414 | { \bool_set_false:N \l_@@_column_bool } , 3415 | hsep .code:n = 3416 | { 3417 | \tl_set:Nn \l_@@_leftsep_tl {#1} 3418 | \tl_set_eq:NN \l_@@_rightsep_tl 3419 | \l_@@_leftsep_tl 3420 | } , 3421 | vsep .code:n = 3422 | { 3423 | \tl_set:Nn \l_@@_abovesep_tl {#1} 3424 | \tl_set_eq:NN \l_@@_belowsep_tl 3425 | \l_@@_abovesep_tl 3426 | } , 3427 | unknown .code:n = 3428 | { \exp_args:No \@@_unknown_key:n { \l_keys_key_str } } , 3429 | leftsep .groups:n = main , 3430 | rightsep .groups:n = main , 3431 | hsep .groups:n = main , 3432 | linewidth .groups:n = main , 3433 | lines .groups:n = main , 3434 | column .groups:n = main , 3435 | hoffset .groups:n = main , 3436 | voffset .groups:n = main , 3437 | top .groups:n = stuff , 3438 | abovesep .groups:n = stuff , 3439 | belowsep .groups:n = stuff , 3440 | vsep .groups:n = stuff , 3441 | width .groups:n = stuff , 3442 | height .groups:n = stuff , 3443 | float .groups:n = stuff , 3444 | ratio .groups:n = ratio , 3445 | l .groups:n = ratio , 3446 | r .groups:n = ratio , 3447 | c .groups:n = ratio , 3448 | i .groups:n = ratio , 3449 | o .groups:n = ratio , 3450 | column .default:n = true , 3451 | column .initial:n = true , 3452 | abovesep .initial:n = \c_zero_dim , 3453 | belowsep .initial:n = \c_zero_dim , 3454 | leftsep .initial:n = 1em , 3455 | rightsep .initial:n = 1em , 3456 | linewidth .initial:n = \linewidth , 3457 | hoffset .initial:n = \c_zero_dim , 3458 | voffset .initial:n = \c_zero_dim , 3459 | width .initial:n = \c_zero_dim , 3460 | height .initial:n = \c_zero_dim , 3461 | ratio .initial:n = \c_one_fp , 3462 | abovesep .value_required:n = true , 3463 | belowsep .value_required:n = true , 3464 | leftsep .value_required:n = true , 3465 | rightsep .value_required:n = true , 3466 | linewidth .value_required:n = true , 3467 | width .value_required:n = true , 3468 | height .value_required:n = true , 3469 | hoffset .value_required:n = true , 3470 | voffset .value_required:n = true , 3471 | hsep .value_required:n = true , 3472 | vsep .value_required:n = true , 3473 | l .value_forbidden:n = true , 3474 | r .value_forbidden:n = true , 3475 | c .value_forbidden:n = true , 3476 | i .value_forbidden:n = true , 3477 | o .value_forbidden:n = true 3478 | } 3479 | \fp_const:Nn \c_@@_c_fp { 0.5 } 3480 | \cs_new_protected:Npn \@@_swap_true:N #1 3481 | { 3482 | \bool_set_true:N \l_@@_swap_bool 3483 | \bool_set_eq:NN \l_@@_inner_bool #1 3484 | \bool_if:NTF \l_@@_inner_bool 3485 | { \bool_set_false:N \l_@@_outer_bool } 3486 | { \bool_set_true:N \l_@@_outer_bool } 3487 | } 3488 | \cs_new_protected_nopar:Npn \@@_swap_false:N 3489 | { 3490 | \bool_set_false:N \l_@@_swap_bool 3491 | \fp_set_eq:NN \l_@@_ratio_fp 3492 | } 3493 | \cs_new_protected:Npn \@@_unknown_key:n #1 3494 | { 3495 | \regex_match:NnTF \c_@@_integer_regex {#1} 3496 | { \int_set:Nn \l_@@_top_int } 3497 | { \@@_unknown_key_error:n } 3498 | {#1} 3499 | } 3500 | \regex_const:Nn \c_@@_integer_regex { \A \d+ \Z } 3501 | \cs_new_protected_nopar:Npn \@@_unknown_key_error:n 3502 | { \msg_error:nnn { wstf } { unknown-key } } 3503 | \msg_new:nnnn { wstf } { unknown-key } 3504 | { The~key~"#1"~is~unknown~and~is~being~ignored. } 3505 | { 3506 | The~package~wrapstuff~does~not~have~a~key~called~"#1".\\ 3507 | Check~that~you~have~spelled~the~key~name~correctly. 3508 | } 3509 | % \end{macrocode} 3510 | % \end{macro} 3511 | % 3512 | % \begin{macro}{\wrapstuffset} 3513 | % \begin{macrocode} 3514 | \NewDocumentCommand \wrapstuffset { m } 3515 | { \keys_set:nn { wrapstuff } {#1} } 3516 | % \end{macrocode} 3517 | % \end{macro} 3518 | % 3519 | % \begin{macro}{\wrapstuffclear} 3520 | % 保险起见,加入 \tn{par} 结束段落,同时结束 \env{wrapstuff@par} 环境。 3521 | % \begin{macrocode} 3522 | \NewDocumentCommand \wrapstuffclear { } 3523 | { 3524 | \par 3525 | \@@_clear: 3526 | } 3527 | % \end{macrocode} 3528 | % \end{macro} 3529 | % 3530 | % \begin{macrocode} 3531 | \cs_if_exist:NTF \ProcessKeyOptions 3532 | { \ProcessKeyOptions [ wrapstuff ] } 3533 | { 3534 | \RequirePackage { l3keys2e } 3535 | \ProcessKeysOptions { wrapstuff } 3536 | } 3537 | % \end{macrocode} 3538 | % 3539 | % \begin{macrocode} 3540 | % 3541 | % \end{macrocode} 3542 | % 3543 | % \end{implementation} 3544 | % 3545 | % \Finale 3546 | % 3547 | \endinput 3548 | --------------------------------------------------------------------------------