markupthrough.lua 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #! /usr/bin/env lua
  2. --
  3. -- Sample GMarkupParser which parses input into the table. Expects
  4. -- name of the markup file on the commandline.
  5. --
  6. local io = require 'io'
  7. local lgi = require 'lgi'
  8. local GLib = lgi.GLib
  9. local assert = lgi.assert
  10. local function make_parser(doc)
  11. local stack = { doc }
  12. local parser = GLib.MarkupParser {
  13. start_element = function(context, tag, attr)
  14. local element = { tag = tag, attr = attr }
  15. stack[#stack + 1] = element
  16. end,
  17. text = function(context, text)
  18. -- Avoid just whitespace.
  19. if text:match('%S') then
  20. local element = stack[#stack]
  21. element[#element + 1] = text
  22. end
  23. end,
  24. end_element = function(context)
  25. local parent = stack[#stack - 1]
  26. parent[#parent + 1] = stack[#stack]
  27. stack[#stack] = nil
  28. end,
  29. }
  30. return parser
  31. end
  32. local function dump_element(result, element, indent)
  33. result[#result + 1] = ('%s<%s'):format(indent, element.tag)
  34. for name, value in pairs(element.attr) do
  35. if type(name) == 'string' then
  36. result[#result + 1] = (' %s=\'%s\''):format(
  37. name, GLib.markup_escape_text(value))
  38. end
  39. end
  40. if #element == 0 then
  41. result[#result + 1] = '/>\n'
  42. else
  43. result[#result + 1] = '>\n'
  44. for i = 1, #element do
  45. if type(element[i]) == 'table' then
  46. dump_element(result, element[i], indent .. ' ')
  47. else
  48. result[#result + 1] = GLib.markup_escape_text(element[i])
  49. result[#result + 1] = '\n'
  50. end
  51. end
  52. result[#result + 1] = ('%s</%s>\n'):format(indent, element.tag)
  53. end
  54. end
  55. local function dump_doc(doc)
  56. local buffer = {}
  57. dump_element(buffer, doc[1], '')
  58. return table.concat(buffer)
  59. end
  60. -- Parse standard input.
  61. local document = {}
  62. local parser = make_parser(document)
  63. local context = GLib.MarkupParseContext(parser, 'TREAT_CDATA_AS_TEXT')
  64. for line in io.lines((...), 512) do
  65. assert(context:parse(line))
  66. end
  67. context:end_parse()
  68. print(dump_doc(document))