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.

138 lines
4.1 KiB

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