sphinx-to-rst.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #!/usr/bin/even/python
  2. from __future__ import with_statement
  3. import os
  4. import re
  5. import sys
  6. dirname = ""
  7. RE_CODE_BLOCK = re.compile(r'.. code-block:: (.+?)\s*$')
  8. RE_INCLUDE = re.compile(r'.. include:: (.+?)\s*$')
  9. RE_REFERENCE = re.compile(r':(.+?):`(.+?)`')
  10. def include_file(lines, pos, match):
  11. global dirname
  12. orig_filename = match.groups()[0]
  13. filename = os.path.join(dirname, orig_filename)
  14. with file(filename) as fh:
  15. old_dirname = dirname
  16. dirname = os.path.dirname(orig_filename)
  17. try:
  18. lines[pos] = sphinx_to_rst(fh)
  19. finally:
  20. dirname = old_dirname
  21. def replace_code_block(lines, pos, match):
  22. lines[pos] = ""
  23. curpos = pos - 1
  24. # Find the first previous line with text to append "::" to it.
  25. while True:
  26. prev_line = lines[curpos]
  27. if not prev_line.isspace():
  28. prev_line_with_text = curpos
  29. break
  30. curpos -= 1
  31. if lines[prev_line_with_text].endswith(":"):
  32. lines[prev_line_with_text] += ":"
  33. else:
  34. lines[prev_line_with_text] += "::"
  35. TO_RST_MAP = {RE_CODE_BLOCK: replace_code_block,
  36. RE_REFERENCE: r'``\2``',
  37. RE_INCLUDE: include_file}
  38. def _process(lines):
  39. lines = list(lines) # non-destructive
  40. for i, line in enumerate(lines):
  41. for regex, alt in TO_RST_MAP.items():
  42. if callable(alt):
  43. match = regex.match(line)
  44. if match:
  45. alt(lines, i, match)
  46. line = lines[i]
  47. else:
  48. lines[i] = regex.sub(alt, line)
  49. return lines
  50. def sphinx_to_rst(fh):
  51. return "".join(_process(fh))
  52. if __name__ == "__main__":
  53. global dirname
  54. dirname = os.path.dirname(sys.argv[1])
  55. with open(sys.argv[1]) as fh:
  56. print(sphinx_to_rst(fh))