makes an ASCII-art comic in the style of webcomicname.com
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.

137 lines
4.0 KiB

5 years ago
5 years ago
  1. #!/usr/bin/env python
  2. # MIT License
  3. #
  4. # Copyright (c) 2019 Colin McMillen
  5. #
  6. # Permission is hereby granted, free of charge, to any person obtaining a copy
  7. # of this software and associated documentation files (the "Software"), to
  8. # deal in the Software without restriction, including without limitation the
  9. # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. # sell copies of the Software, and to permit persons to whom the Software is
  11. # furnished to do so, subject to the following conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be included in
  14. # all copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. # IN THE SOFTWARE.
  23. """makes an ASCII-art comic in the style of webcomicname.com."""
  24. import re
  25. import sys
  26. USAGE = """Usage:
  27. $ ohnosay.py "you can make a single panel of text"
  28. $ ohnosay.py "you can also make two panels" "but three isn't supported"
  29. """
  30. TEMPLATE = r'''
  31. /--------------------------\ |
  32. | aaaaaaaaaaaaaaaaaaaaaaaa | |
  33. \_ ________________________/ |
  34. v |
  35. _____ |
  36. / . . \ |
  37. \ | _ | / |
  38. v v |'''
  39. TO_REPLACE = 'aaaaaaaaaaaaaaaaaaaaaaaa'
  40. OH_NO = r'''
  41. /------\
  42. | ohno |
  43. \_ ____/
  44. v
  45. _____
  46. / . . \
  47. _ | _ | _
  48. v v'''
  49. def chunk_lines(s):
  50. """Splits a string into a list of lines that fit inside the speech bubble."""
  51. if len(s) <= len(TO_REPLACE):
  52. return [s]
  53. try:
  54. split_position = s[:len(TO_REPLACE) + 1].rindex(' ')
  55. except ValueError: # some word is too big to fit! oh no
  56. split_position = len(TO_REPLACE)
  57. return [s[:split_position]] + chunk_lines(s[split_position + 1:])
  58. def main(args):
  59. """does some things. oh no"""
  60. if not args:
  61. print USAGE
  62. return
  63. single_panel = False
  64. if len(args) == 1:
  65. single_panel = True
  66. args.append('')
  67. lines_1 = chunk_lines(args[0])
  68. lines_2 = chunk_lines(args[1])
  69. # the user input has to be at least two lines tall, because the final 'oh no'
  70. # panel is two lines tall and cutting out the second line would be... oh no
  71. if len(lines_1) == 1:
  72. lines_1.append('')
  73. # incredibly cheesy vertical centering
  74. while len(lines_1) < len(lines_2):
  75. if len(lines_1) == len(lines_2) - 1:
  76. lines_1.append('')
  77. else:
  78. lines_1 = [''] + lines_1 + ['']
  79. while len(lines_2) < len(lines_1):
  80. if len(lines_2) == len(lines_1) - 1:
  81. lines_2.append('')
  82. else:
  83. lines_2 = [''] + lines_2 + ['']
  84. # now both lines are the same length
  85. num_lines = len(lines_1)
  86. comic = re.sub('-', u'\u203e', TEMPLATE).split('\n')
  87. oh_no = re.sub('-', u'\u203e', OH_NO).split('\n')
  88. # this got hacky and gross. oh no
  89. for i, _ in enumerate(comic):
  90. if i == 2:
  91. for j in xrange(num_lines):
  92. left_centered = lines_1[j].center(len(TO_REPLACE))
  93. left = re.sub(TO_REPLACE, left_centered, comic[2])
  94. middle_centered = lines_2[j].center(len(TO_REPLACE))
  95. middle = re.sub(TO_REPLACE, middle_centered, comic[2])
  96. if single_panel:
  97. middle = ''
  98. if j == num_lines - 3:
  99. print left + middle + oh_no[1]
  100. elif j == num_lines - 2:
  101. print left + middle + ' | oh |'
  102. elif j == num_lines - 1:
  103. print left + middle + ' | no |'
  104. else:
  105. print left + middle
  106. else:
  107. oh_no_line = oh_no[i]
  108. if num_lines > 2 and i == 1:
  109. oh_no_line = ''
  110. if single_panel:
  111. print comic[i] + oh_no_line
  112. else:
  113. print comic[i] + comic[i] + oh_no_line
  114. if __name__ == '__main__':
  115. main(sys.argv[1:])