PageRenderTime 37ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/gsub.wlua

http://github.com/stuartpb/txtoolbox
Unknown | 199 lines | 172 code | 27 blank | 0 comment | 0 complexity | 1d7d2ef6c6b0a468c54d27dc2374fbf5 MD5 | raw file
  1. local iup = require "iuplua"
  2. local function text(multiline)
  3. return iup.text{
  4. font="Consolas, 8",
  5. multiline=multiline and "YES" or "NO",
  6. --formatting="yes",
  7. autohide="yes",
  8. expand=multiline and "yes" or "horizontal"}
  9. end
  10. local input = text(true)
  11. local output = text(true)
  12. output.readonly = "yes"
  13. local pattern_tb = text()
  14. local repl_tb = text()
  15. local escapes_tog = iup.toggle{title="Escapes"}
  16. local plain_tog = iup.toggle{title="Plain"}
  17. local nr = iup.normalizer{escapes_tog,plain_tog,NORMALIZE="HORIZONTAL"}
  18. local nr2 = iup.normalizer{pattern_tb,repl_tb,NORMALIZE="HORIZONTAL"}
  19. local function depat_s(s)
  20. return string.gsub(s,"%W","%%%0")
  21. end
  22. local escape_s; do
  23. local specchars={
  24. a='\a',
  25. b='\b',
  26. f='\f',
  27. n='\n',
  28. r='\r',
  29. t='\t',
  30. v='\v',
  31. }
  32. local function escape_c(c,ctd)
  33. if specchars[c] then
  34. return specchars[c]..ctd
  35. elseif string.match(c,"%d") then
  36. local ctd, xctd = string.match(ctd, "^(%d*)(%D*)")
  37. local escapebyte = tonumber(c..ctd,10)
  38. if escapebyte > 255 then
  39. --Lua's parser would throw this error:
  40. --escape sequence too large near '"(preceding text)'
  41. --Tossing away the third digit circumvents any errors...
  42. --as ridiculous as it looks.
  43. xctd = string.sub(ctd,2)
  44. ctd = string.sub(ctd,1,1)
  45. escapebyte = tonumber(c..ctd,10)
  46. end
  47. return string.char(escapebyte) .. xctd
  48. elseif c == "x" then
  49. --another dumb not-an-error case.
  50. if ctd == "" then return "x"
  51. else
  52. return string.char(tonumber(ctd,16))
  53. end
  54. else
  55. --just return the literal of whatever's after the slash
  56. return c .. ctd
  57. end
  58. end
  59. function escape_s(s)
  60. return string.gsub(s,"\\(.)(%x?%x?)",escape_c)
  61. end
  62. end
  63. local function rungsub()
  64. local pattern = pattern_tb.value
  65. local repl = repl_tb.value
  66. local function iftogfit(tog,f)
  67. if tog.value=="ON" then
  68. pattern = f(pattern)
  69. repl = f(repl)
  70. end
  71. end
  72. iftogfit(escapes_tog, escape_s)
  73. iftogfit(plain_tog, depat_s)
  74. output.value = string.gsub(
  75. input.value, pattern, repl)
  76. end
  77. local runb = iup.button{title="Run",
  78. expand="horizontal", action=rungsub}
  79. --File menu functions
  80. local function file_dlg(
  81. dlg_type, dlg_title, dlg_extfilter,
  82. filename_operation)
  83. local filedlg = iup.filedlg{
  84. dialogtype = dlg_type,
  85. title = dlg_title,
  86. extfilter = dlg_extfilter
  87. }
  88. filedlg:popup()
  89. local status = tonumber(filedlg.status)
  90. if status > -1 then --not canceled
  91. filename_operation(filedlg.value)
  92. end
  93. end
  94. local function file_contents(filename)
  95. local fhandle = assert(
  96. io.open(filename, 'r'))
  97. local r = fhandle:read"*a"
  98. fhandle:close()
  99. return r
  100. end
  101. local function write_str_to_file(str,filename)
  102. local fhandle = assert(
  103. io.open(filename, 'w'))
  104. fhandle:write(str)
  105. fhandle:close()
  106. end
  107. local function save_textbox(
  108. dlg_title, dlg_extfilter, srctext)
  109. file_dlg("SAVE",
  110. dlg_title, dlg_extfilter,
  111. function(filename)
  112. write_str_to_file(srctext.value, filename)
  113. end)
  114. end
  115. local function recycle()
  116. input.value=output.value
  117. output.value=""
  118. end
  119. local function openinput()
  120. file_dlg("OPEN",
  121. "Open Source Text",
  122. "All Files|*.*|",
  123. function(filename)
  124. input.value = file_contents(filename)
  125. end)
  126. end
  127. local function saveoutput()
  128. save_textbox("Save Output",
  129. "All Files|*.*|",
  130. output)
  131. end
  132. local menu = iup.menu{
  133. {"File",iup.menu{
  134. iup.item{title="Open Input...",
  135. action=openinput},
  136. iup.item{title="Save Output...",
  137. action=saveoutput},
  138. {},
  139. iup.item{title="Exit",
  140. action=iup.ExitLoop},
  141. }},
  142. }
  143. --Dialog creation and display
  144. local dlg = iup.dialog{
  145. title="string.gsub",
  146. menu=menu,
  147. size="HALFxHALF",
  148. shrink="yes";
  149. iup.split{
  150. orientation="HORIZONTAL",
  151. --showgrip="no";
  152. iup.vbox{alignment="ACENTER"; gap="3x3"; nmargin="3x3";
  153. input,
  154. iup.hbox{alignment="ACENTER";
  155. iup.label{title="Pattern:"},
  156. pattern_tb,
  157. escapes_tog
  158. },
  159. iup.hbox{alignment="ACENTER";
  160. iup.label{title="Replacement:"},
  161. repl_tb,
  162. plain_tog
  163. },
  164. },
  165. iup.vbox{alignment="ACENTER"; gap="3x3"; nmargin="3x3";
  166. runb,
  167. output
  168. }
  169. }
  170. }
  171. dlg:show()
  172. iup.MainLoop()