markdown.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. # THIS SOFTWARE IS A PART OF FASTLBRY PROJECT
  2. # THIS SPECIFIC FILE IS UNDER GNU GPLv3 or later
  3. import os
  4. from subprocess import *
  5. ################################################################################
  6. # Markdown. Or .md file format is an easy way to give your simple text documents
  7. # a bit of flare. Stuff like links, images and quotes are supported. Also bold
  8. # an italic characters.
  9. def Open(md):
  10. # Spliting it for the read.
  11. md = "\n\n"+md
  12. md = md.split("\n")
  13. # First thing is I was to read the headings and convert it into a tree.
  14. tree = []
  15. indent = 1
  16. c = []
  17. skip = 0
  18. for n,line in enumerate(md):
  19. if skip > n:
  20. continue
  21. ty = "text"
  22. te = line
  23. # Here I want to simply get a type of each line. Later we going to parse
  24. # the links and other things. But first. Let's parse stuff based on
  25. # lines.
  26. if line.startswith("```"):
  27. # THREE ``` aka code block
  28. # This tag will block any other tags
  29. # untill it's untagged
  30. code = ""
  31. print("#####", n)
  32. for l in md[n+1:]:
  33. if not l.startswith("```"):
  34. code = code + l + "\n"
  35. else:
  36. skip = n + code.count("\n") + 2
  37. break
  38. print("!!!!!!!!!", skip)
  39. tree.append(["text_cm", code+"\n"])
  40. te = ""
  41. elif line.startswith("#"):
  42. # The titles of the chapter. The Headers are usually written similar
  43. # to how here in python you write comments. It's a # , space, and the
  44. # text.
  45. # The amount of hashes. ## or ### gives different sized text. Officialy
  46. # it should support up to 6 hashes. ######. But why not make it more
  47. # just in case.
  48. ty = line.count("#") # This might give bugs
  49. elif line.startswith(">"):
  50. # The > sign in the Markdown language is used for quatations.
  51. ty = "text_q"
  52. te = te[1:]
  53. tree.append([ty, te+"\n"])
  54. # Now the stage 0 is over and we parsed the basic things. Now is the hard
  55. # part to parse out all the images and stuff inside them. It's going to be
  56. # done per part. And we are going to use the same technique I used for the
  57. # conversion of the legacy projects. See : studio/story.py ( in VCStudio )
  58. # We are going to itterate over each letter. And decide what to do by that
  59. newtree = []
  60. for block in tree:
  61. if block[0] == "text_cm":
  62. newtree.append(block)
  63. continue
  64. part = ""
  65. skip = 0
  66. for n, l in enumerate(block[-1]):
  67. if skip > n:
  68. continue
  69. part = part + l
  70. # Here we are going to do something if a give condition is met.
  71. # Usually I gonna do something if [part] ends with a given markdown
  72. # thing. I don't have a manual of markdown on me. So please make it
  73. # more supported. I guess. I might forget things I rarely use.
  74. # Links are made with [stuff you click on](https://example.com)
  75. # but similar to it. Images are done ![Tooltip](Image.png)
  76. # and even weirder you can put one into the other. Like
  77. # [![Tooltip](Image.png)](https://example.com)
  78. # Which going to give you a clickable image.
  79. # For this version what we are going to do is next.
  80. # If we got [![ then it's a clickable image
  81. # If we got ![ then it's just image
  82. # and if we got [ then it's a link.
  83. if part.endswith("[!["):
  84. # IMAGE LINK
  85. newtree.append([block[0], part[:-3]])
  86. tooltip = ""
  87. imageurl = ""
  88. url = ""
  89. t = False
  90. iu = False
  91. skip = n
  92. for le in block[-1][n:]: # For letters in the rest of text
  93. skip = skip + 1
  94. if le == "]":
  95. t = True
  96. elif le == ")" and t and not iu:
  97. iu = True
  98. elif le == ")" and t and iu:
  99. break
  100. elif not t:
  101. tooltip = tooltip +le
  102. elif t and not iu:
  103. imageurl = imageurl + le
  104. else:
  105. url = url+le
  106. tooltip = tooltip[tooltip.find("[")+1:]
  107. imageurl = imageurl[imageurl.find("(")+1:]
  108. url = url[url.find("(")+1:]
  109. apnd = ["image_link", imageurl, url]
  110. newtree.append(apnd)
  111. part = ""
  112. elif part.endswith("!["):
  113. # IMAGE
  114. newtree.append([block[0], part[:-2]])
  115. tooltip = ""
  116. url = ""
  117. t = False
  118. skip = n
  119. for le in block[-1][n:]: # For letters in the rest of text
  120. skip = skip + 1
  121. if le == "]":
  122. t = True
  123. elif le == ")" and t:
  124. break
  125. elif not t:
  126. tooltip = tooltip +le
  127. else:
  128. url = url+le
  129. tooltip = tooltip[tooltip.find("[")+1:]
  130. url = url[url.find("(")+1:]
  131. apnd = ["image", "[IMAGE]", url]
  132. newtree.append(apnd)
  133. part = ""
  134. elif part.endswith("[") and not block[-1][n:].startswith('[!['):
  135. # LINK
  136. newtree.append([block[0], part[:-1]])
  137. tooltip = ""
  138. url = ""
  139. t = False
  140. skip = n
  141. for le in block[-1][n:]: # For letters in the rest of text
  142. skip = skip + 1
  143. if le == "]":
  144. t = True
  145. elif le == ")" and t:
  146. break
  147. elif not t:
  148. tooltip = tooltip +le
  149. else:
  150. url = url+le
  151. tooltip = tooltip[tooltip.find("[")+1:]
  152. url = url[url.find("(")+1:]
  153. apnd = ["link", tooltip, url]
  154. newtree.append(apnd)
  155. part = ""
  156. # Now I want to deal with `, *, ** and ***. If you want to help me you
  157. # can implement other types. Such as _, __, ___ and so on. Markdown is
  158. # a very rich language. I'm going to use the cut down version I see other
  159. # people use.
  160. # BTW this is the time. Feb 28. When I switched from Gedit to GNU Emacs.
  161. # Interesting feeling using this programm. I kind a love it even tho
  162. # so many stuff in not intuitive. Like saving is not Ctrl - S but
  163. # Ctrl - X -> Ctrl - S.
  164. # Things like Alt-; to comment multiple lines at ones is HUGE. Also it
  165. # was built by programmers for programmers. So it's a very good tool.
  166. elif part.endswith("**") and not block[-1][n+2:].startswith('*'):
  167. # DOUBLE **
  168. newtree.append([block[0], part[:-2]])
  169. if block[0] == "text":
  170. block[0] = "text_b"
  171. else:
  172. block[0] = "text"
  173. part = ""
  174. elif part.endswith("*") and not block[-1][n+1:].startswith('*'):
  175. # SINGLE *
  176. newtree.append([block[0], part[:-1]])
  177. if block[0] == "text":
  178. block[0] = "text_i"
  179. else:
  180. block[0] = "text"
  181. part = ""
  182. elif part.endswith("`"):
  183. # SINGLE `
  184. newtree.append([block[0], part[:-1]])
  185. if block[0] == "text":
  186. block[0] = "text_c"
  187. else:
  188. block[0] = "text"
  189. part = ""
  190. newtree.append([block[0], part])
  191. #newtree.append(["text", "\n"*20+" [END OF DOCUMENT] "])
  192. tree = newtree
  193. return(tree)
  194. def search_convert(s):
  195. # This function convers a chapter name into a link
  196. # such links are use in notabug.org to link to chapters
  197. # for example example.com/file.md#chapter-name
  198. # With this url it will load the example.com/file.md and
  199. # then skip to the "Chapter Name" chapter.
  200. # This function transforms "Chapter Name" into "chapter-name"
  201. l = " ./\|[]{}()?!@#$%^&*`~:;'\"=,<>"
  202. s = s.lower().replace(" ","-")
  203. r = ""
  204. for i in s:
  205. if i not in l:
  206. r = r + i
  207. return r
  208. def convert(filename):
  209. textReturn = ""
  210. text = open(filename)
  211. text = text.read()
  212. md = Open(text)
  213. for i in md:
  214. if type(i[0]) == str and i[0].startswith("text") and not i[0] == "text_cm":
  215. tag = ""
  216. ctag = ""
  217. for f in ["i", "b", "c"]:
  218. if f in i[0]:
  219. f.replace("c", "code").replace("q", "blockquote")
  220. tag = "<"+f+">"
  221. ctag = "</"+f+">"
  222. if i[-1].startswith("lbry://"):
  223. tag = '<a href="https://odysee.com/'+i[-1].replace("lbry://", "")[:-1]+'">'
  224. ctag = "</a>"
  225. if i[-1].startswith("http"):
  226. tag = '<a href="'+i[-1][:-1]+'">'
  227. ctag = "</a>"
  228. textReturn = textReturn + tag + i[-1] + ctag
  229. elif i[0] == "text_cm":
  230. tag = "<code>"
  231. ctag = "</code>"
  232. textReturn = textReturn + tag + i[-1] + ctag
  233. elif type(i[0]) == int:
  234. textReturn = textReturn + "<br><br><h"+str(i[0])+">" + i[-1].replace("#", "") +"</h"+str(i[0])+"><br><br>"
  235. elif i[0] == "image_link":
  236. textReturn = textReturn + '<center><a href="'+i[-1]+'">'+'<img src="'+i[1]+'">'+"</a></center>"
  237. elif i[0] == "image":
  238. textReturn = textReturn + '<center><img src="'+i[-1]+'"></center>'
  239. elif i[0] == "link":
  240. textReturn = textReturn + '<a href="'+i[-1]+'">'+i[1]+"</a>"
  241. textReturn = textReturn.replace("\n", "<br>")
  242. return textReturn