public inbox archive for pandoc-discuss@googlegroups.com
 help / color / mirror / Atom feed
From: William Lupton <wlupton-QSt+ys/nuMyEUIsrzH9SikB+6BGkLq7r@public.gmane.org>
To: John MacFarlane <jgm-TVLZxgkOlNX2fBVCVOL8/A@public.gmane.org>
Cc: pandoc-discuss <pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org>
Subject: Re: Printing lua tables
Date: Tue, 7 Jun 2022 16:24:28 +0100	[thread overview]
Message-ID: <CAEe_xxjopWC0y3Nk-ZrHSWDoAAj71szfHhivi=c42zK_aFpZ4Q@mail.gmail.com> (raw)
In-Reply-To: <CAEe_xxiVFhQ8PqSq_37yhMm-8-Pnb2ZgY4eDkO7kdCZQt6bNkA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>


[-- Attachment #1.1: Type: text/plain, Size: 3577 bytes --]

All,

I've split this out into two functions (each currently in its own [attached
as .lua.txt] file):

   - dump(value, maxlen=70) that returns a possibly multi-line string
   representation of a value
   - output(...) that's a utility function that outputs space-separated
   arguments, each passed to dump() and with a terminating newline if needed

Here's an updated example filter (it uses output() and doesn't call dump()
directly):

local output = require 'output'
function Pandoc(doc)
    output('meta', doc.meta)
    output('blocks', doc.blocks)
end

Please feel free to do whatever you like with these functions.

In my environment I have an additional layer in which I derive a log-level
from PANDOC_STATE.{trace,verbosity} and use this in a set of logging
functions like this one (*please let me know if you'd like me to supply
these too*):

function error(...)
    if logLevel >= -1 then
        output('(E)', ...)
    end
end

Cheers,
William

On Tue, 7 Jun 2022 at 15:13, William Lupton <wlupton-QSt+ys/nuMyEUIsrzH9SikB+6BGkLq7r@public.gmane.org>
wrote:

> I'll need to extract the reporting functions. I'll do that soon, and post
> the result. This is currently working in pandoc 2.16.1 (and earlier). I
> haven't yet bitten the bullet of the move to 2.18.
>
> On Tue, 7 Jun 2022 at 14:55, John MacFarlane <jgm-TVLZxgkOlNX2fBVCVOL8/A@public.gmane.org> wrote:
>
>>
>> That looks nice.  Can you share your utils.lua?
>>
>> William Lupton <wlupton-QSt+ys/nuMyEUIsrzH9SikB+6BGkLq7r@public.gmane.org> writes:
>>
>> > I think I've mentioned this before... but I'd be happy to contribute
>> (in a
>> > suitable form) the somewhat-pandoc-aware utility that I use for this.
>> >
>> > Given this input:
>> >
>> > *% *cat doc.md
>> >
>> > ---
>> >
>> > a: 1
>> >
>> > b: |
>> >
>> >   2 3 4
>> >
>> > ---
>> >
>> >
>> > # Header
>> >
>> >
>> > This is a sentence (and a paragraph).
>> >
>> >
>> > * This is a list item
>> >
>> > * And another
>> >
>> >
>> > | Right | Left | Default | Center |
>> >
>> > |------:|:-----|---------|:------:|
>> >
>> > |   12  |  12  |    12   |    12  |
>> >
>> > |  123  |  123 |   123   |   123  |
>> >
>> > |    1  |    1 |     1   |     1  |
>> >
>> >
>> > : Demonstration of pipe table syntax.
>> >
>> > and this filter:
>> >
>> > *% *cat rep.lua
>> >
>> > local utils = require 'utils'
>> >
>> >
>> > -- do it this way to avoid reporting MetaBlocks twice
>> >
>> > function Pandoc(doc)
>> >
>> >     utils.temp('meta', doc.meta)
>> >
>> >     utils.temp('blocks', doc.blocks)
>> >
>> > end
>> >
>> > this command:
>> >
>> > pandoc doc.md -L rep.lua >/dev/null 2>doc.txt
>> >
>> > generates the attached.
>> >
>> > On Tue, 7 Jun 2022 at 08:57, <denis.maier-NSENcxR/0n0@public.gmane.org> wrote:
>> >
>> >> Hi,
>> >>
>> >> When playing around with filters I use pprint.lua or inspect.lua to
>> >> visualize lua tables. Would it make sense to include some sort of
>> «print
>> >> the contents of this table» to pandoc ?
>> >>
>> >> Best,
>> >>
>> >> Denis
>> >>
>> >> --
>>
>

-- 
You received this message because you are subscribed to the Google Groups "pandoc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pandoc-discuss+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To view this discussion on the web visit https://groups.google.com/d/msgid/pandoc-discuss/CAEe_xxjopWC0y3Nk-ZrHSWDoAAj71szfHhivi%3Dc42zK_aFpZ4Q%40mail.gmail.com.

[-- Attachment #1.2: Type: text/html, Size: 5605 bytes --]

[-- Attachment #2: output.lua.txt --]
[-- Type: text/plain, Size: 555 bytes --]

-- output() outputs to stderr

local dump = require 'dump'

local function output(...)
    local need_newline = false
    for i, item in ipairs({...}) do
        -- XXX space logic could be cleverer, e.g. no space after newline
        local maybe_space = i > 1 and ' ' or ''
        local text = ({table=1, userdata=1})[type(item)] and
            dump(item) or tostring(item)
        io.stderr:write(maybe_space, text)
        need_newline = text:sub(-1) ~= '\n'
    end
    if need_newline then
        io.stderr:write('\n')
    end
end

return output

[-- Attachment #3: dump.lua.txt --]
[-- Type: text/plain, Size: 3734 bytes --]

-- 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

  parent reply	other threads:[~2022-06-07 15:24 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-07  7:57 denis.maier-NSENcxR/0n0
     [not found] ` <551a3f2a8d364717bcc569baa974573a-NSENcxR/0n0@public.gmane.org>
2022-06-07 10:44   ` William Lupton
     [not found]     ` <CAEe_xxiL81rUdVtCeKovjYeo=KaKP1GAbwEiM6_9byZY8t_XvA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2022-06-07 13:55       ` John MacFarlane
     [not found]         ` <m2y1y8fuij.fsf-pgq/RBwaQ+zq8tPRBa0AtqxOck334EZe@public.gmane.org>
2022-06-07 14:13           ` William Lupton
     [not found]             ` <CAEe_xxiVFhQ8PqSq_37yhMm-8-Pnb2ZgY4eDkO7kdCZQt6bNkA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2022-06-07 15:24               ` William Lupton [this message]
     [not found]                 ` <CAEe_xxjopWC0y3Nk-ZrHSWDoAAj71szfHhivi=c42zK_aFpZ4Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2022-06-23 12:25                   ` William Lupton
     [not found]                     ` <CAEe_xxhcoCqPPYx5Ob-ZT083vTx9wDbnBg+8-cVGnhExLFnXXw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2022-07-18  8:46                       ` William Lupton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAEe_xxjopWC0y3Nk-ZrHSWDoAAj71szfHhivi=c42zK_aFpZ4Q@mail.gmail.com' \
    --to=wlupton-qst+ys/numyeuisrzh9sikb+6bgklq7r@public.gmane.org \
    --cc=jgm-TVLZxgkOlNX2fBVCVOL8/A@public.gmane.org \
    --cc=pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).