render.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/env python3
  2. """
  3. A Python script to generate a single PDF document with all the `tldr` pages. It works by generating
  4. intermediate HTML files from existing md files using Python-markdown, applying desired formatting
  5. through CSS, and finally rendering them as PDF. There is no LaTeX dependency for generating the PDF.
  6. """
  7. import os
  8. import sys
  9. import glob
  10. import re
  11. import markdown
  12. import argparse
  13. from datetime import datetime
  14. from weasyprint import HTML
  15. def main(loc, colorscheme):
  16. oslist = []
  17. allmd = []
  18. group = []
  19. ap = []
  20. # Checking correctness of path
  21. if not os.path.isdir(loc):
  22. print("Invalid directory. Please try again!", file=sys.stderr)
  23. sys.exit(1)
  24. # Writing names of all directories inside 'pages' to a list
  25. for os_dir in os.listdir(loc):
  26. oslist.append(os_dir)
  27. oslist.sort()
  28. # Required strings to create intermediate HTML files
  29. header = '<!doctype html><html><head><meta charset="utf-8"><link rel="stylesheet" href="basic.css">'
  30. if colorscheme != "basic":
  31. header += '<link rel="stylesheet" href="' + colorscheme + '.css"></head><body>\n'
  32. header += "</head><body>\n"
  33. footer = "</body></html>"
  34. title_content = "<h1 class=title-main>tldr pages</h1>" \
  35. + "<h4 class=title-sub>Simplified and community-driven man pages</h4>" \
  36. + "<h6 class=title-sub><em><small>Generated on " + datetime.now().strftime("%c") + "</small></em></h6>" \
  37. + "</body></html>"
  38. # Creating title page
  39. with open("title.html", "w") as f:
  40. f.write(header + title_content)
  41. group.append(HTML("title.html").render())
  42. for operating_sys in oslist:
  43. i = 1
  44. # Required string to create directory title pages
  45. dir_title = "<h2 class=title-dir>" + \
  46. operating_sys.capitalize() + "</h2></body></html>"
  47. # Creating directory title page for current directory
  48. with open("dir_title.html", "w") as os_html:
  49. os_html.write(header + dir_title)
  50. group.append(HTML("dir_title.html").render())
  51. # Creating a list of all md files in the current directory
  52. for temp in glob.glob(os.path.join(loc, operating_sys, "*.md")):
  53. allmd.append(temp)
  54. # Sorting all filenames in the directory, to maintain the order of the PDF
  55. allmd.sort()
  56. # Conversion of Markdown to HTML
  57. for page_number, md in enumerate(allmd, start=1):
  58. with open(md, "r") as inp:
  59. text = inp.readlines()
  60. with open("htmlout.html", "w") as out:
  61. out.write(header)
  62. for line in text:
  63. if re.match(r'^>', line):
  64. line = line[:0] + '####' + line[1:]
  65. html = markdown.markdown(line)
  66. out.write(html)
  67. out.write(footer)
  68. group.append(HTML("htmlout.html").render())
  69. print("Rendered page {} of the directory {}".format(
  70. str(i), operating_sys))
  71. i += 1
  72. allmd.clear()
  73. # Merging all the documents into a single PDF
  74. for doc in group:
  75. for p in doc.pages:
  76. ap.append(p)
  77. # Writing the PDF to disk, preserving metadata of first `tldr` page
  78. group[2].copy(ap).write_pdf('tldr-pages.pdf')
  79. if os.path.exists("tldr-pages.pdf"):
  80. print("\nCreated tldr-pages.pdf in the current directory!\n")
  81. # Removing unnecessary intermediate files
  82. try:
  83. os.remove("htmlout.html")
  84. os.remove("title.html")
  85. os.remove("dir_title.html")
  86. except OSError:
  87. print("Error removing temporary file(s)")
  88. if __name__ == "__main__":
  89. # Parsing the arguments
  90. parser = argparse.ArgumentParser(prog="tdlr-pages-to-PDF", description="A Python script to generate a single PDF document with all the `tldr` pages.")
  91. parser.add_argument("dir_path", help = "Path to the 'pages' directory")
  92. parser.add_argument("-c", "--color", choices=["solarized-light", "solarized-dark", "basic"], default="basic", help="Color scheme of the PDF")
  93. args = parser.parse_args()
  94. main(args.dir_path, args.color)