From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.io/gmane.text.pandoc/32831 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: H Newsgroups: gmane.text.pandoc Subject: Re: Inserting attributes into elements Date: Thu, 15 Jun 2023 21:12:45 -0400 Message-ID: <0104c4b7-c583-c8d4-75ab-87eea44c07d5@meddatainc.com> References: <76a72c07-6699-d243-ae20-64808682ec9e@meddatainc.com> <90C7A30F-C0FA-49D8-B0CD-6521B58113F1@meddatainc.com> <0a6aa41a-fe72-a1e8-2630-ec6070c0bbb3@meddatainc.com> <74253f39-02db-dc2e-2ae1-9d27aaab82ea@meddatainc.com> <61724767-ada0-133f-6751-5884c7460a25@meddatainc.com> <37d8c191-388e-164e-6955-9014b4f0a4a0@meddatainc.com> Reply-To: pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="------------4BAF06CD62FED7CA5DEA6FD4" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="13794"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1 To: pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org Original-X-From: pandoc-discuss+bncBCEIZSNSZ4IRBEHOV2SAMGQEBJ2PL6A-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org Fri Jun 16 03:12:53 2023 Return-path: Envelope-to: gtp-pandoc-discuss@m.gmane-mx.org Original-Received: from mail-oo1-f57.google.com ([209.85.161.57]) by ciao.gmane.io with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1q9y1F-0003SH-28 for gtp-pandoc-discuss@m.gmane-mx.org; Fri, 16 Jun 2023 03:12:53 +0200 Original-Received: by mail-oo1-f57.google.com with SMTP id 006d021491bc7-5556fbf5225sf132135eaf.1 for ; Thu, 15 Jun 2023 18:12:52 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1686877972; cv=pass; d=google.com; s=arc-20160816; b=JJ6Jz+Zmz9OjqPvkRswb3K2o9WIlsVqKpYKEORgJ58Y+QyGUu/7jae1qfLhvqRegYW CvaeUuZiNeFAW6liVDtgmmYXTmTCNjaxjuOR2/iA5PcvF1ZU1O8Uq3U/CLCj1ZgC46lq mFcvaot6OQr682dk5HEKdLflpUTksKRl20NrkQJPRrOSMp+4y01Ass8gztFlMbH9/jGa 5KDovCXDVq23YewXhmbkzawB30CUGTTfnWkDkBmpzMIK17/p9ZDZTikndX+pWeV07grN KPRO/S5s/2nkEb7rJWcJsUlOVOeZVBpLAPyK5LgQMspMgGQojDyYhexQ3glXl/Xjneav 93YA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to:ui-outboundreport :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:to:subject:sender:dkim-signature; bh=yDgz04gWmKYVpYvbvqINoOX1r/Wm0tNQVkkcXWDKCb4=; b=dSvSkXJVcuNFyzhZMKyDXkzbHl3O76ZIe0imX680h4tGJNkIBOlTAIjksUC2Zx+CvG FUbQmvQFWdV49L1hDjThLje1s00jww3x5F/E5qaUrCpotaXpv43sqTFxrHt1xRFB7td5 sTY4J7AbUn3sl0wlrM75+Wq0i+Y3OjKq21OpZXC3XIMwDHGYHGB81PFOWSk3CqWCZEXR 7YFawqraT3CUCy4sVpgFDD5lz0brRH2KF+h9ovn+gfqUOpc0bNVM1AIphPrXCyKOxRpR 2gqiubk17EuFMn1YSjpYGz+x5GIdQnyTmyCkuj63tgZ5YKKQpxX6EGQRZ6Cx+nTHP8YW NCSw== ARC-Authentication-Results: i=2; gmr-mx.google.com; spf=pass (google.com: domain of agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org designates 74.208.4.194 as permitted sender) smtp.mailfrom=agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=meddatainc.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlegroups.com; s=20221208; t=1686877972; x=1689469972; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender :ui-outboundreport:content-language:in-reply-to:mime-version :user-agent:date:message-id:from:references:to:subject:sender:from :to:cc:subject:date:message-id:reply-to; bh=yDgz04gWmKYVpYvbvqINoOX1r/Wm0tNQVkkcXWDKCb4=; b=lQ+1ERxkaQ8k0iYvX0x1rLYt7vPFD4SWkG9imd7Rkt1QFTZGZmNx5kVJJDsl0weAd3 hEtQq8/rcKB2lOWAXhjLcibw0ZDnVnXL2+9HrodnEx7YTu6c/MHaSryTWfCKTQ66gyP6 p94oa+EqsUXVHdIGQZx3bdiPRPqDvwNbBwc7dQ+MFMvT7XzKSAJ7rZIDDZlIw1QNygwr eUY1VsbCJHNLcHO4i3VjKYdfXcJCJnrzQhkHoTw6G1xOOsmOg/bODj2/pHNkQMB+GVD7 xXM5o0RWsAKbzomU/ X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686877972; x=1689469972; h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post :x-spam-checked-in-group:list-id:mailing-list:precedence:reply-to :x-original-authentication-results:x-original-sender :ui-outboundreport:content-language:in-reply-to:mime-version :user-agent:date:message-id:from:references:to:subject:x-beenthere :x-gm-message-state:sender:from:to:cc:subject:date:message-id :reply-to; bh=yDgz04gWmKYVpYvbvqINoOX1r/Wm0tNQVkkcXWDKCb4=; b=GQy9S1EG0+s1EB9gyrW5dlPhsuX71oe16eLMOZIk+KfuoL6VRdJaik/8fdHz1Gj5wI CbEWr0IKcRFX9DhX1fJ+SC0InOiTacVshvBS/jY4/l7mJo+SgSSz48P2IvY+N+Uup9D2 2xV2m/Nwx8Ex3ZtwQl3Gds3vgxf287C4TjLewQkOp8ZEGwqUFhdUIqrLwY0NNvi8Jlva Aso+dQJ35i4agJelrecfX6AlCQlJ Original-Sender: pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org X-Gm-Message-State: AC+VfDzfJRcWN6GbNWsgHmi+3zC7YIcnq97srORUTAPLjfjKvz8bto0A gubdBg7BW/KS4mcv17T2tIo= X-Google-Smtp-Source: ACHHUZ7nozwpiJPrh29BuVlZPfefdWFJrPqUJX6nU99I8YUgY+aJ9Z/1mrHyFLFewLA2gvi+NNeN6g== X-Received: by 2002:a05:6808:30a5:b0:39a:b55b:a445 with SMTP id bl37-20020a05680830a500b0039ab55ba445mr937832oib.22.1686877971901; Thu, 15 Jun 2023 18:12:51 -0700 (PDT) X-BeenThere: pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org Original-Received: by 2002:a17:90a:2a85:b0:259:b51e:6f42 with SMTP id j5-20020a17090a2a8500b00259b51e6f42ls37023pjd.0.-pod-prod-01-us; Thu, 15 Jun 2023 18:12:47 -0700 (PDT) X-Received: by 2002:a05:6a21:329e:b0:11d:24c1:c599 with SMTP id yt30-20020a056a21329e00b0011d24c1c599mr1303224pzb.5.1686877967711; Thu, 15 Jun 2023 18:12:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686877967; cv=none; d=google.com; s=arc-20160816; b=JD1Wc0xAqXn+/jpqBo25hfFt4ruJ7w43SNiQtIaZt6HTXOuTCz8SsRgsVbPPiJJBOr W6iQ5V2M9WuKnOft0QnjyJifvnmAXK7XmdG/RmA2hf7gfy4MWe0+s5YHcq88BiVP2YKo mCDHpQwgRKNH1pfeOqDiTt6kyt4t/Sejv1Tecd/H63pmD+TDrNJFW0VzQCbNBxbjtGmH 8U0SjJAh6KqItoBxqnJLJbixYAP1gyz5zoAogAlF6AjQK5FXl7hxZSDePwrqT7uftf94 V5t97QDfykh248CJ39kMv5Odc7o4CC5kIzPSxKEPZbbdWOOFqGIINm+dymmtIl7Igus7 Jzdw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=ui-outboundreport:content-language:in-reply-to:mime-version :user-agent:date:message-id:from:references:to:subject; bh=5EuuMX9lHR5jJi5i2mPh8Zt2XpqlmgJH/SJW8zWsGRQ=; b=EOj0gujnWJXcamB+osXZAo14/3IW0IzRMvl1nCQj5QH4jzb/wI2q088CJltFfmGfD4 ux6YQsLFR0O2PTYV8GXBZeS/XGuymYvELC2sA7DHRLAlqn1tAtaOoowF2aLMPGdoek2s GaYIgn/4aK4CRg41SHOYn4Mz6P13kjOZqMptTv/CoD15poTlkSA+cborl9FnY3Kb7iMl IkiEXyr6TGSbCjo8HBN+v2u/a032bfqsan3cU3c5zNV71tP68HQ8n2P4YFo1ej9Z+xN6 0vxLmvqzUh03aMNCdad//xQISBW5BU044EXAfCHRcJDkHNmCGnWa4OzuytxDrMj2a+W0 Ttew== ARC-Authentication-Results: i=1; gmr-mx.google.com; spf=pass (google.com: domain of agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org designates 74.208.4.194 as permitted sender) smtp.mailfrom=agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=meddatainc.com Original-Received: from mout.perfora.net (mout.perfora.net. [74.208.4.194]) by gmr-mx.google.com with ESMTPS id p8-20020a056a000a0800b0066115badfa4si1541236pfh.4.2023.06.15.18.12.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Jun 2023 18:12:47 -0700 (PDT) Received-SPF: pass (google.com: domain of agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org designates 74.208.4.194 as permitted sender) client-ip=74.208.4.194; Original-Received: from [192.168.1.17] ([72.94.51.172]) by mrelay.perfora.net (mreueus003 [74.208.5.2]) with ESMTPSA (Nemesis) id 0MS4Ue-1qXemC0qAk-00TEE8 for ; Fri, 16 Jun 2023 03:12:46 +0200 In-Reply-To: Content-Language: en-US X-Provags-ID: V03:K1:Ff1KVC/0fSoe2hYSyBdwLs8hWabidF6I33eSV5nITR2VHZyMVnE yOLjEz/BzcZVeU7HunsYtC74F9FNkNKs/vzfgFASyun6eS+Qsd//cRrx4UN0w8QuVV1LG8p MzxOrHfp/xceOFlYCBM3V4910qMxMFx4kjesTh34pvmpMVftErOUO8dZ84thJi7278WV5A7 esaAi99htpdGj9oLS8dRg== UI-OutboundReport: notjunk:1;M01:P0:bjn/GyNarZM=;5foqeGgyiDupUFeRTJkuY3uy0N9 FeCQAqdnIEa6Mf7PNV4krVDo+8FZUwxnIcsBfUD3DudkGSeaWamRp2ztkQ9wp53dsYB/kqCgZ gCtMgV9SG/3ty5e/TVmcfnfIzCEF2oEbSFZ3G2D5DA/ZlHAWfC9xgJ7Z2G8DAZn85MqIAvx38 fnvjjGUqNPXZ2fCl6gP/zD8oEoe3o76j2pDyfwIGD8BlgSV67twXbXAcAJmtZD0KB6yflPv0y Pi7iRvjxlFyNAZopmI7HoLCq5JMVXDGLiHUjLzIZdwAnKipM/orfRmWJQtdftnKtZmdaBuoYa oaDFwVKU/BFo+8OuWjmqPxooVFaNZcEcYJF6143mrSANXZ3ZcELDOiJq1AZWMB7ZBPn0y7d09 5DrE4MQ1xQsCk7m0ifGLqMTMExq5FhgT8oK9uTsE9VJaH48O2pX7lKbDqOMs9usVrsZljB4+W guMzcMNGmeOXo05DwOPaid+/23N3l0balguKALUdRDG7++6VAqFMEjLq8hVtRX45Cbn4Pooy1 hcmSNWamSxkttTtiapWd/aI8tOdxnFX45uI7Lguava9flVX1o93MvgiWyJlxfdDq3TPr+mVUk xBvPhxJ5tneICkytuMCkwZVdm4UY8bF5JD2+KkJ9vm9VeVbHWK14F1a7SaYgmLkpX6zBkcrSk 9n4j8F4q7qILhhtoFoBoEJj+Va9nTfjt5reLHlKtpg== X-Original-Sender: agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org X-Original-Authentication-Results: gmr-mx.google.com; spf=pass (google.com: domain of agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org designates 74.208.4.194 as permitted sender) smtp.mailfrom=agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=meddatainc.com Precedence: list Mailing-list: list pandoc-discuss-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org; contact pandoc-discuss+owners-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org List-ID: X-Google-Group-Id: 1007024079513 List-Post: , List-Help: , List-Archive: , List-Unsubscribe: , Xref: news.gmane.io gmane.text.pandoc:32831 Archived-At: This is a multi-part message in MIME format. --------------4BAF06CD62FED7CA5DEA6FD4 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On 06/15/2023 09:00 AM, BPJ wrote: > > > Den tors 15 juni 2023 03:20H > skrev: > > On 06/14/2023 01:30 PM, BPJ wrote: > > > > Pandoc's document module used to not support attributes at all. IIR= C attributes were first introduced for fenced code blocks, then extended to= inline code. Spans and divs (in the Pandoc sense) were introduced specific= ally to provide containers for arbitrary content to which attributes can be= attached. At the same time (IIRC) attributes were extended to headings ("H= eader"), links and images. It was decided not to extend attributes to other= elements as that would entail huge changes to the code base. Later when Pa= ndoc's table model was changed the new table model included attributes. > > > > Code needs attributes to allow to attach highlighting information t= o it, and headings and images need them too for various reasons, and links = probably came along for the ride together with images. Normally divs and sp= ans are enough for all other cases, because in regular CSS in an external f= ile or embedded in the `` of an HTML document you can use a child sel= ector, e.g. in Markdown you type > > > > ``````markdown > > :::class > > **** > > ::: > > `````` > > > > and then you style the rule with > > > > ``````css > > div.class hr { ... } > > `````` > > > > Your imposed limitation of not being able to use external CSS creat= es problems which most users simply don't have. For the horizontal rule cas= e you can use a raw block to insert the HTML directly, if you are not going= to generate other formats from the source: > > > > ``````markdown > > Para before. > > > > ```{=3Dhtml} > >
> > ``` > > > > Para after > > `````` > > > > You can also use a filter to do things like this: > > > > ``````lua > > local hr_filter =3D { > > =C2=A0 HorizontalRule =3D function() > > =C2=A0 =C2=A0 return pandoc.RawBlock('html', '
') > > =C2=A0 end > > } > > function Div(div) > > =C2=A0 if div.classes:includes('class') then > > =C2=A0 =C2=A0 return div:walk(hr_filter).content > > =C2=A0 end > > end > > `````` > > =C2=A0=C2=A0 > > > > I sometimes post-process HTML generated by pandoc with with Mojo::D= om to transfer attributes from wrappin= g divs/spans to contained elements and remove the wrapper, or just to set a= ttributes to elements contained in wrappers. The API makes such changes ver= y easy. You basically find elements in an HTML document with CSS selectors,= then loop through the found elements and change them in-place with Perl co= de. Adding/removing/changing attributes is very easy: you just treat the el= ement object as if it is a hash (associative array) reference containing th= e attributes! Then when you are done you print the document object to a fil= e or stdout. > > > Thank you for the explanation. I did resort to creating the
in the filter. > > Now another problem - I have multiple images in my markdown document = and a
tag pair gets added around the which is fin= e. > > However, while processing the
block I want to make changes t= o the default style attribute for some of the images. Using the log= ging module I find e.g.: > > (#) figure Figure { > =C2=A0 attr: Attr { > =C2=A0=C2=A0=C2=A0 attributes: AttributeList { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 style: "margin: 0px;" > =C2=A0=C2=A0=C2=A0 } > =C2=A0=C2=A0=C2=A0 classes: List {} > =C2=A0=C2=A0=C2=A0 identifier: "" > =C2=A0 } > =C2=A0 caption: { > =C2=A0=C2=A0=C2=A0 long: Blocks {} > =C2=A0 } > =C2=A0 content: Blocks[1] { > =C2=A0=C2=A0=C2=A0 [1] Plain { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 content: Inlines[1] { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [1] Image { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 attr: Attr { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 at= tributes: AttributeList {} > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 cl= asses: List {} > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 id= entifier: "" > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 caption: Inlin= es[1] { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [1= ] Str "whatever" > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 src: "https://= www.somedomain.tld/images/someimage.jpg" > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 title: "" > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 } > =C2=A0=C2=A0=C2=A0 } > =C2=A0 } > } > > > and if look at the logging output for the Image I find: > > #) image Image { > =C2=A0 attr: Attr { > =C2=A0=C2=A0=C2=A0 attributes: AttributeList { > =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 style: "height: auto; width: 100%; obj= ect-fit: contain;" > =C2=A0=C2=A0=C2=A0 } > =C2=A0=C2=A0=C2=A0 classes: List {} > =C2=A0=C2=A0=C2=A0 identifier: "" > =C2=A0 } > =C2=A0 caption: Inlines[1] { > =C2=A0=C2=A0=C2=A0 [1] Str "whatever" > =C2=A0 } > =C2=A0 src: "https://www.somedomain.tld/images/someimage.jpg" > =C2=A0 title: "" > } > > While processing the Figure element in the filter, I want to change t= he style attributes for the Image listed above. They show up correctly in t= he logging module output for Image above but the logging output for Figure = shows an empty list. > > > > > I=E2=80=99m not quite sure what you mean but here are basically two ways = to affect only elements inside another element of a certain kind (with a ce= rtain tag): > > A.=C2=A0 If you want to do something with all Image elements inside any F= igure element you can use a local filter which you apply only to the Figure= element. This is done by calling the `:walk(inner_filter)` method on the p= arent/ancestor element. > > =C2=A0 =C2=A0 Some things to keep in mind: > > =C2=A0 =C2=A0 a)=C2=A0 The `inner_filter` is a table where the keys are e= lement tag names and each value are filter functions to apply to descendant= s with that tag. > =C2=A0 =C2=A0 b)=C2=A0 The `:walk` method does _not_ change the element i= t is called on.=C2=A0 Rather it returns a =E2=80=9Ccopy=E2=80=9D with any m= odifications applied. Thus you have to assign the return value of `?walk` t= o a variable, or return the return value of `:walk` from the outer filter f= unction in turn. > > =C2=A0 =C2=A0 This again can take two forms: > > =C2=A0 =C2=A0 1.=C2=A0 If the action of the inner filter function does no= t access the parent/ancestor element in any way it is probably more efficie= nt (and less cluttered) to define the inner filter only once outside the ou= ter filter function: > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 ```lua > =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Define static "inner" filter once > =C2=A0 =C2=A0 =C2=A0 =C2=A0 local fig_img_filter =3D { > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Image =3D function(img) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Do something with Image > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 img.attributes.style =3D 'borde= r: 0.2rem solid black' > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return img > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 } > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Main filter function > =C2=A0 =C2=A0 =C2=A0 =C2=A0 function Figure(fig) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Apply "inner" filter to images insi= de the Figure > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return fig:walk(fig_img_filter) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 ``` > > =C2=A0 =C2=A0 2.=C2=A0 If on the other hand the inner filter function nee= ds to access the parent/ancestor element you need to define the inner filte= r inside the outer filter function where the parent is in scope: > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 ```lua > =C2=A0 =C2=A0 =C2=A0 =C2=A0 function Div(div) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Test condition on div > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if div.classes:includes('foo') then > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Apply dynamic filter to nest= ed links > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return div:walk({ > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Link =3D function(lnk) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Test condition= on link > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if lnk.classes:in= cludes('bar') then > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Copy so= mething from div > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lnk.attrib= utes.baz =3D div.attributes.zip > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 else > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Copy so= mething else from div > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lnk.attrib= utes.baz =3D div.attributes.zap > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return lnk > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }).content > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Div is not needed anymore so= replace it with its content > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 ``` > > =C2=A0 =C2=A0 =C2=A0 =C2=A0 This also illustrates the common situation wh= ere a Div or Span is only used to tell the filter what to do to elements in= side it. In this case the Div is no longer needed when you have applied the= changes to the elements inside it, so rather than returning the Div you re= turn only what is inside it. > > B.=C2=A0 In case you want to do something only with specific descendants = of an element you have to walk/check the children at each level manually. > > =C2=A0 =C2=A0 Some things to remember: > > =C2=A0 =C2=A0 a)=C2=A0 You need to check that any child exist separately = before accessing its properties, because trying to access properties on a n= on-existing value is a fatal error. > =C2=A0 =C2=A0 b)=C2=A0 Don=E2=80=99t forget to reassign any elements whic= h you have changed to the right place in the structure or the change may no= t take effect. It=E2=80=99s not all that clear when it is needed so it=E2= =80=99s safer to do it always. > > =C2=A0 =C2=A0 Here is a more explicit version (with more comments and som= e extras :-) of my filter for conditionally stripping the Figure around an = Image: > > =C2=A0 =C2=A0 ```lua > =C2=A0 =C2=A0 function Figure(fig) > =C2=A0 =C2=A0 =C2=A0 -- First check that we have exactly one child... > =C2=A0 =C2=A0 =C2=A0 if 1 =3D=3D #fig.content then > =C2=A0 =C2=A0 =C2=A0 =C2=A0 local child =3D fig.content[1] > =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- ...then check that the child is a Plain... > =C2=A0 =C2=A0 =C2=A0 =C2=A0 if 'Plain' =3D=3D child.tag then > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- ...then check that there is exactly= one grandchild... > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if 1 =3D=3D #child.content then > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 local grandchild =3D child.cont= ent[1] > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- ...and that the grandchild i= s an Image. > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if 'Image' =3D=3D grandchild.ta= g then > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Bingo! > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Now do we want it to = be a figure? > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if grandchild.classes:in= cludes('fig') then > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 grandchild.attrib= utes.style =3D style_for_img_in_fig > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Put grandchild= back > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 child.content[1] = =3D grandchild > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Put child back > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fig.content[1] = =3D child > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fig.attributes.st= yle =3D style_for_figs > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Done with figu= re > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return fig > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- else if a standalone = image > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 grandchild.attributes.st= yle =3D style_for_img > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Don't want the fig so= return the image! > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return granchild > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 =C2=A0 -- If not all the conditions hold > =C2=A0 =C2=A0 =C2=A0 return nil > =C2=A0 =C2=A0 end > =C2=A0 =C2=A0 ``` > > =C2=A0 =C2=A0 (Note: the `style_for_*` variables aren=E2=80=99t actually = defined in this code; they are just placeholders for some strings!) > > > > I thought > print(pandoc.utils.stringify(el.content[1].content[1].attr.attributes= )) > would give me the attributes but it does not. > > > `pandoc.utils.stringify` concatenates and returns the Str element values = in its argument, which must be an element object. The attributes of an elem= ent don't meet any of those two descriptions, but they are an object with c= ustom stringification (in the Lua sense) so you can just say `print(element= .attributes)` to inspect them. > > > > Could this be a bug? > > > No. Thank you for your thorough and excellent explanation! --=20 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 e= mail 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/0104c4b7-c583-c8d4-75ab-87eea44c07d5%40meddatainc.com. --------------4BAF06CD62FED7CA5DEA6FD4 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On 06/15/2023 09:00 AM, BPJ wrote:


Den tors 15 juni 2023 03:20H <agents-FcZObrvlYduBUy7/sJONFg@public.gmane.org> skrev:
On 06/14/2023 01:30 PM, BPJ wrote:
>
> Pandoc's document module used to not support attributes at all. IIRC attributes were first introduced for fenced code blocks, then extended to inline code. Spans and divs (in the Pandoc sense) were introduced specifically to provide containers for arbitrary content to which attributes can be attached. At the same time (IIRC) attributes were extended to headings ("Header"), links and images. It was decided not to extend attributes to other elements as that would entail huge changes to the code base. Later when Pandoc's table model was changed the new table model included attributes.
>
> Code needs attributes to allow to attach highlighting information to it, and headings and images need them too for various reasons, and links probably came along for the ride together with images. Normally divs and spans are enough for all other cases, because in regular CSS in an external file or embedded in the `<head>` of an HTML document you can use a child selector, e.g. in Markdown you type
>
> ``````markdown
> :::class
> ****
> :::
> ``````
>
> and then you style the rule with
>
> ``````css
> div.class hr { ... }
> ``````
>
> Your imposed limitation of not being able to use external CSS creates problems which most users simply don't have. For the horizontal rule case you can use a raw block to insert the HTML directly, if you are not going to generate other formats from the source:
>
> ``````markdown
> Para before.
>
> ```{=3Dhtml}
> <hr style=3D"...">
> ```
>
> Para after
> ``````
>
> You can also use a filter to do things like this:
>
> ``````lua
> local hr_filter =3D {
> =C2=A0 HorizontalRule =3D function()
> =C2=A0 =C2=A0 return pandoc.RawBlock('html', '<hr style=3D"...">')
> =C2=A0 end
> }
> function Div(div)
> =C2=A0 if div.classes:includes('class') then
> =C2=A0 =C2=A0 return div:walk(hr_filter).content
> =C2=A0 end
> end
> ``````
> =C2=A0=C2=A0
>
> I sometimes post-process HTML generated by pandoc with with Mojo::Dom <https://metacpan.org/pod/Mojo::DOM= > to transfer attributes from wrapping divs/spans to contained elements and remove the wrapper, or just to set attributes to elements contained in wrappers. The API makes such changes very easy. You basically find elements in an HTML document with CSS selectors, then loop through the found elements and change them in-place with Perl code. Adding/removing/changing attributes is very easy: you just treat the element object as if it is a hash (associative array) reference containing the attributes! Then when you are done you print the document object to a file or stdout.
>
Thank you for the explanation. I did resort to creating the <hr ... /> in the filter.

Now another problem - I have multiple images in my markdown document and a <figure></figure> tag pair gets added around the <image> which is fine.

However, while processing the <figure> block I want to make changes to the default style attribute <image> for some of the images. Using the logging module I find e.g.:

(#) figure Figure {
=C2=A0 attr: Attr {
=C2=A0=C2=A0=C2=A0 attributes: AttributeList {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 style: "margin: 0px;"
=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 classes: List {}
=C2=A0=C2=A0=C2=A0 identifier: ""
=C2=A0 }
=C2=A0 caption: {
=C2=A0=C2=A0=C2=A0 long: Blocks {}
=C2=A0 }
=C2=A0 content: Blocks[1] {
=C2=A0=C2=A0=C2=A0 [1] Plain {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 content: Inlines[1] {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 [1] Image {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 attr: = Attr {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 attributes: AttributeList {}
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 classes: List {}
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 identifier: ""
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 captio= n: Inlines[1] {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 [1] Str "whatever"
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 src: "= https://www.somedomain.tld/images/= someimage.jpg"
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 title:= ""
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 }
=C2=A0 }
}


and if look at the logging output for the Image I find:

#) image Image {
=C2=A0 attr: Attr {
=C2=A0=C2=A0=C2=A0 attributes: AttributeList {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 style: "height: auto; width: 1= 00%; object-fit: contain;"
=C2=A0=C2=A0=C2=A0 }
=C2=A0=C2=A0=C2=A0 classes: List {}
=C2=A0=C2=A0=C2=A0 identifier: ""
=C2=A0 }
=C2=A0 caption: Inlines[1] {
=C2=A0=C2=A0=C2=A0 [1] Str "whatever"
=C2=A0 }
=C2=A0 src: "https://www.somedomain.tld/images/= someimage.jpg"
=C2=A0 title: ""
}

While processing the Figure element in the filter, I want to change the style attributes for the Image listed above. They show up correctly in the logging module output for Image above but the logging output for Figure shows an empty list.



I=E2=80=99m not quite sure what you mean but he= re are basically two ways to affect only elements inside another element of a certain kind (with a certain tag):

A.=C2=A0 If you want to do something with all I= mage elements inside any Figure element you can use a local filter which you apply only to the Figure element. This is done by calling the `:walk(inner_filter)` method on the parent/ancestor element.

=C2=A0 =C2=A0 Some things to keep in mind:

=C2=A0 =C2=A0 a)=C2=A0 The `inner_filter` is a = table where the keys are element tag names and each value are filter functions to apply to descendants with that tag.
=C2=A0 =C2=A0 b)=C2=A0 The `:walk` method does = _not_ change the element it is called on.=C2=A0 Rather it returns a =E2=80= =9Ccopy=E2=80=9D with any modifications applied. Thus you have to assign the return value of `?walk` to a variable, or return the return value of `:walk` from the outer filter function in turn.

=C2=A0 =C2=A0 This again can take two forms:

=C2=A0 =C2=A0 1.=C2=A0 If the action of the inn= er filter function does not access the parent/ancestor element in any way it is probably more efficient (and less cluttered) to define the inner filter only once outside the outer filter function:

=C2=A0 =C2=A0 =C2=A0 =C2=A0 ```lua
=C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Define static "i= nner" filter once
=C2=A0 =C2=A0 =C2=A0 =C2=A0 local fig_img_filte= r =3D {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Image =3D fu= nction(img)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Do= something with Image
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 img.a= ttributes.style =3D 'border: 0.2rem solid black'
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 retur= n img
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Main filter func= tion
=C2=A0 =C2=A0 =C2=A0 =C2=A0 function Figure(fig= )
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Apply "in= ner" filter to images inside the Figure
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return fig:w= alk(fig_img_filter)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ```

=C2=A0 =C2=A0 2.=C2=A0 If on the other hand the= inner filter function needs to access the parent/ancestor element you need to define the inner filter inside the outer filter function where the parent is in scope:

=C2=A0 =C2=A0 =C2=A0 =C2=A0 ```lua
=C2=A0 =C2=A0 =C2=A0 =C2=A0 function Div(div)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Test cond= ition on div
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if div.class= es:includes('foo') then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Ap= ply dynamic filter to nested links
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 retur= n div:walk({
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Link =3D function(lnk)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 -- Test condition on link
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 if lnk.classes:includes('bar') then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 -- Copy something from div
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 lnk.attributes.baz =3D div.attributes.zip
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 else
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 -- Copy something else from div
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 lnk.attributes.baz =3D div.attributes.zap
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return lnk
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }).co= ntent
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- Di= v is not needed anymore so replace it with its content
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 ```

=C2=A0 =C2=A0 =C2=A0 =C2=A0 This also illustrat= es the common situation where a Div or Span is only used to tell the filter what to do to elements inside it. In this case the Div is no longer needed when you have applied the changes to the elements inside it, so rather than returning the Div you return only what is inside it.

B.=C2=A0 In case you want to do something only = with specific descendants of an element you have to walk/check the children at each level manually.

=C2=A0 =C2=A0 Some things to remember:

=C2=A0 =C2=A0 a)=C2=A0 You need to check that a= ny child exist separately before accessing its properties, because trying to access properties on a non-existing value is a fatal error.
=C2=A0 =C2=A0 b)=C2=A0 Don=E2=80=99t forget to = reassign any elements which you have changed to the right place in the structure or the change may not take effect. It=E2=80=99s not all that cl= ear when it is needed so it=E2=80=99s safer to do it always.

=C2=A0 =C2=A0 Here is a more explicit version (= with more comments and some extras :-) of my filter for conditionally stripping the Figure around an Image:

=C2=A0 =C2=A0 ```lua
=C2=A0 =C2=A0 function Figure(fig)
=C2=A0 =C2=A0 =C2=A0 -- First check that we hav= e exactly one child...
=C2=A0 =C2=A0 =C2=A0 if 1 =3D=3D #fig.content t= hen
=C2=A0 =C2=A0 =C2=A0 =C2=A0 local child =3D fig= .content[1]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 -- ...then check th= at the child is a Plain...
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if 'Plain' =3D=3D c= hild.tag then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- ...then c= heck that there is exactly one grandchild...
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if 1 =3D=3D = #child.content then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 local= grandchild =3D child.content[1]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -- ..= .and that the grandchild is an Image.
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if 'I= mage' =3D=3D grandchild.tag then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 -- Bingo!
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 -- Now do we want it to be a figure?
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 if grandchild.classes:includes('fig') then
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 grandchild.attributes.style =3D style_for_img_in_fig
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 -- Put grandchild back
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 child.content[1] =3D grandchild
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 -- Put child back
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 fig.content[1] =3D child
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 fig.attributes.style =3D style_for_figs
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 -- Done with figure
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return fig
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 -- else if a standalone image
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 grandchild.attributes.style =3D style_for_img
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 -- Don't want the fig so return the image!
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 return granchild
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 end
=C2=A0 =C2=A0 =C2=A0 -- If not all the conditio= ns hold
=C2=A0 =C2=A0 =C2=A0 return nil
=C2=A0 =C2=A0 end
=C2=A0 =C2=A0 ```

=C2=A0 =C2=A0 (Note: the `style_for_*` variable= s aren=E2=80=99t actually defined in this code; they are just placeholders for some strings!)



I thought
print(pandoc.utils.stringify(el.content[1].content[1].attr.attributes))
would give me the attributes but it does not.

`pandoc.utils.stringify` concatenates and returns the Str element values in its argument, which must be an element object. The attributes of an element don't meet any of those two descriptions, but they are an object with custom stringification (in the Lua sense) so you can just say `print(element.attributes)` to inspect them.



Could this be a bug?

No.
Thank you for your thorough and excellent explanation!

--
You received this message because you are subscribed to the Google Groups &= quot;pandoc-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an e= mail to pand= oc-discuss+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org.
To view this discussion on the web visit https://groups.google.com/d/ms= gid/pandoc-discuss/0104c4b7-c583-c8d4-75ab-87eea44c07d5%40meddatainc.com.
--------------4BAF06CD62FED7CA5DEA6FD4--