-- pandoc-aware object dumper -- helper function to return a sensible typename -- XXX is there a better way of doing this? using metatables? local function getTypename(value) local typ = type(value) if typ == 'table' and value.tag and value.t then return value.tag elseif typ == 'userdata' then if value.tag and value.t then return value.tag else -- e.g., Attributes is userdata but doesn't have tag and t return typ end else return typ end end -- helper function -- note: don't use anything from the pandoc module (so can test standalone) -- XXX should detect repetition/recursion -- XXX would like maxlen logic to apply at all levels? but not trivial local function helper(prefix, value, maxlen, level, add) local buffer = {} if prefix == nil then prefix = '' end if level == nil then level = 0 end if add == nil then add = function(item) table.insert(buffer, item) end end local indent = maxlen and '' or (' '):rep(level) local typename = getTypename(value) local typ = (({boolean=1, number=1, string=1, table=1, userdata=1}) [typename] and '' or typename) if ({table=1, userdata=1})[type(value)] then local numKeys, lastKey = 0, nil for key, val in pairs(value) do -- pandoc >= 2.15 includes 'tag', nil values and functions if key ~= 'tag' and val and type(val) ~= 'function' then numKeys = numKeys + 1 lastKey = key end end if numKeys == 0 then -- XXX this wouldn't be needed with proper maxlen handling value = '{}' elseif numKeys == 1 and lastKey == 'content' then typ = string.format('content: %s', typ) value = value.content elseif numKeys == 1 and lastKey == 'text' and typename == 'Str' then typename = 'string' typ = 'Str text:' value = value.text end end local presep = #prefix > 0 and ' ' or '' local typsep = #typ > 0 and ' ' or '' local valtyp = type(value) if ({boolean=1, number=1, string=1})[valtyp] then local fmt = typename == 'string' and '%q' or '%s' add(string.format('%s%s%s%s%s' .. fmt, indent, prefix, presep, typ, typsep, value)) elseif ({table=1, userdata=1})[valtyp] then add(string.format('%s%s%s%s%s{', indent, prefix, presep, typ, typsep)) -- Attr and Attr.attributes have both numeric and string keys, so -- ignore the numeric ones (no longer the case for pandoc >= 2.15?) if prefix ~= 'attributes:' and typ ~= 'Attr' then for i, val in ipairs(value) do local pre = maxlen and i > 1 and ', ' or '' local text = helper(string.format('%s[%s]', pre, i), val, maxlen, level + 1, add) end end local first = true for key, val in pairs(value) do -- pandoc >= 2.15 includes 'tag' if not tonumber(key) and key ~= 'tag' then local pre = maxlen and not first and ', ' or '' local text = helper(string.format('%s%s:', pre, key), val, maxlen, level + 1, add) end first = false end add(string.format('%s}', indent)) end return table.concat(buffer, maxlen and '' or '\n') end local function dump(value, maxlen) if maxlen == nil then maxlen = 70 end local text = helper(nil, value, maxlen) if #text > maxlen then text = helper(nil, value, nil) end return text end return dump