The source code for https://takoshell.org
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.

make_site.py 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env python3
  2. import os
  3. import re
  4. from collections import OrderedDict
  5. CURRENT_VERSION = '0.2.7'
  6. PAGES = OrderedDict()
  7. PAGES['index'] = {'toc': False, 'menu': 'Home', 'dotitle': False}
  8. PAGES['download'] = {'toc': True, 'menu': 'Download/Install'}
  9. PAGES['documentation'] = {'toc': True, 'menu': 'Documentation'}
  10. PAGES['contact'] = {'toc': False, 'menu': 'Contact'}
  11. PAGES['development'] = {'raw': 'https://hz.mit.edu/git/tako/tako', 'menu': 'Development', 'post':''}
  12. PAGES['xonsh'] = {'toc': False, 'menu': None}
  13. SRCDIR = os.path.join(os.path.dirname(__file__), 'source')
  14. TEMPLATE = open(os.path.join(SRCDIR, 'TEMPLATE.HTML')).read()
  15. HEADER_REGEX = re.compile(r'<h(?P<level>[34])>(?P<title>.*?)</h(?P=level)>', re.MULTILINE|re.DOTALL)
  16. def make_toc_html(toc):
  17. links = []
  18. for (major, minor, title) in toc:
  19. link = str(major)
  20. pref = ''
  21. if minor != -1:
  22. link = '%s_%s' % (link, minor)
  23. pref = '&nbsp;'*4
  24. label = link.replace('_', '.')
  25. if len(toc) >= 10 and major < 10:
  26. label = '0%s' % label
  27. links.append('%s%s) <a href="#section_%s">%s</a>' % (pref, label, link, title))
  28. return '\n<br/>'.join(links)
  29. def do_toc(text):
  30. toc = []
  31. nummaj = len([i for i in re.finditer(HEADER_REGEX, text) if i.group(1) == '3'])
  32. major = 0
  33. minor = None
  34. def _toc_helper(m):
  35. nonlocal major, minor
  36. level = int(m.group(1))
  37. title = m.group(2)
  38. if level == 3:
  39. minor = -1
  40. major += 1
  41. else:
  42. minor = 1 if minor == -1 else minor + 1
  43. tag = 'h%d' % level
  44. link = str(major)
  45. if minor != -1:
  46. link = '%s_%s' % (link, minor)
  47. label = link.replace('_', '.')
  48. if nummaj >= 10 and major < 10:
  49. label = '0%s' % label
  50. toc.append((major, minor, title))
  51. return '<a name="section_%s" />\n<%s>%s) %s</%s>' % (link, tag, label, title, tag)
  52. out = re.sub(HEADER_REGEX, _toc_helper, text)
  53. out = out.replace('_TAKO_TOC', make_toc_html(toc))
  54. return out
  55. def get_menu_entry(i, active):
  56. p = PAGES[i]
  57. title = p['menu']
  58. if active == i:
  59. return title
  60. newwindow = True
  61. rawlink = p.get('raw', None)
  62. if rawlink is None:
  63. newwindow = False
  64. rawlink = '%s.html' % i
  65. post = p.get('post', '')
  66. return '<a href="%s"%s>%s</a>%s' % (rawlink, ' target="_blank"' if newwindow else '',title,post)
  67. def make_menu(active):
  68. ps = [get_menu_entry(i, active) for i in PAGES if PAGES[i].get('menu', False)]
  69. return "&nbsp;|&nbsp;\n".join(ps)
  70. def colorize_one(match, color='#6d00ba'):
  71. return '<span style="font-weight:bold;color:%s;">%s</span>' % (color, match.group(0))
  72. def colorize_prompts(text):
  73. text = re.sub('\n>>>', colorize_one, text)
  74. text = re.sub('\n(~|bash|hey|[0-9]).*? (\$|#)', colorize_one, text)
  75. text = re.sub('\n\.+', colorize_one, text)
  76. text = re.sub('\n\$', colorize_one, text)
  77. return text.replace('">\n','">',1)
  78. def colorize_prompts_in_pre(text):
  79. return re.sub(re.compile('<pre>(.*?)</pre>', re.MULTILINE|re.DOTALL),
  80. lambda x: '<pre>%s</pre>' % colorize_prompts(x.group(1)),
  81. text)
  82. def do_page(name):
  83. if name not in PAGES:
  84. raise Exception('%s not in PAGES' % name)
  85. fname = os.path.join(SRCDIR, '%s.html' % name)
  86. if not os.path.isfile(fname):
  87. raise Exception('no file %s' % fname)
  88. p = PAGES[name]
  89. body = open(fname).read()
  90. body = body % {'version': CURRENT_VERSION}
  91. body = colorize_prompts_in_pre(body)
  92. if p.get('toc', False):
  93. body = do_toc(body)
  94. bigname = p.get('menu', None)
  95. title = 'The Tako Shell'
  96. if bigname is not None and p.get('dotitle', True):
  97. title = '%s | %s' % (bigname, title)
  98. menu = make_menu(name)
  99. return TEMPLATE % {'body': body, 'menu': menu, 'title': title}
  100. for i in PAGES:
  101. if PAGES[i].get('raw', None):
  102. continue
  103. realname = os.path.join(SRCDIR, '..', '%s.html' % i)
  104. with open(realname, 'w') as f:
  105. f.write(do_page(i))