size: 2 KiB
| 1 | local djot = require("djot") |
| 2 | |
| 3 | local help = [[ |
| 4 | djot [opts] [file*] |
| 5 | |
| 6 | Options: |
| 7 | --matches -m Show matches. |
| 8 | --ast -a Show AST. |
| 9 | --json -j Use JSON for -m or -a. |
| 10 | --sourcepos -p Include source positions in AST. |
| 11 | --filter FILE -f FILE Filter AST using filter in FILE. |
| 12 | --verbose -v Verbose (show warnings). |
| 13 | --version Show version information. |
| 14 | --help -h Help. |
| 15 | ]] |
| 16 | |
| 17 | local function err(msg, code) |
| 18 | io.stderr:write(msg .. "\n") |
| 19 | os.exit(code) |
| 20 | end |
| 21 | |
| 22 | local opts = {} |
| 23 | local files = {} |
| 24 | |
| 25 | local shortcuts = |
| 26 | { m = "--matches", |
| 27 | a = "--ast", |
| 28 | j = "--json", |
| 29 | p = "--sourcepos", |
| 30 | v = "--verbose", |
| 31 | f = "--filter", |
| 32 | h = "--help" } |
| 33 | |
| 34 | local argi = 1 |
| 35 | while arg[argi] do |
| 36 | local thisarg = arg[argi] |
| 37 | local longopts = {} |
| 38 | if string.find(thisarg, "^%-%-%a") then |
| 39 | longopts[#longopts + 1] = thisarg |
| 40 | elseif string.find(thisarg, "^%-%a") then |
| 41 | string.gsub(thisarg, "(%a)", |
| 42 | function(x) |
| 43 | longopts[#longopts + 1] = shortcuts[x] or ("-"..x) |
| 44 | end) |
| 45 | else |
| 46 | files[#files + 1] = thisarg |
| 47 | end |
| 48 | for _,x in ipairs(longopts) do |
| 49 | if x == "--matches" then |
| 50 | opts.matches = true |
| 51 | elseif x == "--ast" then |
| 52 | opts.ast = true |
| 53 | elseif x == "--json" then |
| 54 | opts.json = true |
| 55 | elseif x == "--sourcepos" then |
| 56 | opts.sourcepos = true |
| 57 | elseif x == "--verbose" then |
| 58 | opts.verbose = true |
| 59 | elseif x == "--filter" then |
| 60 | if arg[argi + 1] then |
| 61 | opts.filters = opts.filters or {} |
| 62 | table.insert(opts.filters, arg[argi + 1]) |
| 63 | argi = argi + 1 |
| 64 | end |
| 65 | elseif x == "--version" then |
| 66 | io.stdout:write("djot " .. djot.version .. "\n") |
| 67 | os.exit(0) |
| 68 | elseif x == "--help" then |
| 69 | io.stdout:write(help) |
| 70 | os.exit(0) |
| 71 | else |
| 72 | err("Unknown option " .. x, 1) |
| 73 | end |
| 74 | end |
| 75 | argi = argi + 1 |
| 76 | end |
| 77 | |
| 78 | local inp |
| 79 | if #files == 0 then |
| 80 | inp = io.read("*all") |
| 81 | else |
| 82 | local buff = {} |
| 83 | for _,f in ipairs(files) do |
| 84 | local ok, msg = pcall(function() io.input(f) end) |
| 85 | if ok then |
| 86 | table.insert(buff, io.read("*all")) |
| 87 | else |
| 88 | err(msg, 7) |
| 89 | end |
| 90 | end |
| 91 | inp = table.concat(buff, "\n") |
| 92 | end |
| 93 | |
| 94 | local warn = function(warning) |
| 95 | if opts.verbose then |
| 96 | io.stderr:write(string.format("%s at byte position %d\n", |
| 97 | warning.message, warning.pos)) |
| 98 | end |
| 99 | end |
| 100 | |
| 101 | if opts.matches then |
| 102 | |
| 103 | io.stdout:write(djot.parse_and_render_events(inp, warn)) |
| 104 | |
| 105 | else |
| 106 | |
| 107 | local ast = djot.parse(inp, opts.sourcepos, warn) |
| 108 | |
| 109 | if opts.filters then |
| 110 | for _,fp in ipairs(opts.filters) do |
| 111 | local filt, err = djot.filter.require_filter(fp) |
| 112 | if filt then |
| 113 | djot.filter.apply_filter(ast, filt) |
| 114 | else |
| 115 | io.stderr:write("Error loading filter " .. fp .. ":\n" .. err .. "\n") |
| 116 | end |
| 117 | end |
| 118 | end |
| 119 | |
| 120 | if opts.ast then |
| 121 | if opts.json then |
| 122 | io.stdout:write(djot.render_ast_json(ast)) |
| 123 | else |
| 124 | io.stdout:write(djot.render_ast_pretty(ast)) |
| 125 | end |
| 126 | else |
| 127 | io.stdout:write(djot.render_html(ast)) |
| 128 | end |
| 129 | |
| 130 | end |
| 131 | |
| 132 | os.exit(0) |