You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
3.2 KiB

  1. #!/usr/bin/env python3
  2. # Usage:
  3. #
  4. # cd ~/src/www-builder
  5. # python3 build.py
  6. # cd output
  7. # cp -r * ~/src/www-home
  8. # cd ~/src/www-home
  9. # git status
  10. # git add [some stuff]
  11. # git commit
  12. # git push
  13. # TODO: replace gallery.tinyletterapp.com images with locally hosted content.
  14. # TODO: in template.html, add apple touch icon, maybe other favicon sizes.
  15. # TODO: local mirrors of all papers in publications.html
  16. import glob
  17. import markdown
  18. import os
  19. import re
  20. import shutil
  21. input_directory = 'content'
  22. static_directory = 'static'
  23. output_directory = 'output'
  24. md_extensions = ['fenced_code', 'codehilite', 'nl2br', 'toc', 'smarty', 'tables', 'linkify']
  25. def print_file(in_file, out_file):
  26. print('%-62s -> %s' % (in_file, out_file))
  27. def copy_static_files():
  28. for (dirpath, _, filenames) in os.walk(static_directory):
  29. for filename in filenames:
  30. source = os.path.join(dirpath, filename)
  31. out_path = dirpath.replace(static_directory, '', 1)
  32. out_path = out_path.lstrip('/')
  33. dest_dir = os.path.join(output_directory, out_path)
  34. os.makedirs(dest_dir, exist_ok=True)
  35. dest = os.path.join(dest_dir, filename)
  36. print_file(source, dest)
  37. shutil.copy2(source, dest)
  38. def process_markdown_files():
  39. template = open('template.html').read()
  40. for (dirpath, _, filenames) in os.walk(input_directory):
  41. for filename in filenames:
  42. markdown_filename = os.path.join(dirpath, filename)
  43. if not markdown_filename.endswith('.md'):
  44. continue
  45. markdown_file = open(markdown_filename)
  46. text = markdown_file.read()
  47. markdown_file.close()
  48. if not text.startswith('# '):
  49. text = '# ' + text
  50. match = re.match(r'^(.*?)\n', text)
  51. if match:
  52. title = match.group(1).lstrip('# ')
  53. else:
  54. title = text
  55. title += ' | Colin McMillen'
  56. if markdown_filename == os.path.join(input_directory, 'index.md'):
  57. title = 'Colin McMillen'
  58. out_filename = os.path.basename(markdown_filename).replace('.md', '.html')
  59. out_dirpath = os.path.join(output_directory, dirpath)
  60. out_dirpath = out_dirpath.replace('/content', '', 1)
  61. out_fullpath = os.path.join(out_dirpath, out_filename)
  62. page_url = out_fullpath.replace('output/', '', 1)
  63. if page_url.endswith('index.html'): # strip off index.html
  64. page_url = page_url[:-len('index.html')]
  65. html = markdown.markdown(text, extensions=md_extensions, output_format='html5')
  66. output = template.format(title=title, content=html, page_url=page_url)
  67. os.makedirs(out_dirpath, exist_ok=True)
  68. print_file(markdown_filename, out_fullpath)
  69. out_file = open(out_fullpath, 'w')
  70. out_file.write(output)
  71. out_file.close()
  72. def make_sitemap():
  73. sitemap_command = ' '.join("""
  74. find output -regextype posix-extended -regex '.*.(html|pdf)$' |
  75. grep -v ^output/google |
  76. grep -v ^output/drafts |
  77. perl -pe 's|output|https://www.mcmillen.dev|'
  78. > output/sitemap.txt""".split('\n'))
  79. os.system(sitemap_command)
  80. def make_rss(): # TODO: implement.
  81. pass
  82. def main():
  83. os.makedirs(output_directory, exist_ok=True)
  84. copy_static_files()
  85. process_markdown_files()
  86. make_sitemap()
  87. make_rss()
  88. if __name__ == '__main__':
  89. main()