build_manpages.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. # -*- coding: utf-8 -*-
  2. # manpage/build_manpages.py
  3. # Part of ‘manpage’, a Python library for making Unix manual documents.
  4. #
  5. # Copyright © 2016 Ben Finney <ben+python@benfinney.id.au>
  6. #
  7. # This is free software: see the grant of license at end of this file.
  8. """ Distutils integration to build Unix “man page” documents. """
  9. import os
  10. import os.path
  11. import distutils.core
  12. from distutils.errors import DistutilsOptionError
  13. from . import document
  14. from . import argparse_help
  15. class BuildManPages(distutils.core.Command, object):
  16. """ Generate Unix “man page” documents for this distribution. """
  17. description = (
  18. "Generate Unix “man page” documents for this distribution.")
  19. user_options = [
  20. ('output-dir=', 'O', (
  21. "Filesystem path to output directory."
  22. " (example: 'doc/')"
  23. " (default: '.')")),
  24. ]
  25. def initialize_options(self):
  26. """ Set defaults for options this command supports. """
  27. self.output_dir = os.path.curdir
  28. def finalize_options(self):
  29. """ Set final values for options this command supports. """
  30. self.ensure_dirname('output_dir')
  31. for (output_name, maker) in self.manpage_makers.items():
  32. maker.output_path = os.path.join(self.output_dir, output_name)
  33. def build_manpage(self, maker):
  34. """ Build a manual page document to its output file.
  35. :param maker: The `document.ManPageMaker` instance to
  36. create the document.
  37. :return: None.
  38. """
  39. self.announce(
  40. "Building manual page document ‘{name}({section})’".format(
  41. name=maker.metadata.name,
  42. section=maker.metadata.section))
  43. builder = DocumentBuilder(maker, self.distribution)
  44. manpage = builder.build()
  45. return manpage
  46. def write_manpage(self, manpage, outfile_path):
  47. """ Write the manual page document to the output file.
  48. :param manpage: The document to write to the output file.
  49. :param outfile_path: The filesystem path at which to
  50. create the output file.
  51. :return: None.
  52. """
  53. self.announce("Writing manual page document to ‘{path}’".format(
  54. path=outfile_path))
  55. manpage_writer = document.Writer(manpage, outfile_path)
  56. manpage_writer.write()
  57. def run(self):
  58. """ Execute this command. """
  59. for maker in self.manpage_makers.values():
  60. manpage = self.build_manpage(maker)
  61. self.write_manpage(manpage, maker.output_path)
  62. class DocumentBuilder:
  63. """ Builder for one manual page document in a distribution.
  64. Data attributes:
  65. * `maker`: The `document.ManPageMaker` to use for making the
  66. document.
  67. * `distribution`: The `distutils.dist.Distribution` to
  68. interrogate for the Python distribution fields.
  69. """
  70. def __init__(self, maker, distribution):
  71. self.maker = maker
  72. self.distribution = distribution
  73. def make_source_field(self):
  74. """ Make the “source” field value based on the distribution.
  75. :return: The text value for the “source” field in a manual
  76. page header.
  77. """
  78. text = "{name} {version}".format(
  79. name=self.distribution.get_name(),
  80. version=self.distribution.get_version())
  81. return text
  82. def insert_distribution_section(self, manpage):
  83. """ Insert the section into `manpage` for the distribution.
  84. :param manpage: The `document.Document` instance to modify.
  85. :return: None.
  86. """
  87. section_index = list(
  88. manpage.content_sections.keys()
  89. ).index("SEE ALSO")
  90. section = self.maker.make_distribution_section(self.distribution)
  91. manpage.insert_section(section_index, section)
  92. def build(self):
  93. """ Build the manual page document.
  94. :return: The `document.Document` instance.
  95. """
  96. metadata = self.maker.metadata
  97. if metadata.source is None:
  98. metadata = metadata._replace(source=self.make_source_field())
  99. self.maker.metadata = metadata
  100. manpage = self.maker.make_manpage()
  101. self.insert_distribution_section(manpage)
  102. return manpage
  103. def assemble_maker(
  104. maker_class, name, whatis,
  105. manual=None, section=None, source=None,
  106. parser=None):
  107. """ Assemble manual document maker from attributes.
  108. :param maker_class: The subclass of `ManPageMaker` of which to
  109. create an instance.
  110. :param name: The name of the document.
  111. :param whatis: The succinct one-line description of the document.
  112. :param manual: The title of the manual to which the document
  113. belongs.
  114. :param section: The section code to which the document belongs.
  115. :param source: The project that includes of the item documented
  116. in the document.
  117. :param parser: The `argparse.ArgumentParser` instance from
  118. which to derive help for the command.
  119. """
  120. metadata = document.MetaData(name, whatis, manual, section, source)
  121. maker = maker_class(metadata)
  122. if parser is not None:
  123. maker.set_parser(parser)
  124. return maker
  125. # This is free software: you may copy, modify, and/or distribute this work
  126. # under the terms of the GNU General Public License as published by the
  127. # Free Software Foundation; version 3 of that license or any later version.
  128. #
  129. # No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details,
  130. # or view it online at <URL:https://www.gnu.org/licenses/gpl-3.0.html>.
  131. # Local variables:
  132. # coding: utf-8
  133. # mode: python
  134. # End:
  135. # vim: fileencoding=utf-8 filetype=python :