sequoia-man-0.3.2/.cargo_vcs_info.json0000644000000001360000000000100132550ustar { "git": { "sha1": "5a21c63ab33e86477c286271bff5c3eae7e7dc53" }, "path_in_vcs": "" }sequoia-man-0.3.2/.gitignore000064400000000000000000000000321046102023000140300ustar 00000000000000/target *~ .dir-locals*.elsequoia-man-0.3.2/.gitlab-ci.yml000064400000000000000000000012521046102023000145010ustar 00000000000000stages: - test - deploy cache: &general_cache_config # default key is default # default policy is pull-push paths: - target/ - $CARGO_HOME test-trixie: stage: test image: jampot.sequoia-pgp.org/sequoia-pgp/build-docker-image/trixie:latest before_script: - if [ -d target ]; then find target | wc --lines; du -sh target; fi - if [ -d cargo ]; then find cargo | wc --lines; du -sh $CARGO_HOME; fi - rustc --version - cargo --version after_script: - du -sh target - du -sh $CARGO_HOME cache: # inherit all general cache settings <<: *general_cache_config # override the key key: "trixie" script: - cargo test sequoia-man-0.3.2/Cargo.lock0000644000000226610000000000100112370ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "anstream" version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", "once_cell", "windows-sys", ] [[package]] name = "anyhow" version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" [[package]] name = "bitflags" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", "clap_derive", ] [[package]] name = "clap_builder" version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstream", "anstyle", "clap_lex", "strsim", ] [[package]] name = "clap_derive" version = "4.5.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" dependencies = [ "heck", "proc-macro2", "quote", "syn", ] [[package]] name = "clap_lex" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "errno" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", "windows-sys", ] [[package]] name = "fastrand" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "getrandom" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ "cfg-if", "libc", "wasi", "windows-targets", ] [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "is_terminal_polyfill" version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "libc" version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "linux-raw-sys" version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "once_cell" version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "proc-macro2" version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] [[package]] name = "roff" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88f8660c1ff60292143c98d08fc6e2f654d722db50410e3f3797d40baaf9d8f3" [[package]] name = "rustix" version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys", ] [[package]] name = "sequoia-man" version = "0.3.2" dependencies = [ "anyhow", "clap", "roff", "tempfile", ] [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "tempfile" version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", "fastrand", "getrandom", "once_cell", "rustix", "windows-sys", ] [[package]] name = "unicode-ident" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "wasi" version = "0.13.3+wasi-0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" dependencies = [ "wit-bindgen-rt", ] [[package]] name = "windows-sys" version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", "windows_i686_gnu", "windows_i686_gnullvm", "windows_i686_msvc", "windows_x86_64_gnu", "windows_x86_64_gnullvm", "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-bindgen-rt" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" dependencies = [ "bitflags", ] sequoia-man-0.3.2/Cargo.toml0000644000000027430000000000100112610ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" rust-version = "1.79" name = "sequoia-man" version = "0.3.2" authors = [ "Justus Winter ", "Lars Wirzenius ", "Neal H. Walfield ", ] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "Man page generation for Sequoia PGP CLIs" homepage = "https://sequoia-pgp.org/" documentation = "https://docs.rs/sequoia-man" readme = "README.md" keywords = [ "cli", "library", "format", ] categories = ["command-line-interface"] license = "LGPL-2.0-or-later" repository = "https://gitlab.com/sequoia-pgp/sequoia-man" [badges.gitlab] repository = "sequoia-pgp/sequoia-man" [badges.maintenance] status = "actively-developed" [lib] name = "sequoia_man" path = "src/lib.rs" [dependencies.anyhow] version = "1" [dependencies.clap] version = "4" features = [ "derive", "env", ] [dependencies.roff] version = "0.2.1" [dev-dependencies.tempfile] version = "3" sequoia-man-0.3.2/Cargo.toml.orig000064400000000000000000000014551046102023000147410ustar 00000000000000[package] name = "sequoia-man" description = "Man page generation for Sequoia PGP CLIs" version = "0.3.2" authors = [ "Justus Winter ", "Lars Wirzenius ", "Neal H. Walfield ", ] documentation = "https://docs.rs/sequoia-man" homepage = "https://sequoia-pgp.org/" repository = "https://gitlab.com/sequoia-pgp/sequoia-man" readme = "README.md" keywords = ["cli", "library", "format"] categories = ["command-line-interface"] license = "LGPL-2.0-or-later" edition = "2021" rust-version = "1.79" [badges] gitlab = { repository = "sequoia-pgp/sequoia-man" } maintenance = { status = "actively-developed" } [dependencies] anyhow = "1" clap = { version = "4", features = ["derive", "env"] } roff = "0.2.1" [dev-dependencies] tempfile = "3" sequoia-man-0.3.2/LICENSE.txt000064400000000000000000000627341046102023000137040ustar 00000000000000Sequoia-git is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Sequoia-git is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. --- GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Library General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! sequoia-man-0.3.2/README.md000064400000000000000000000004201046102023000133200ustar 00000000000000A helper library used by [Sequoia PGP]'s various CLIs to generate man pages. [Sequoia PGP]: https://sequoia-pgp.org If you're a developer and considering using this, please don't. Really. Instead, consider using [`clap_mangen`](https://crates.io/crates/clap_mangen). sequoia-man-0.3.2/openpgp-policy.toml000064400000000000000000003100251046102023000157100ustar 00000000000000version = 0 commit_goodlist = [] [authorization.dvn] sign_commit = true keyring = """ -----BEGIN PGP PUBLIC KEY BLOCK----- Comment: 0CC0 11A7 C3DC 6EB4 7567 9BC9 AC0A BA31 866A 7E76 Comment: Devan Carpenter Comment: dvn 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 /g== =nP6D -----END PGP PUBLIC KEY BLOCK----- """ [authorization.justus] sign_commit = true keyring = """ -----BEGIN PGP PUBLIC KEY BLOCK----- Comment: D2F2 C5D4 5BE9 FDE6 A4EE 0AAF 3185 5247 6038 31FD Comment: Justus Winter (Code Signing Key) Comment: Justus Winter Comment: Justus Winter Comment: Justus Winter Comment: Justus Winter Comment: Justus Winter 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 =BwBn -----END PGP PUBLIC KEY BLOCK----- """ [authorization.neal] sign_commit = true keyring = """ -----BEGIN PGP PUBLIC KEY BLOCK----- Comment: F717 3B3C 7C68 5CD9 ECC4 191B 74E4 45BA 0E15 C957 Comment: Neal H. Walfield (Code Signing Key) Comment: Neal H. Walfield Comment: Neal H. Walfield Comment: Neal H. Walfield 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 =DRsl -----END PGP PUBLIC KEY BLOCK----- """ sequoia-man-0.3.2/src/lib.rs000064400000000000000000000164331046102023000137570ustar 00000000000000/// Generate Unix manual pages for sq from its `clap::Command` value. /// /// A Unix manual page is a document marked up with the /// [troff](https://en.wikipedia.org/wiki/Troff) language. The troff /// markup is the source code for the page, and is formatted and /// displayed using the "man" command. /// /// Troff is a child of the 1970s and is one of the earlier markup /// languages. It has little resemblance to markup languages born in /// the 21st century, such as Markdown. However, it's not actually /// difficult, merely old, and sometimes weird. Some of the design of /// the troff language was dictated by the constraints of 1970s /// hardware, programming languages, and fashions in programming. Let /// not those scare you. /// /// The troff language supports "macros", a way to define new commands /// based on built-in commands. There are a number of popular macro /// packages for various purposes. One of the most popular ones for /// manual pages is called "man", and this module generates manual /// pages for that package. It's supported by the "man" command on all /// Unix systems. /// /// Note that this module doesn't aim to be a generic manual page /// generator. The scope is specifically the Sequoia sq command. use std::env; use std::fs; use std::io::Write; use std::path::Path; use std::path::PathBuf; use anyhow::Context; pub mod man; type Result = std::result::Result; /// Variable name to control the asset out directory with. pub const ASSET_OUT_DIR: &str = "ASSET_OUT_DIR"; /// Returns the directory to write the given assets to. /// /// For man pages, this would usually be `man-pages`. /// /// The base directory is takens from the environment variable /// [`ASSET_OUT_DIR`] or, if that is not set, cargo's [`OUT_DIR`]: /// /// > OUT_DIR — If the package has a build script, this is set to the /// > folder where the build script should place its output. See below /// > for more information. (Only set during compilation.) /// /// [`OUT_DIR`]: https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-crates /// /// This function panics if neither environment variable is set. pub fn asset_out_dir(asset: &str) -> Result { println!("cargo:rerun-if-env-changed={}", ASSET_OUT_DIR); let outdir: PathBuf = env::var_os(ASSET_OUT_DIR).unwrap_or_else( || env::var_os("OUT_DIR").expect("OUT_DIR not set")).into(); if outdir.exists() && ! outdir.is_dir() { return Err(anyhow::anyhow!("{}={:?} is not a directory", ASSET_OUT_DIR, outdir)); } let path = outdir.join(asset); fs::create_dir_all(&path)?; Ok(path) } /// pandoc helper file to convert a man page to HTML. pub const MAN_PANDOC_LUA: &[u8] = include_bytes!("man-pandoc.lua"); /// pandoc helper file to convert a man page to HTML. pub const MAN_PANDOC_INC_HTML: &[u8] = include_bytes!("man-pandoc.inc.html"); /// Generates man pages. /// /// `asset_dir` is the directory where the man pages will be written. /// /// `version` is the bare version string, which is usually obtained /// from `env!("CARGO_PKG_VERSION")`. /// /// If `extra_version` is `Some`, then the version is created `version /// (extra_version)`. /// /// The helper files `man-pandoc.lua`, `man-pandoc.inc.html` and /// `man2html.sh`, will also be written to the directory. /// /// If you define a data type `Cli`, then you would do: /// /// ```no_run /// use clap::CommandFactory; /// use clap::Parser; /// # /// /// #[derive(Parser, Debug)] /// #[clap( /// name = "sq", /// about = "A command-line frontend for Sequoia, an implementation of OpenPGP")] /// struct Cli { /// // ... /// } /// /// # fn main() -> Result<(), Box> { /// let dir = sequoia_man::asset_out_dir("man-pages")?; /// let mut cli = Cli::command(); /// let mut builder = sequoia_man::man::Builder::new(&mut cli, env!("CARGO_PKG_VERSION"), None); /// builder.see_also(&[ "For the full documentation see ." ]); /// sequoia_man::generate_man_pages(&dir, &builder)?; /// # Ok(()) /// # } /// ``` /// /// To convert the man pages to HTML, run the `man2html.sh` script. /// /// ```shell /// bash .../man-pages/man2html.sh /// ``` pub fn generate_man_pages(asset_dir: &Path, builder: &man::Builder) -> Result<()> { let mut man2html = String::new(); man2html.push_str("#! /bin/bash\n"); man2html.push_str("# Convert the man pages to HTML using pandoc.\n"); man2html.push_str("\n"); man2html.push_str("set -e\n\n"); man2html.push_str("cd $(dirname $0)\n\n"); man2html.push_str("FILES=\""); for man in builder.build() { man2html.push_str(&format!(" {}", man.filename().display())); std::fs::write(asset_dir.join(man.filename()), man.troff_source())?; } man2html.push_str("\"\n"); man2html.push_str("\n"); man2html.push_str(&format!("\ case \"$1\" in --generate) for man_page in $FILES do BINARY={} pandoc -s $man_page -L man-pandoc.lua -H man-pandoc.inc.html -o $man_page.html done ;; --man-files) for man_page in $FILES do echo $man_page done ;; --man-root) for man_page in $FILES do echo $man_page break done ;; --html-files) for man_page in $FILES do echo $man_page.html done ;; --html-root) for man_page in $FILES do echo $man_page.html break done ;; *) echo \"Usage: $0 --generate|--man-files|--man-root|--html-files|--html-root\" exit 1 ;; esac ", builder.binary())); let target = asset_dir.join("man-pandoc.lua"); std::fs::write(&target, MAN_PANDOC_LUA) .with_context(|| format!("Writing {}", target.display()))?; let target = asset_dir.join("man-pandoc.inc.html"); std::fs::write(&target, MAN_PANDOC_INC_HTML) .with_context(|| format!("Writing {}", target.display()))?; let target = asset_dir.join("man2html.sh"); let mut f = std::fs::File::create(&target) .with_context(|| format!("Crating {}", target.display()))?; f.write_all(man2html.as_bytes())?; #[cfg(unix)] { use std::os::unix::fs::PermissionsExt; // Make it executable for the owner. let metadata = f.metadata()?; let mut permissions = metadata.permissions(); permissions.set_mode(permissions.mode() | 0o100); f.set_permissions(permissions)?; } println!("cargo:warning=man pages written to {}", asset_dir.display()); Ok(()) } #[cfg(test)] mod tests { use super::*; use clap::CommandFactory; use clap::Parser; #[derive(Parser, Debug)] #[clap( name = "frob", about = "A tool to help with frobnication.")] struct Cli { /// How intense to frobnicate. #[arg(long="intensity")] intensity: usize, } #[test] fn build() { let dir = tempfile::TempDir::new().unwrap(); let mut cli = Cli::command(); let mut builder = man::Builder::new( &mut cli, env!("CARGO_PKG_VERSION"), None); builder.see_also(&[ "For the full documentation see ." ]); generate_man_pages(dir.path(), &builder).unwrap(); // Persist the state: if false { let p = dir.into_path(); eprintln!("Persisted output to: {}", p.display()); } } } sequoia-man-0.3.2/src/man-pandoc.inc.html000064400000000000000000000003171046102023000163100ustar 00000000000000 sequoia-man-0.3.2/src/man-pandoc.lua000064400000000000000000000142321046102023000153560ustar 00000000000000-- Tweaks our manual pages during conversion to html by pandoc. -- -- See https://pandoc.org/lua-filters.html#debugging-lua-filters on -- how to debug and develop these filters. -- Note: you must set the environment variable BINARY to the name of -- the primary executable, e.g., 'sq' or `sq-git`. BINARY = os.getenv("BINARY") if BINARY == nil or BINARY == "" then error("BINARY environment variable should be set to the binary's name, e.g., sq") end -- Overwrites the title. -- -- It just says 'sq` which looks odd. function Meta(m) m.title = "Sequoia PGP Manual Pages" return m end -- Turns subcommand headers into links. function Header (h) -- Given a sequence of subcommands, return the appropriate file -- name. local function subcommand_to_link (s) t = "" for i = 1, #s do if s[i].t == 'Space' then t = t .. '-' else t = t .. s[i].text end end return t .. ".1.html" end if h.c[1].t == 'Str' and h.c[1].text == BINARY then h.c = pandoc.Link(h.c, subcommand_to_link(h.c)) return h end end -- Transform the entries in the "SYNOPSIS" section into links. local function rewrite_synopsis (inlines) -- Returns true if we're looking at a synopsis entry. -- -- Matches on the following sequence: -- -- [1] LineBreak {} -- [2] Strong { -- content: Inlines[7] { -- [1] Str "sq" -- [2] Space -- [3] Str "key" -- [4] Space -- [5] Str "userid" -- [6] Space -- [7] Str "add" -- } -- } -- [3] Space -- [4] Str "[" local function synopsis_p (s) return s[1] and s[1].t == 'LineBreak' and s[2] and s[2].t == 'Strong' and s[2].c[1].text == BINARY and (not s[2].c[2] or s[2].c[2].t == 'Space') and s[3] and s[3].t == 'Space' and s[4] and s[4].t == 'Str' and s[4].text == '[' end -- Given a sequence of subcommands, return the appropriate file -- name. local function subcommand_to_link (s) t = "" for i = 1, #s do if s[i].t == 'Space' then t = t .. '-' else t = t .. s[i].text end end return t .. ".1.html" end for i = 1, #inlines-4 do if synopsis_p(table.pack(table.unpack(inlines, i, i + 3))) then inlines[i+1] = pandoc.Link(inlines[i+1], subcommand_to_link(inlines[i+1].c)) end end end -- Transforms the entries in the "SEE ALSO" section into links. local function rewrite_see_also (inlines) -- Returns true if we're looking at a see-also entry. -- -- Matches on the following sequence: -- -- [43] Strong { -- content: Inlines[1] { -- [1] Str "sq-wkd" -- } -- } -- [44] Str "(1)," local function see_also_p (a, b) return a and a.t == 'Strong' and b and b.t == 'Str' and string.sub(b.text, 1, 3) == '(1)' end for i = 1, #inlines-1 do if see_also_p(inlines[i], inlines[i+1]) then inlines[i] = pandoc.Link(inlines[i], inlines[i].c[1].text .. ".1.html") end end end -- Transforms text enclosed in backticks into inline code or links. local function rewrite_inline_code (inlines) -- Returns the length of the token stream containing quoted text -- starting from the first token, or nil if no quoted text is -- found. local function inline_quoted (s) if s[1] and s[1].t == 'Str' and string.sub(s[1].text, 1, 1) == "`" then -- Find the end, i.e. the first token containing the closing -- tick (which may be the first token). for i = 1, #s do if s[i] and s[i].t == 'Str' and string.find(s[i].text, "`", 2) then return i end end end end -- Given a sequence of tokens, returns the text representation. local function tokens_to_text (s) t = "" for i = 1, #s do if s[i].t == 'Space' then t = t .. ' ' else t = t .. s[i].text end end return t end -- Given a string subcommand, return the appropriate file -- name. local function subcommand_to_link (s) return string.gsub(s, " ", "-") .. ".1.html" end -- Note: as we mutate `inlines` here, we use a while loop to -- iterate over it. Using a for loop doesn't cut it as `#inlines` -- is then evaluated only once when entering the loop for the first -- time. local i = 1 while i <= #inlines do local len = inline_quoted(table.pack(table.unpack(inlines, i))) if len then -- First, flatten the matched tokens to a text. local text = tokens_to_text(table.pack(table.unpack(inlines, i, i+len))) -- Then, remove the tokens from the AST. for j = math.min(i+len, #inlines), i, -1 do inlines:remove(j) end -- We need to create a replacement node. local replacement -- See if the quoted text is a reference to a (sub)command. local s, e = string.find(text, "`" .. BINARY .. "[^`]*`") if s then -- If so, we turn it into a link. local sub = string.sub(text, s+1, e-1) replacement = pandoc.Link(sub, subcommand_to_link(sub)) else s, e = string.find(text, "`[^`]*`") replacement = pandoc.Code(string.sub(text, s+1, e-1)) end -- Finally, insert prefix, replacement, and suffix into the -- AST. inlines:insert(i+0, pandoc.Str(string.sub(text, 1, s-1))) inlines:insert(i+1, replacement) inlines:insert(i+2, pandoc.Str(string.sub(text, e+1))) end i = i + 1 end end function Inlines (inlines) rewrite_synopsis(inlines) rewrite_see_also(inlines) rewrite_inline_code(inlines) return inlines end -- Turns implicit links into actual links. function Str (s) s = s.text a, b = string.find(s, "]+>") if a and b then target = string.sub(s, a+1, b-1) return pandoc.Inlines { pandoc.Str(string.sub(s, 0, a)), pandoc.Link(target, target), pandoc.Str(string.sub(s, b)), } end end sequoia-man-0.3.2/src/man.rs000064400000000000000000001126271046102023000137660ustar 00000000000000use std::path::{Path, PathBuf}; use roff::{bold, italic, roman, Inline, Roff}; /// The "manual" the manual page is meant for. The full Unix /// documentation is (or was) divided into separate manuals, some of /// which don't consist of manual pages. const MANUAL: &str = "User Commands"; /// The "source" of the manual: who produced the manual. const SOURCE: &str = "Sequoia PGP"; /// Emits a warning. macro_rules! warn { {$($exp: expr),*} => { println!("cargo:warning={}", format_args!($($exp),*)); }; } /// Emits a warning and exits with an error. macro_rules! fail { {$($exp: expr),*} => { warn!($($exp),*); std::process::exit(1); }; } /// Build a ManualPage or several. // /// The main command is sq itself. It can have multiple levels of /// subcommands, and we treat the leaves of the subcommand tree /// specially: every leaf gets a manual page, and every intermediate /// node gets an overview page. For example, "sq encrypt" is a leaf, /// as is "sq key generate", but "sq key" is not. pub struct Builder { title: String, section: String, date: Option, source: Option, manual: Option, version: Option, see_also: Vec, maincmd: Command, // The set of top-level, global options. This is derived from // maincmd. top_level_global_args: Vec, } impl Builder { /// Return a builder to generate manual page. /// /// `cmd` is a `clap::Command` that has been built to represent /// the sq command line interface. The manual pages are generated /// automatically from that information. /// /// `version` is the bare version, which is usually obtained from /// `env!("CARGO_PKG_VERSION")`. /// /// If `extra_version` is `Some`, then the version is created /// `version (extra_version)`. /// /// For sequoia packages, this is usually: /// `format!("sequoia-openpgp {}", sequoia_openpgp::VERSION)`. pub fn new(cmd: &mut clap::Command, version: &str, extra_version: Option<&str>) -> Self { cmd.build(); let version = if let Some(extra_version) = extra_version { format!("{} ({})", version, extra_version) } else { version.to_string() }; let maincmd = Command::from_command(&[], cmd); let options = maincmd.get_options(); // Also consider --help a global argument. This argument is // added by clap, so applications can't mark it as such. let top_level_global_args = options.into_iter() .filter(|a| a.global || a.long.as_deref() == Some("--help")) .collect::>(); Self { title: cmd.get_name().into(), section: "1".into(), date: Some(version.clone()), source: Some(SOURCE.to_string()), manual: Some(MANUAL.to_string()), version: Some(version), see_also: Vec::new(), maincmd, top_level_global_args, } } /// Returns whether the specified argument is a top-level global /// argument. fn is_top_level_global_arg(&self, arg: &CommandOption) -> bool { self.top_level_global_args .binary_search_by_key(&arg.sort_key(), |a: &CommandOption| a.sort_key()) .is_ok() } /// Set the date for the manual page. This is typically typeset in /// the center of the footer of the page. pub fn date(&mut self, date: &str) -> &mut Self{ self.date = Some(date.into()); self } /// Set the source of the manual page. This is typically typeset on /// left of the footer of the page. pub fn source(&mut self, source: &str) -> &mut Self { self.source = Some(source.into()); self } /// Set the manual this page belongs to. This is typically typeset /// on the center of the header of the page. pub fn manual(&mut self, manual: &str) -> &mut Self { self.manual = Some(manual.into()); self } /// Return a one-line summary of the command. This goes in the NAME /// section of the manual page. fn summary(about: &str) -> String { let line = if let Some(line) = about.lines().next() { line } else { "" }; line.to_string() } /// Text that is added to the see also section. /// /// For example: /// /// ```text /// For the full documentation see . /// ``` pub fn see_also(&mut self, see_also: &[S]) -> &mut Self where S: AsRef { self.see_also = see_also.into_iter() .map(|s| { s.as_ref().to_string() }) .collect(); self } /// Returns the name of the binary, e.g., `sq`, or `sq-git`. pub fn binary(&self) -> String { self.maincmd.name() } /// Build all manual pages for sq and one for each leaf subcommand. pub fn build(&self) -> Vec { let mut pages = vec![]; self.maincmd.build(self, &mut pages); pages } /// Set the title of the page. fn th(&self, man: &mut ManualPage) { let empty = String::new(); man.th( &self.title.to_uppercase(), &self.section.to_uppercase(), self.date.as_ref().unwrap_or(&empty), self.source.as_ref().unwrap_or(&empty), self.manual.as_ref().unwrap_or(&empty), ) } } /// The command for which we generate a manual page. // /// We collect all the information about a command here so that it's /// handy when we generate various parts of a manual page that includes /// this command. #[derive(Debug, PartialEq, Eq)] struct Command { command_words: Vec, before_help: Option, after_help: Option, about: Option, long_about: Option, options: Vec, args: Vec, examples: Vec, exit_status: Vec, subcommands: Vec, } impl Command { /// Create a new `Command`. The command words are the part of /// the command line that invokes this command. For sq itself, /// they're `["sq"]`, but for a subcommand they might be `["sq", /// "key", "generate"]` for example. fn new(command_words: Vec) -> Self { assert!(! command_words.is_empty()); Self { command_words, before_help: None, after_help: None, about: None, long_about: None, options: vec![], args: vec![], examples: vec![], exit_status: vec![], subcommands: vec![], } } /// Returns whether the command is the top-level command. fn top_level(&self) -> bool { self.command_words.len() == 1 } /// Returns whether the command is a leaf command. /// /// A leaf command is not the top-level command and has no subcommands. fn leaf(&self) -> bool { ! self.top_level() && self.subcommands.is_empty() } /// Returns whether this it command is a singleton, i.e., it is /// the top-level command, and it has no subcommands. fn singleton(&self) -> bool { self.top_level() && self.subcommands.is_empty() } /// Return the name of the command, with command words separated by /// spaces. This is suitable for, say, the NAME section. fn name(&self) -> String { self.command_words.join(" ") } /// Return name of the subcommand, without the main command name. fn subcommand_name(&self) -> String { let mut words = self.command_words.clone(); words.remove(0); words.join(" ") } /// Return the name of the manual page for this command. This is /// the command words separated by dashes. Thus "sq key generate" /// would return "sq-key-generate". Manual page names mustn't /// contain spaces, thus the dash. fn manpage_name(&self) -> String { self.command_words.join("-") } /// Return the description of the command. This is collected from /// the various about and help texts given to `clap`. fn description(&self) -> String { let mut desc = String::new(); if let Some(text) = &self.before_help { desc.push_str(text); desc.push('\n'); } if let Some(text) = &self.long_about { desc.push_str(text); desc.push('\n'); } else if let Some(text) = &self.about { desc.push_str(text); desc.push('\n'); } if let Some(text) = &self.after_help { desc.push_str(text); desc.push('\n'); } desc } /// Add the `before_help` help text for this command. fn before_help(&mut self, help: &str) { self.before_help = Some(self.extract_all(help)); } /// Add the `after_help` help text for this command. fn after_help(&mut self, help: &str) { self.after_help = Some(self.extract_all(help)); } /// Add the `about` help text for this command. fn about(&mut self, help: &str) { self.about = Some(self.extract_all(help)); } /// Add the `long_about` help text for this command. fn long_about(&mut self, help: &str) { self.long_about = Some(self.extract_all(help)); } /// Add an option to this command. fn option(&mut self, opt: CommandOption) { self.options.push(opt); } /// Add a positional argument to this command. fn arg(&mut self, arg: &str) { self.args.push(arg.into()); } /// Extracts all additional sections. fn extract_all(&mut self, text: &str) -> String { let text = self.extract_example(text); let text = self.extract_exit_status(&text); text } /// Extract examples from help text: anything that follows a line /// consisting of "Examples:". /// /// This is a convention specific to sq, not something that comes /// from `clap`. fn extract_example(&mut self, text: &str) -> String { Self::extract("Examples:\n", &mut self.examples, text) } /// Extract exit status from help text: anything that follows a line /// consisting of "Exit status:". /// /// This is a convention specific to sq, not something that comes /// from `clap`. fn extract_exit_status(&mut self, text: &str) -> String { Self::extract("Exit status:\n", &mut self.exit_status, text) } /// Extracts sections, like examples, putting them into `into`. fn extract(marker: &str, into: &mut Vec, text: &str) -> String { if let Some(pos) = text.find(marker) { let (text, ex) = text.split_at(pos); if let Some(ex) = ex.strip_prefix(marker) { into.push(ex.into()); } else { into.push(ex.into()); } text.into() } else { text.into() } } /// Does this command have any options? fn has_options(&self) -> bool { !self.options.is_empty() } /// Get the list of options for this command. fn get_options(&self) -> Vec { let mut opts = self.options.clone(); opts.sort_by_cached_key(|opt| opt.sort_key()); opts } /// Does this command have examples? fn has_examples(&self) -> bool { !self.examples.is_empty() } /// Create a new `Command` from a `clap::Command` structure. fn from_command(parent: &[String], cmd: &clap::Command) -> Self { let mut words: Vec = parent.into(); words.push(cmd.get_name().to_string()); let mut new = Self::new(words); if let Some(text) = cmd.get_before_help() { new.before_help(&text.to_string()); } if let Some(text) = cmd.get_after_help() { new.after_help(&text.to_string()); } if let Some(text) = cmd.get_about() { new.about(&text.to_string()); } if let Some(text) = cmd.get_long_about() { new.long_about(&text.to_string()); } for arg in cmd.get_arguments() .filter(|a| ! a.is_hide_set()) { new.option(CommandOption::from_arg(arg)); } for arg in cmd.get_positionals() .filter(|a| ! a.is_hide_set()) { if let Some(names) = arg.get_value_names() { for name in names { new.arg(name); } } } let mut parent = parent.to_vec(); parent.push(cmd.get_name().into()); new.subcommands = cmd.get_subcommands() .filter(|cmd| ! cmd.is_hide_set()) .filter(|cmd| cmd.get_name() != "help") .map(|cmd| Command::from_command(&parent, cmd)) .collect(); new } /// Builds manpages recursively. fn build(&self, builder: &Builder, acc: &mut Vec) { acc.push(self.build_command(builder)); for cmd in &self.subcommands { cmd.build(builder, acc); } } /// Build a manual page for an intermediate (i.e. non-leaf) command. fn build_command(&self, builder: &Builder) -> ManualPage { let filename = format!("{}.{}", self.manpage_name(), builder.section); let mut man = ManualPage::new(PathBuf::from(filename)); builder.th(&mut man); let about = &self.about.clone().unwrap(); let summary = Builder::summary(about); man.name_section(&self.manpage_name(), &summary); man.section("SYNOPSIS"); let bin_name = builder.binary(); if self.singleton() || self.leaf() { // Show the command. man.subcommand_synopsis( &bin_name, &self.subcommand_name(), self.has_options(), &self.args, true, ); } else { // Show the subcommands. for sub in &self.subcommands { man.subcommand_synopsis( &bin_name, &sub.subcommand_name(), sub.has_options(), &sub.args, sub.leaf(), ); } } man.section("DESCRIPTION"); man.text_with_period(&self.description()); // Show the options for top-level and leaf commands. if self.top_level() || self.leaf() { let mut showed_options_header = false; // Show command-specific arguments. let mut self_opts = self.get_options(); if ! self.singleton() { self_opts = self_opts.into_iter() .filter(|o| ! builder.is_top_level_global_arg(o)) .collect::>(); } if ! self_opts.is_empty() { if ! showed_options_header { showed_options_header = true; man.section("OPTIONS"); } if ! self.top_level() { // This is not the top-level command. man.subsection("Subcommand options"); } for opt in self_opts.iter() { man.option(opt); } } // Show the global arguments at the top-level. Otherwise, // reference the top-level command. let global_options = &builder.top_level_global_args; if ! self.singleton() && ! global_options.is_empty() { #[allow(unused_assignments)] if ! showed_options_header { showed_options_header = true; man.section("OPTIONS"); } man.subsection("Global options"); if self.top_level() { // At the top-level, we print out the top-level // global options. for opt in global_options.iter() { man.option(opt); } } else { // Non-top-level commands just reference the top // level's documentation. man.roff.text(vec![ roman("See "), bold(bin_name), roman("("), roman("1"), roman(")"), roman(" for a description of the global options."), ]); } } } if ! self.subcommands.is_empty() { man.section("SUBCOMMANDS"); for sub in &self.subcommands { let desc = sub.description(); if !desc.is_empty() { man.subsection(&sub.name()); man.text_with_period(&desc); } } } man.exit_status_section(self); // Maybe add environment section. if self == &builder.maincmd { let opts = self.get_options(); let mut envs: Vec<_> = opts.iter().filter(|o| o.env.is_some()).collect(); envs.sort_by_key(|o| o.env.as_ref()); if ! envs.is_empty() { man.section("ENVIRONMENT"); for opt in envs { man.env_option(opt); } } } if self.singleton() || self.leaf() { man.examples_section(&[self]); } else { man.examples_section( &std::iter::once(self) .chain(self.subcommands.iter()) .collect::>()); } let mut see_also_shown = false; let names: Vec = (1..self.command_words.len()) .map(|n| self.command_words[0..n].join("-")) .chain(self.subcommands.iter().map(|sub| sub.manpage_name())) .collect(); if ! names.is_empty() { if ! see_also_shown { man.section("SEE ALSO"); see_also_shown = true; } man.man_page_refs(&names, &builder.section); man.paragraph(); } if ! builder.see_also.is_empty() { #[allow(unused_assignments)] if ! see_also_shown { man.section("SEE ALSO"); see_also_shown = true; } for (i, see_also) in builder.see_also.iter().enumerate() { if i > 0 { man.paragraph(); } man.text(see_also); } } man.version_section(&builder.version); man } } /// Represent a command line option for manual page generation. // /// This doesn't capture all the things that `clap` allows, but is /// sufficient for what sq actually uses. #[derive(Clone, Debug, PartialEq, Eq)] struct CommandOption { /// Index for positional arguments. index: Option, short: Option, long: Option, /// Whether the global flag is set. global: bool, env: Option, value_names: Values, possible_values: Vec, default_values: Vec, help: Option, } /// Formal arguments for a command option. #[derive(Clone, Debug, PartialEq, Eq)] enum Values { /// This option does not take any arguments. None, /// This option takes the given arguments. Some(Vec), /// This option optionally takes the given arguments. /// /// XXX: Currently, this is all or nothing, i.e. either all /// arguments are mandatory, or all are optional. Let's see /// whether we need something more complicated. Optional(Vec), } impl CommandOption { /// Return a key for sorting a list of options. /// /// Manual pages list options in various places, and it enables /// quicker lookup by readers if they lists are sorted /// alphabetically. By convention, such lists are sorted by short /// option first, if one exists. And, positional arguments are /// sorted to the bottom, and in the order they appear on the /// command line. fn sort_key(&self) -> (usize, String) { let mut key = String::new(); if let Some(name) = &self.short { key.push_str(name.strip_prefix('-').unwrap()); key.push(','); } if let Some(name) = &self.long { key.push_str(name.strip_prefix("--").unwrap()); } (self.index.unwrap_or(0), key) } } impl CommandOption { /// Create a `CommandOption` from a `clap::Arg`. fn from_arg(arg: &clap::Arg) -> Self { let num_args = arg.get_num_args().unwrap_or_default(); let value_names = if num_args.takes_values() { let names = arg.get_value_names() .unwrap_or(&[]) .into_iter() .map(|s| s.to_string()) .collect::>(); if num_args.min_values() == 0 { Values::Optional(names) } else { Values::Some(names) } } else { // Flag. Values::None }; let long = arg.get_long().map(|o| format!("--{}", o)); let global = arg.is_global_set(); if global { assert!(long.is_some(), "Global options must have a long name."); } Self { index: arg.get_index(), short: arg.get_short().map(|o| format!("-{}", o)), long, global, value_names, env: arg.get_env().and_then(|e| e.to_str().map(Into::into)), possible_values: arg.get_possible_values().iter() .map(|o| o.get_name().into()).collect(), default_values: if num_args.takes_values() { // At least one argument. arg.get_default_values().iter() .map(|s| s.to_string_lossy().to_string()) .collect() } else { // No argument, i.e. a flag. We don't want to // output `[default: false]` in that case. vec![] }, help: arg.get_long_help().or(arg.get_help()) .map(|s| s.to_string()), } } } /// Troff code for a manual page. /// /// The code is in [`troff`](https://en.wikipedia.org/wiki/Troff) /// format, as is usual for Unix manual page documentation. It's using /// the `man` macro package for `troff`. pub struct ManualPage { filename: PathBuf, roff: Roff, // Are we in code mode (emitted .nf)? in_code: bool, } impl ManualPage { fn new(filename: PathBuf) -> Self { Self { filename, roff: Roff::new(), in_code: false, } } /// Set the title of the manual page. The "TH" macro takes five /// arguments: name of the command; section of the manual; the date /// of latest update; the source of manual; and the name of the manual. fn th(&mut self, name: &str, section: &str, date: &str, source: &str, manual: &str) { self.roff .control("TH", [name, section, date, source, manual]); } /// Typeset the NAME section: the title, and a line with the name /// of the command, followed by a dash, and a one-line. The dash /// should be escaped with backslash, but the `roff` crate does /// that for us. fn name_section(&mut self, name: &str, summary: &str) { self.section("NAME"); self.roff.text([roman(&format!("{} - {}", name, summary))]); } /// Typeset code blocks, joining adjacent blocks. fn code(&mut self, code: bool) { match (self.in_code, code) { (false, false) => (), (false, true) => { self.roff.control("nf", []); self.in_code = true; }, (true, false) => { self.roff.control("fi", []); self.in_code = false; }, (true, true) => (), } } /// Typeset the synopsis of a command. This is going to be part of /// the SYNOPSIS section. There are conventions for how it should /// be typeset. For sq, we simplify them by summarizing options /// into a placeholder, and only listing command words and /// positional arguments. fn subcommand_synopsis( &mut self, bin: &str, sub: &str, sub_options: bool, args: &[String], is_leaf: bool, ) { let mut line = vec![ bold(if sub.is_empty() { bin.to_string() } else { format!("{} {}", bin, sub) }), roman(" ["), italic("OPTIONS"), roman("] "), ]; for (i, arg) in args.iter().enumerate() { if i > 0 || ! sub_options { line.push(roman(" ")); } line.push(italic(arg)); } if args.is_empty() { line.push(roman(" ")); } if ! is_leaf { line.push(italic("SUBCOMMAND")); } self.roff.control("br", []); self.roff.text(line); } /// Typeset an option, for the OPTIONS section. This is typeset /// using "tagged paragraphs", where the first line lists the /// aliases of the option, and any values it may take, and the rest /// is indented paragraphs of text explaining what the option does. fn option(&mut self, opt: &CommandOption) { let mut line = vec![]; if let Some(short) = &opt.short { line.push(bold(short)); } if let Some(long) = &opt.long { if opt.short.is_some() { line.push(roman(", ")); } line.push(bold(long)); } match &opt.value_names { Values::None => (), Values::Some(values) | Values::Optional(values) => { if matches!(opt.value_names, Values::Optional(_)) { line.push(roman("[")); } if (opt.short.is_some() || opt.long.is_some()) && values.len() == 1 { line.push(roman("=")); line.push(italic(&values[0])); } else { for value in values { line.push(roman(" ")); line.push(italic(value)); } } if matches!(opt.value_names, Values::Optional(_)) { line.push(roman("]")); } }, } self.tagged_paragraph(line, &opt.help); if ! opt.default_values.is_empty() { self.indented_paragraph(); let mut line = vec![]; line.push(roman("[default: ")); for (i, v) in opt.default_values.iter().enumerate() { if i > 0 { line.push(roman(", ")); } line.push(bold(v)); } line.push(roman("]")); self.roff.text(line); } if ! opt.possible_values.is_empty() { self.indented_paragraph(); let mut line = vec![]; line.push(roman("[possible values: ")); for (i, v) in opt.possible_values.iter().enumerate() { if i > 0 { line.push(roman(", ")); } line.push(bold(v)); } line.push(roman("]")); self.roff.text(line); } } /// Typeset an option, for the ENVIRONMENT section. /// /// This is typeset using "tagged paragraphs", where the first /// line lists the aliases of the option, and any values it may /// take, and the rest is indented paragraphs of text explaining /// what the option does. fn env_option(&mut self, opt: &CommandOption) { let mut line = vec![ bold(opt.env.as_ref().expect("must be an env")), ]; match &opt.value_names { Values::None => (), Values::Some(values) | Values::Optional(values) => { assert_eq!(values.len(), 1); line.push(roman("=")); line.push(italic(&values[0])); }, } self.tagged_paragraph(line, &opt.help); if ! opt.default_values.is_empty() { self.indented_paragraph(); let mut line = vec![]; line.push(roman("[default: ")); for (i, v) in opt.default_values.iter().enumerate() { if i > 0 { line.push(roman(", ")); } line.push(bold(v)); } line.push(roman("]")); self.roff.text(line); } if ! opt.possible_values.is_empty() { self.indented_paragraph(); let mut line = vec![]; line.push(roman("[possible values: ")); for (i, v) in opt.possible_values.iter().enumerate() { if i > 0 { line.push(roman(", ")); } line.push(bold(v)); } line.push(roman("]")); self.roff.text(line); } } /// Typeset an EXIT STATUS section, if available. fn exit_status_section(&mut self, c: &Command) { if c.exit_status.is_empty() { return; } self.section("EXIT STATUS"); for chunk in &c.exit_status { self.text(&chunk); } } /// Typeset an EXAMPLES section, if a command has examples. fn examples_section(&mut self, subs: &[&Command]) { if !subs.iter().any(|c| c.has_examples()) { return; } self.section("EXAMPLES"); let mut need_para = false; let need_subsections = subs.len() > 1; for cmd in subs.iter() { if need_para { self.paragraph(); need_para = false; } if !cmd.examples.is_empty() { if need_subsections { self.subsection(&cmd.name()); need_para = false; } for ex in cmd.examples.iter() { // Was the last line a continuation? let mut continuation = false; // Was the last line part of the description? let mut description = false; for line in ex.lines() { if ! continuation && ! (description && line.starts_with("#")) { self.paragraph(); } const TARGET_LINE_LENGTH: usize = 78; const RS_INDENTATION: usize = 7; const EXAMPLE_COMMAND_MAX_WIDTH: usize = TARGET_LINE_LENGTH - 2 * RS_INDENTATION; const EXAMPLE_CONTINUATION_MAX_WIDTH: usize = TARGET_LINE_LENGTH - 3 * RS_INDENTATION; if let Some(line) = line.strip_prefix("# ") { self.code(false); self.roff.text([roman(line)]); } else if let Some(line) = line.strip_prefix("$ ") { let line = line.trim(); if line.len() > EXAMPLE_COMMAND_MAX_WIDTH { warn!("Command in example exceeds {} chars:", EXAMPLE_COMMAND_MAX_WIDTH); fail!("{} ({} chars)", line, line.len()); } self.code(true); self.roff.control("RS", []); self.roff.text([roman(line)]); self.roff.control("RE", []); } else if continuation { let line = line.trim(); if line.len() > EXAMPLE_CONTINUATION_MAX_WIDTH { warn!("Continuation in example exceeds {} chars:", EXAMPLE_CONTINUATION_MAX_WIDTH); fail!("{} ({} chars)", line, line.len()); } self.code(true); self.roff.control("RS", []); self.roff.control("RS", []); self.roff.text([roman(line)]); self.roff.control("RE", []); self.roff.control("RE", []); } else { self.code(false); self.roff.text([roman(line)]); } // Update continuation for the next loop iteration. continuation = line.ends_with("\\"); // Update description for the next loop iteration. description = line.starts_with("#"); // We emitted at least one example, make sure // to add a new paragraph before going to the // next command. need_para = true; } } self.code(false); } } } /// Typeset the VERSION section, if the main command has a version /// set. fn version_section(&mut self, version: &Option) { if let Some(v) = version { self.section("VERSION"); self.roff.text([roman(v)]); } } /// Start a new section with the SH troff command. fn section(&mut self, heading: &str) { self.roff.control("SH", [heading]); } /// Start a new subsection with the SS troff command. fn subsection(&mut self, heading: &str) { self.roff.control("SS", [heading]); } /// Start a new paragraph with the PP troff command. fn paragraph(&mut self) { self.roff.control("PP", []); } /// Start a new indented paragraph with the IP troff command. fn indented_paragraph(&mut self) { self.roff.control("IP", []); } /// Start a tagged paragraph with th TP troff command. /// /// This command takes the line after the command and typesets it, /// and the line after that starts an indented paragraph. /// /// Additionally, if `text` is given, it is rendered after the /// `line`, indenting it. fn tagged_paragraph(&mut self, line: Vec, text: &Option) { self.roff.control("TP", []); self.roff.text(line); if let Some(text) = text { let mut paras = text.split("\n\n"); if let Some(first) = paras.next() { self.roff.text([roman(first)]); } for para in paras { self.roff.control("IP", []); self.roff.text([roman(para)]); } } } /// Typeset a list of references to manual pages, suitable for the /// SEE ALSO section. Manual page references are, by convention, /// typeset with the name of manual page in bold, and the section /// of the page in normal ("roman") font, enclosed in parentheses. /// The references are separated by commas, in normal font. fn man_page_refs(&mut self, names: &[String], section: &str) { let mut line = vec![]; for name in names.iter() { if !line.is_empty() { line.push(roman(", ")); } line.push(bold(name)); line.push(roman("(")); line.push(roman(section)); line.push(roman(")")); } line.push(roman(".")); self.roff.control("nh", []); self.roff.text(line); self.roff.control("hy", []); } /// Typeset normal text consisting of paragraphs. Paragraphs are /// separated by an empty line. All but the first paragraph are /// preceded by the troff paragraph command. The first one is not, /// to avoid unwanted empty lines in the output. fn text(&mut self, text: &str) { let mut paras = text.split("\n\n"); if let Some(first) = paras.next() { self.roff.text([roman(first)]); } for para in paras { self.paragraph(); self.roff.text([roman(para)]); } } /// Like [`ManualPage::text`], but add a period, if missing, to the end of /// the first paragraph. In `clap` about texts, the first line /// conventionally doesn't end in a period, but in manual pages, /// when that text is used in a DESCRIPTION section, it should have /// a period. fn text_with_period(&mut self, text: &str) { let mut paras = text.split("\n\n"); if let Some(first) = paras.next() { let first = if let Some(prefix) = first.strip_suffix(".\n") { format!("{}.", prefix) } else if let Some(prefix) = first.strip_suffix('\n') { format!("{}.", prefix) } else if first.ends_with('.') { first.to_string() } else { format!("{}.", first) }; self.roff.text([roman(first)]); } for para in paras { self.paragraph(); self.roff.text([roman(para)]); } } /// What should the filename be, on disk, for this manual page? pub fn filename(&self) -> &Path { &self.filename } /// Return the `troff` source code for the manual page. pub fn troff_source(&self) -> String { self.roff.to_roff() } }