From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Richard Lawrence Newsgroups: gmane.emacs.devel Subject: Re: Upstreaming org-element-ast (was: Improving Emacs' iCalendar support) Date: Wed, 01 Jan 2025 13:38:05 +0100 Message-ID: <87seq290b6.fsf@recursewithless.net> References: <87ed4dss2x.fsf@ohm.mail-host-address-is-not-set> <87mshq9w5c.fsf@ohm.mail-host-address-is-not-set> <86ed31j6zk.fsf@gnu.org> <87ldx9vsnb.fsf@localhost> <868qt8kj6f.fsf@gnu.org> <87ikscx5io.fsf@localhost> <867c8skhy6.fsf@gnu.org> <87frngx4fx.fsf@localhost> <864j3wkczm.fsf@gnu.org> <87cyhg0zjz.fsf@localhost> <87ttamtf7g.fsf@recursewithless.net> <87h66l2isk.fsf@localhost> <87cyh8guci.fsf@recursewithless.net> <87r05mg9ve.fsf@localhost> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="5863"; mail-complaints-to="usenet@ciao.gmane.io" Cc: emacs-devel@gnu.org To: Ihor Radchenko Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Jan 01 13:39:36 2025 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tSy0c-0001Of-LG for ged-emacs-devel@m.gmane-mx.org; Wed, 01 Jan 2025 13:39:36 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tSxzk-0005fU-R2; Wed, 01 Jan 2025 07:38:40 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tSxzX-0005fG-Bn for emacs-devel@gnu.org; Wed, 01 Jan 2025 07:38:27 -0500 Original-Received: from fhigh-b1-smtp.messagingengine.com ([202.12.124.152]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tSxzV-0001AI-3E for emacs-devel@gnu.org; Wed, 01 Jan 2025 07:38:26 -0500 Original-Received: from phl-compute-02.internal (phl-compute-02.phl.internal [10.202.2.42]) by mailfhigh.stl.internal (Postfix) with ESMTP id 1E7AB2540108; Wed, 1 Jan 2025 07:38:22 -0500 (EST) Original-Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Wed, 01 Jan 2025 07:38:22 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= recursewithless.net; h=cc:cc:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm1; t=1735735101; x=1735821501; bh=fPATxSngP7tMfhIKpI1syhO1tY1aefQis/T+jIJPrpk=; b= E+q0mVzrWkO9iugGUT6gQueDgk/FcJEVG8a/iWHdz4Ki9wHGtWN+w5Gpl1u3w8SU k5VmUOJuYbLndO1hT/T8psCcS+mH93NmD9WXbEi9ORIKGQiox1UrGk3wVEm8unb/ b2fVBIv2EL+G/pxUaH1G7pBFMtbOsmsDRw+0wEmpZsQgYv7ZpaGaWv/lkhdeT9Qz DT7L4/ZcOMa0SncTEc14xS6a2boPqvGzIr0kvS3/vS/JchHydM2UJwMrz7I4kF8Z bp0hfai+oAgA5Ois1eWNXW6TdM6++MMj3FYGnOn7PqF0+/Ny5BJjOIexk+ixq5Ve nOTMupNjDz5XKIhhRDJGwA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t= 1735735101; x=1735821501; bh=fPATxSngP7tMfhIKpI1syhO1tY1aefQis/T +jIJPrpk=; b=DgcWRBZ9kh1yPxD1lzoO2meO5OFLBy8CvoMI0h+tBjW9ouf6nTR LT4lnEscg1dRILXAa8U7PX7hv4oKEzoXJKgTM5GFR+Oe43VVJ5vCBrKmNpJ3K7ot Oklny9vGwhRFUf8otIO3ILOCfqHURAUdfkuEiVizofbvGgX0s38TWDB+pTjYU2e3 8Kb6SpJeIfe2FZGIpUs8pAiXuV7Gx8neYGqfP/KP6qqewj6rQeCgRLRqNX9uXLtA LQ79wQLR/vHzJv8MceR5Fme2y65PwXvL5dA9G64aNQEIiGQpb8MGjCQck7gIrUBY /BKa8M+MUvafa94R9YpBiF+/xhv3x5kftXA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudeftddggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucenucfjughrpefhvfevuf gjfhffkfggtgesthdtredttddttdenucfhrhhomheptfhitghhrghrugcunfgrfihrvghn tggvuceorhiflhesrhgvtghurhhsvgifihhthhhlvghsshdrnhgvtheqnecuggftrfgrth htvghrnhepfeeuffdvfeeffedtuedtgfejtedtudevuddufeejtdekjefgheehvdfggfff udfhnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprh iflhesrhgvtghurhhsvgifihhthhhlvghsshdrnhgvthdpnhgspghrtghpthhtohepvddp mhhouggvpehsmhhtphhouhhtpdhrtghpthhtohephigrnhhtrghrledvsehpohhsthgvoh drnhgvthdprhgtphhtthhopegvmhgrtghsqdguvghvvghlsehgnhhurdhorhhg X-ME-Proxy: Feedback-ID: if7394488:Fastmail Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 1 Jan 2025 07:38:21 -0500 (EST) In-Reply-To: <87r05mg9ve.fsf@localhost> Received-SPF: pass client-ip=202.12.124.152; envelope-from=rwl@recursewithless.net; helo=fhigh-b1-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:327544 Archived-At: Ihor Radchenko writes: >> 2) I'm finding org-element-create rather unintuitive to work with, I >> think because of its &rest argument for children and the handling of >> "anonymous" nodes. >> ... >> As it is, I can't figure out how to call org-element-create and >> org-element-contents in the right way to set the contents of a node >> to a list of other nodes, and return that list from >> org-element-contents. > > Should be just > (org-element-create type props contents) > and then > (org-element-contents new-node) That's what I would have thought. In my experiment, I have done this: (defun ical:make-ast-node (type &optional props &rest children) ;; automatically mark :value as a seconary property for org-element-ast: (let ((full-props (plist-put props :secondary (list :value)))) (org-element-create type full-props children))) (so basically just aliasing org-element-create) and (defalias 'ical:ast-node-children #'org-element-contents) I also changed all my calls to ical:make-ast-node to reflect the calling convention of org-element-create, e.g. in ical:read-property-value I now have (ical:make-ast-node type (list :value value :original-value unrecognized-val) params) The calls to ical:ast-node-children shouldn't need adjusting, since both the old version and org-element-set-contents just take a single argument, the syntax node. But when I run my parser tests with the above changes, they (almost) all fail with errors like this: Test string: "ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT:mailto:jsmith@example.com\n" Error: (icalendar-validation-error "`icalendar-attendee' may not contain `nil'" (icalendar-attendee (:standard-properties [1 nil nil nil 66 nil (:value) nil nil nil ...] :value (icalendar-cal-address (:standard-properties [nil nil nil nil nil nil ... nil nil nil ...] :value "mailto:jsmith@example.com") nil) :original-value nil :value-begin 41 :value-end 66) ((icalendar-rsvpparam (:standard-properties [10 nil nil nil 19 nil ... nil nil nil ...] :value (icalendar-boolean ... nil) :original-value nil :value-begin 15 :value-end 19) nil) (icalendar-roleparam (:standard-properties [20 nil nil nil 40 nil ... nil nil nil ...] :value "REQ-PARTICIPANT" :original-value nil :value-begin 25 :value-end 40) nil)))) And probing with the debugger reveals e.g. that (icalendar-node-children node) returns in this example: (((icalendar-rsvpparam (:standard-properties [10 nil nil nil 19 nil (:value) nil nil nil nil nil nil nil # nil nil nil] :value (icalendar-boolean (:standard-properties [nil nil nil nil nil nil (:value) nil nil nil nil nil nil nil nil nil nil nil] :value t) nil) :original-value nil :value-begin 15 :value-end 19) nil) (icalendar-roleparam (:standard-properties [20 nil nil nil 40 nil (:value) nil nil nil nil nil nil nil # nil nil nil] :value "REQ-PARTICIPANT" :original-value nil :value-begin 25 :value-end 40) nil))) That is, the list of parameter nodes is wrapped in an extra list, which causes my function which counts children by type to fail and signal the error. Initially I thought that this is because org-element-contents is implemented in the relevant case as (nthcdr 2 node) rather than e.g. (nth 2 node). Changing the definition of ical:ast-node-children from the above alias to (defun ical:ast-node-children (node) (nth 2 node)) helps -- more tests pass -- but I'm not sure why this change should be necessary. (I feel like I'm missing something really obvious here but so far it eludes me!) Even with this change, most tests still fail with an error like the above, because an *empty* list of children is still returned as (nil) rather than nil. The problem here is apparently that I am passing nil as an explicit &rest argument to org-element-create; if I then change the definition of ical:make-ast-node to work around this, e.g. (defun ical:make-ast-node (type &optional props &rest children) ;; automatically mark :value as a seconary property for org-element-ast: (let ((full-props (plist-put props :secondary (list :value)))) (if (equal children '(nil)) (org-element-create type full-props) (org-element-create type full-props children)))) then all the tests pass again. But this is where I find the calling convention of org-element-create unintuitive and would prefer an interface where I can just always pass a list of child nodes, including an empty list, and org-element-contents will always give me exactly that list back. This got a bit long, but I hope it's detailed enough to make things clear! Best, Richard