colorize_lua.lua 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. --This file is taken from technomancy's polywell editor--
  2. -- Take a table of lines and turn it into a table of {color, string,
  3. -- color2, string2} which can be used by love.graphics.print.
  4. --Colors table keys:text,keyword,number,comment,str
  5. local lume = require("libraries.lume")
  6. local keywords = {"and", "break", "do", "else", "elseif", "end", "false",
  7. "for", "function", "if", "in", "local", "nil", "not", "or",
  8. "repeat", "return", "then", "true", "until", "while", }
  9. local colors, comment_match
  10. local function colorize_keyword(l, n, offset)
  11. -- hoo boy, not having access to | in lua patterns is a pain!
  12. -- if this code makes you cringe at the performance implications, just
  13. -- remember that luajit is faster than you could possibly hope for.
  14. -- (the longest file in the codebase, 1200 lines, colorizes in 0.3 seconds
  15. -- on a 2009-era core 2 duo thinkpad)
  16. if(n and n > #keywords) then return {colors.text, l} end
  17. local s,e = string.find(l, keywords[n or 1], offset, true)
  18. if(s and string.find(string.sub(l,s-1,s-1), "[%w_]") or
  19. (e and string.find(string.sub(l,e+1,e+1), "[%w_]"))) then
  20. -- if it's inside a larger word, no match!
  21. return colorize_keyword(l, n, e+1)
  22. elseif(s == 1) then
  23. return {colors.keyword, string.sub(l,1,e),
  24. unpack(colorize_keyword(string.sub(l, e+1)))}
  25. elseif(s) then
  26. local pre = colorize_keyword(string.sub(l,1, s-1))
  27. return lume.concat(pre, {colors.keyword, string.sub(l,s,e),
  28. unpack(colorize_keyword(string.sub(l,e+1))) })
  29. else
  30. return colorize_keyword(l, (n or 1) + 1)
  31. end
  32. end
  33. local function colorize_number(l, offset)
  34. -- TODO: scientific notation, hex
  35. local s,e = string.find(l, "[\\.0-9]+", offset)
  36. if(s and string.find(string.sub(l,s-1,s-1), "[%w_]")) then
  37. return colorize_number(l, e+1) -- no numbers at the end of identifiers
  38. elseif(s == 1) then
  39. return {colors.number, string.sub(l,1,e),
  40. unpack(colorize_number(string.sub(l, e+1)))}
  41. elseif(s) then
  42. local line = colorize_keyword(string.sub(l, 1, s-1))
  43. return lume.concat(line, {colors.number, string.sub(l,s,e),
  44. unpack(colorize_number(string.sub(l,e+1))) })
  45. else
  46. return colorize_keyword(l)
  47. end
  48. end
  49. local colorize_comment = function(l)
  50. comment_match = string.find(l, "[-][-]")
  51. if(comment_match == 1) then
  52. return {colors.comment, l}
  53. elseif(comment_match) then
  54. local line = colorize_number(string.sub(l, 1,comment_match-1))
  55. table.insert(line, colors.comment)
  56. table.insert(line, string.sub(l,comment_match))
  57. return line
  58. else
  59. return colorize_number(l)
  60. end
  61. end
  62. local function colorize_string(l)
  63. local s,e = string.find(l, "\"[^\"]*\"")
  64. if(s == 1) then
  65. return {colors.str, string.sub(l,1,e),
  66. unpack(colorize_comment(string.sub(l,e+1)))}
  67. elseif(s) then
  68. local pre = colorize_comment(string.sub(l, 1,s-1))
  69. if(comment_match) then
  70. table.insert(pre, colors.comment)
  71. table.insert(pre, string.sub(l,s))
  72. return pre
  73. else
  74. local post = colorize_string(string.sub(l,e+1))
  75. return lume.concat(pre, {colors.str, string.sub(l, s, e)}, post)
  76. end
  77. else
  78. return colorize_comment(l)
  79. end
  80. end
  81. return function(lines, color_table)
  82. colors = color_table
  83. local t = {}
  84. for _,l in ipairs(lines) do table.insert(t, colorize_string(l)) end
  85. return t
  86. end