0

I tried to build a small converter which will traverse the dom-tree and output its org-mode equivalent but I faced a *** Eval error *** Wrong type argument: listp, " " error means the list is an empty string or a non-closed quote is being captured. How can i improve on this if possible and fix the error? The purpose of the function is to return an org-mode headings and subheadings from the tags obtained the dom-node which should be in a format of

*~div~ text-from-dom-node-if-exists
  :PROPERTIES
   list-of-dom-attributes
**~p~ text-from-dom-node-if-exists

I'm open to any suggestions.

(defun org-tagify-node (node depth)
  "Convert a DOM NODE into Org-mode text with appropriate depth."
  (let* ((tag-name (dom-tag node))
         (text (and (stringp tag-name) (dom-text node)))
         (attributes (dom-attributes node))
         (attr-text (if attributes
                        (concat ":PROPERTIES\n"
                                (mapconcat (lambda (attr)
                                             (format "  - %s: %s" (car attr) (cdr attr)))
                                           attributes
                                           "\n")
                        "")))
         (stars (make-string depth ?*)))
    (concat stars "~" tag-name "~"
            (if text (concat " `" text "`") "")
            "\n" attr-text
            (mapconcat (lambda (child)
                         (org-tagify-node child (1+ depth)))
                       (dom-children node)
                       ""))))


(defun macro-etagify (tag-entries)
  "Return the Org-mode representation of HTML tags."
  (with-temp-buffer
    (insert tag-entries)
    (let* ((mytags (libxml-parse-html-region (point-min) (point-max))))
      (org-tagify-node (car (dom-by-tag mytags 'body)) 1))))

let ((myskel "<html>
     <head>
         <title>Demo: Gradient Slide</title>
     <link href=\"https://fonts.googleapis.com/css?family=Nunito+Sans\" rel=\"stylesheet\">
     <link rel=\"stylesheet\" href=\"dist/build.css\">
     </head>
     <body>
         <header data-table=\"testtable\">
             <h1 data-field=\"testfield\">Skeleton Screen</h1>
             <h1 data-field=\"newfield\">Skeleton Screen</h1>
         </header>
         <div class=\"wrap\"> Sample Text <p class=\"format\" data-attribute=\"somethingsomething\">Welcome to this page</p>
             <div class=\"flex-grid generic-card\">
                 <!-- ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIMATE -->
                 <div class=\"card loading\">Text </div>
                 <!-- ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIMATE 
                   this multiline comment 
                    -->
                <div class=\"card loading\"></div>
             </div>
         </div>
     </body>
 </html>"))

From the debugger, I have the following

Debugger entered--Lisp error: (wrong-type-argument listp "\n         ")
  dom-tag("\n         ")
  (let* ((tag-name (dom-tag node)) (text (and (stringp tag-name) (dom-text node))) (attributes (dom-attributes node)) (attr-text (if attributes (concat ":PROPERTIES\n" (mapconcat (lambda (attr) (format "  - %s: %s" ... ...)) attributes "\n") ""))) (stars (make-string depth 42))) (concat stars "~" tag-name "~" (if text (concat " `" text "`") "") "\n" attr-text (mapconcat (lambda (child) (org-tagify-node child (1+ depth))) (dom-children node) "")))
  org-tagify-node("\n         " 2)
  (closure ((stars . "*") (attr-text) (attributes) (text) (tag-name . body) (depth . 1) (node body nil "\n         " (header ((data-table . "testtable")) (h1 ((data-field . "testfield")) "Skeleton Screen") "\n             " (h1 ((data-field . "newfield")) "Skeleton Screen") "\n         ") (div ((class . "wrap")) " Sample Text " (p ((class . "format") (data-attribute . "somethingsomething")) "Welcome to this page") "\n             " (div ((class . "flex-grid generic-card")) "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                 " (div (...) "Text ") "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                " (div (...)) "\n             ") "\n         ") "\n     ") t) (child) (org-tagify-node child (1+ depth)))("\n         ")
  mapconcat((closure ((stars . "*") (attr-text) (attributes) (text) (tag-name . body) (depth . 1) (node body nil "\n         " (header ((data-table . "testtable")) (h1 ((data-field . "testfield")) "Skeleton Screen") "\n             " (h1 ((data-field . "newfield")) "Skeleton Screen") "\n         ") (div ((class . "wrap")) " Sample Text " (p ((class . "format") (data-attribute . "somethingsomething")) "Welcome to this page") "\n             " (div ((class . "flex-grid generic-card")) "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                 " (div (...) "Text ") "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                " (div (...)) "\n             ") "\n         ") "\n     ") t) (child) (org-tagify-node child (1+ depth))) ("\n         " (header ((data-table . "testtable")) (h1 ((data-field . "testfield")) "Skeleton Screen") "\n             " (h1 ((data-field . "newfield")) "Skeleton Screen") "\n         ") (div ((class . "wrap")) " Sample Text " (p ((class . "format") (data-attribute . "somethingsomething")) "Welcome to this page") "\n             " (div ((class . "flex-grid generic-card")) "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                 " (div ((class . "card loading")) "Text ") "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                " (div ((class . "card loading"))) "\n             ") "\n         ") "\n     ") "")
  (concat stars "~" tag-name "~" (if text (concat " `" text "`") "") "\n" attr-text (mapconcat (lambda (child) (org-tagify-node child (1+ depth))) (dom-children node) ""))
  (let* ((tag-name (dom-tag node)) (text (and (stringp tag-name) (dom-text node))) (attributes (dom-attributes node)) (attr-text (if attributes (concat ":PROPERTIES\n" (mapconcat (lambda (attr) (format "  - %s: %s" ... ...)) attributes "\n") ""))) (stars (make-string depth 42))) (concat stars "~" tag-name "~" (if text (concat " `" text "`") "") "\n" attr-text (mapconcat (lambda (child) (org-tagify-node child (1+ depth))) (dom-children node) "")))
  org-tagify-node((body nil "\n         " (header ((data-table . "testtable")) (h1 ((data-field . "testfield")) "Skeleton Screen") "\n             " (h1 ((data-field . "newfield")) "Skeleton Screen") "\n         ") (div ((class . "wrap")) " Sample Text " (p ((class . "format") (data-attribute . "somethingsomething")) "Welcome to this page") "\n             " (div ((class . "flex-grid generic-card")) "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                 " (div ((class . "card loading")) "Text ") "\n                 " (comment nil " ADD .loading CLASS TO ANY ELEMENT TO SHIMMER/ANIM...") "\n                " (div ((class . "card loading"))) "\n             ") "\n         ") "\n     ") 1)
  (let* ((mytags (libxml-parse-html-region (point-min) (point-max)))) (org-tagify-node (car (dom-by-tag mytags 'body)) 1))
  (progn (insert tag-entries) (let* ((mytags (libxml-parse-html-region (point-min) (point-max)))) (org-tagify-node (car (dom-by-tag mytags 'body)) 1)))
  (unwind-protect (progn (insert tag-entries) (let* ((mytags (libxml-parse-html-region (point-min) (point-max)))) (org-tagify-node (car (dom-by-tag mytags 'body)) 1))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (insert tag-entries) (let* ((mytags (libxml-parse-html-region (point-min) (point-max)))) (org-tagify-node (car (dom-by-tag mytags 'body)) 1))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (with-current-buffer temp-buffer (unwind-protect (progn (insert tag-entries) (let* ((mytags (libxml-parse-html-region (point-min) (point-max)))) (org-tagify-node (car (dom-by-tag mytags 'body)) 1))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*" t))) (with-current-buffer temp-buffer (unwind-protect (progn (insert tag-entries) (let* ((mytags (libxml-parse-html-region ... ...))) (org-tagify-node (car (dom-by-tag mytags ...)) 1))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  (with-temp-buffer (insert tag-entries) (let* ((mytags (libxml-parse-html-region (point-min) (point-max)))) (org-tagify-node (car (dom-by-tag mytags 'body)) 1)))
  macro-etagify("<html>\n     <head>\n         <title>Demo: Gradient ...")
  (let ((myskel "<html>\n     <head>\n         <title>Demo: Gradient ...")) (macro-etagify myskel))
  eval((let ((myskel "<html>\n     <head>\n         <title>Demo: Gradient ...")) (macro-etagify myskel)) t)
  ielm-eval-input(#("(let ((myskel \"<html>\n     <head>\n         <title>..." 0 1 (fontified t) 1 4 (face font-lock-keyword-face fontified t) 4 14 (fontified t) 14 1003 (face font-lock-string-face fontified t) 1003 1031 (fontified t) 1031 1032 (fontified t rear-nonsticky t)) nil)
  ielm-send-input(nil)
  ielm-return()
  lispy-newline-and-indent-plain()
  funcall-interactively(lispy-newline-and-indent-plain)
  command-execute(lispy-newline-and-indent-plain)

4
  • emacs.stackexchange.com/tags/elisp/info
    – Drew
    Commented Oct 9, 2023 at 1:44
  • Can you please add the expression that you are trying to evaluate in ielm? The debugger elided most of it: ` (let ((myskel \"<html>\n <head>\n <title>...` so wec can't see what you typed and we can't see how you called org-tagify-node. But that is crucial information, without which all that can be said is what @Drew has said in his answer. Please edit the question and add that information to it.
    – NickD
    Commented Oct 9, 2023 at 2:01
  • I have added it earlier, it has been edited. let me add it again,
    – alexander
    Commented Oct 9, 2023 at 2:03
  • @NickD, I've added it.
    – alexander
    Commented Oct 9, 2023 at 2:06

1 Answer 1

0

The error message is telling you that function dom-tag expects a list and it's being passed a string.

Evidently you're passing a string to org-tagify-node, which passes it to dom-tag. Either you need to pass org-tagify-node a list or org-tagify-node needs to first obtain a list from the string you're passing it, and then pass that list to dom-tag.

5
  • Can you please share some snippets?
    – alexander
    Commented Oct 9, 2023 at 1:53
  • Dunno what you mean. org-tagify-node is your code, no? I have no idea what code defines dom-tag. I'm just explaining that your code is passing a string to a function that requires/expects a list. It's up to you to figure out what list to pass it, to get the behavior you want.
    – Drew
    Commented Oct 9, 2023 at 1:57
  • it's rather org-tagify-node I renamed the function to dom-tag to help in debugging.
    – alexander
    Commented Oct 9, 2023 at 2:01
  • I have updated the code, can you look at it ?
    – alexander
    Commented Oct 9, 2023 at 2:21
  • 1
    The children of a node are not necessarily nodes: they can be strings, so when org-tagify-node is called recursively on the first child of the body, it gets a string as argument and gives you the error. You will either need to filter out such strings before you call org-tagify-node recursively (and also at top level obviously, its caller (macro-etagify in this case) would also have to enforce that restriction); or you would have to make org-tagify-node smarter and able to deal with strings as well.
    – NickD
    Commented Oct 9, 2023 at 2:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.