build_manual_gallery.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #!/usr/bin/env python3
  2. ############################################################################
  3. #
  4. # MODULE: build_graphical_index
  5. # AUTHOR(S): Vaclav Petras <wenzeslaus gmail com>
  6. # PURPOSE: Build index gallery from images from all HTML files
  7. # COPYRIGHT: (C) 2015 by Vaclav Petras and the GRASS Development Team
  8. #
  9. # This program is free software under the GNU General Public
  10. # License (>=v2). Read the file COPYING that comes with GRASS
  11. # for details.
  12. #
  13. #############################################################################
  14. import os
  15. import sys
  16. import fnmatch
  17. import re
  18. from build_html import write_html_footer, grass_version, header1_tmpl
  19. output_name = "manual_gallery.html"
  20. img_extensions = ["png", "jpg", "gif"]
  21. img_patterns = ["*." + extension for extension in img_extensions]
  22. # we don't want some images to show up
  23. # logos
  24. img_blacklist = ["grass_logo.png", "grass_icon.png"]
  25. # circles with numbers from helptext.html (unfortunate we have to list it here)
  26. # perhaps some general name ending would be good, like *_noindex.png
  27. img_blacklist.extend(["circle_{0}.png".format(num) for num in range(1, 6)])
  28. year = os.getenv("VERSION_DATE")
  29. # other similar strings are in a different file
  30. # TODO: all HTML manual building needs refactoring (perhaps grass.tools?)
  31. header_graphical_index_tmpl = """\
  32. <link rel="stylesheet" href="grassdocs.css" type="text/css">
  33. <style>
  34. .img-list {
  35. list-style-type: none;
  36. margin: 0;
  37. padding: 0;
  38. text-align: center;
  39. }
  40. .img-list li {
  41. display: inline-block;
  42. position: relative;
  43. width: 7em;
  44. margin: 0;
  45. padding: 0.5em;
  46. }
  47. .img-list li:hover {
  48. background-color: #eee;
  49. }
  50. .img-list li img {
  51. float: left;
  52. max-width: 100%;
  53. background: white;
  54. }
  55. .img-list li span {
  56. text-align: center;
  57. }
  58. .img-list li a {
  59. color: initial;
  60. text-decoration: none;
  61. }
  62. .img-list li .name {
  63. margin: 0.1em;
  64. display: block;
  65. color: #409940;
  66. font-weight: normal;
  67. font-style: italic;
  68. font-size: 80%;
  69. }
  70. </style>
  71. </head>
  72. <body style="width: 99%">
  73. <div id="container">
  74. <a href="index.html"><img src="grass_logo.png" alt="GRASS logo"></a>
  75. <hr class="header">
  76. <h2>GRASS GIS manual gallery</h2>
  77. """
  78. def img_in_html(filename, imagename):
  79. # for some reason, calling search just once is much faster
  80. # than calling it on every line (time is spent in _compile)
  81. pattern = re.compile("<img .*src=.{0}.*>".format(imagename))
  82. with open(filename) as file:
  83. if re.search(pattern, file.read()):
  84. return True
  85. return False
  86. def file_matches(filename, patterns):
  87. for pattern in patterns:
  88. if fnmatch.fnmatch(filename, pattern):
  89. return True
  90. return False
  91. def get_files(directory, patterns, exclude_patterns):
  92. files = []
  93. for filename in sorted(os.listdir(directory)):
  94. if file_matches(filename, patterns):
  95. if not file_matches(filename, exclude_patterns):
  96. files.append(filename)
  97. return files
  98. def remove_module_name(string, module):
  99. string = string.replace(module.replace("wxGUI.", "g.gui."), "")
  100. string = string.replace(module.replace(".", "_"), "") # using _
  101. string = string.replace(module.replace(".", ""), "") # using nothing
  102. string = string.replace(module, "") # using original dots
  103. return string
  104. def title_from_names(module_name, img_name):
  105. # we ignore the possibility of having extension at the end of image
  106. # so possibly r.out.png fails but image name should use _ anyway
  107. # strictly speaking, it could be also, e.g., index name
  108. for extension in img_extensions:
  109. img_name = img_name.replace("." + extension, "")
  110. img_name = remove_module_name(img_name, module_name)
  111. img_name = img_name.replace("_", " ")
  112. img_name = img_name.strip()
  113. if img_name:
  114. return "{name} ({desc})".format(name=module_name, desc=img_name)
  115. else:
  116. return "{name}".format(name=module_name)
  117. def get_module_name(filename):
  118. return filename.replace(".html", "")
  119. def main():
  120. html_dir = sys.argv[1]
  121. html_files = get_files(
  122. html_dir,
  123. ["*.html"],
  124. exclude_patterns=[output_name, "*_graphical.html", "graphical_index.html"],
  125. )
  126. img_html_files = {}
  127. for filename in os.listdir(html_dir):
  128. if filename in img_blacklist:
  129. continue
  130. if file_matches(filename, img_patterns):
  131. for html_file in html_files:
  132. if img_in_html(os.path.join(html_dir, html_file), filename):
  133. img_html_files[filename] = html_file
  134. # for now suppose one image per html
  135. with open(os.path.join(html_dir, output_name), "w") as output:
  136. output.write(
  137. header1_tmpl.substitute(
  138. title="GRASS GIS %s Reference " "Manual: Manual gallery" % grass_version
  139. )
  140. )
  141. output.write(header_graphical_index_tmpl)
  142. output.write('<ul class="img-list">\n')
  143. for image, html_file in sorted(img_html_files.items()):
  144. name = get_module_name(html_file)
  145. title = title_from_names(name, image)
  146. output.write(
  147. "<li>"
  148. '<a href="{html}" title="{title}">'
  149. '<img src="{img}">'
  150. '<span class="name">{name}</span>'
  151. "</a>"
  152. "</li>\n".format(html=html_file, img=image, title=title, name=name)
  153. )
  154. output.write("</ul>")
  155. write_html_footer(output, "index.html", year)
  156. if __name__ == "__main__":
  157. main()