In the follow-up of this question, I am trying to edit a gnus-button text-property, called gnus-data, so that when my invitation emails are exported/updated into org-mode any MS safelinks have been filtered out. Now, I have no idea of what the text property is a printed representation of. I've tried to do a car or hash-table-count to check if it's a list or hash-table and got a wrong argument type for both. type-of isn't much more helpful, as it returns gnus-icalendar-event-request.

My problem is how to update that representation to filter out the safelinks and then save it back in the gnus-data text-property?

The below function is based on my previous question and has my current progress towards retrieving the printed representation object.

(defun unsafelinks (vmode)
  "This function filters MS safelinks from a message buffer"
  (let ((simple-url-regexp "https?://") urls)
      ;; edit text URLs
      (while (search-forward-regexp simple-url-regexp nil t)
    (when-let ((url (thing-at-point 'url))
           (bounds (thing-at-point-bounds-of-url-at-point)))
      (delete-region (car bounds) (cdr bounds))
      (insert (my-decode-safelink url))))
      ;; edit gnus data for invitation save/update to org-mode
      (while (not (eobp)) 
    (goto-char (next-overlay-change (point)))
    (when-let (link (get-text-property (point) 'gnus-data))
      (if (equal (get-text-property (point) 'gnus-callback) 'gnus-icalendar-sync-event-to-org)
          (type-of (eval link))))
    (goto-char (next-overlay-change (point))))
      ;; edit widget URLs
      (while (not (eobp)) 
    (goto-char (next-overlay-change (point)))
    (when-let (link (get-text-property (point) 'shr-url))             
      (and (string-match simple-url-regexp link) 
           ;; change overlay url echo
           (when (overlay-put (car (overlays-at (point))) 'help-echo (my-decode-safelink link)) t)
           ;; change url text-properties 
           (add-text-properties (point) (next-overlay-change (point)) (list 'shr-url (my-decode-safelink link) 'help-echo (my-decode-safelink link))) 
    (goto-char (next-overlay-change (point))))
      (when vmode (gnus-article-prepare-display)
        (set-buffer-modified-p nil)

And this is an edited example of what the printed representation looks like (I've inserted the link example from my previous question).

#s(gnus-icalendar-event-request "donald.duck@disney.com" "Disney catch-up meeting" "This is a general meeting.\n________________________________________________________________________________\nJoin Disney Teams Meeting<https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Foffice.memoriesflower.com%2FPermission%2F%2525%2524%255E%2526%2526*%2523%2523%255E%2524%2525%255E%2526%255E*%2526%2523%255E%2525%2525%2526%2540%255E*%2523%2526%255E%2525%2523%2526%2540%2525*%255E%2540%255E%2523%2525%255E%2540%2526%2525*%255E%2540%2Foffice.php&data=01%7C01%7Cdavid.levin%40mheducation.com%7C0ac9a3770fe64fbb21fb08d50764c401%7Cf919b1efc0c347358fca0928ec39d8d5%7C0&sdata=PEoDOerQnha%2FACafNx8JAep8O9MdllcKCsHET2Ye%2B4%3D&reserved=0>\n________________________________________________________________________________\n\n" "Disney Teams Meeting"
                (24387 42168)
                (24387 45768)
                nil "040000008200E00074C5B7101A82E00800000000304C204C352DD601000000000000000010000000EC49B8272CC9E446882F1BCD53D14E6B" "REQUEST" t required
                ("Mickey Mouse" "mickey.mouse@disney.com" "Goofy" "Goofy@disney.com" )


The printed representation of an object is usually valid syntax for creating the object, so all you have to do is read it; read is the lisp function which parses a string to build lisp objects from their printed representations. After you've modified it, you can print the object to create a string with the printed representation of the object in it.

As a mnemonic, recall that REPL stands for the Read Eval Print Loop. All the lisp repl is doing is looping forever reading your input, evaluating it, then printing the results.

| improve this answer | |
  • Thanks. But I think read doesn't work for whatever this object is. When I eval (read object) on scratch I get a read: Invalid function: #s(gnus-icalendar-event-request ... error :-(. The type-of command on the other hand returns a gnus-icalendar-event-request type – Ajned May 25 at 20:13
  • Is your object variable actually a string? It looks like you're passing it an object rather than a string. – db48x May 25 at 20:19
  • I don't think it is a string. I'm evaluating like this (read #s(gnus-icalendar-event-request ...)) – Ajned May 25 at 20:22
  • Yea, then you're not passing it a string. Remember that in order to evaluate anything in the scratch buffer, Emacs has to first read it. This means that (read #s(…)) is first read and turned into the lisp object '(read #<some actual object>), which is then then evaluated by passing the object to the read function. If you instead type in (read "#s(…)"), then it will read in '(read "the string containing #s(…)"), and when evaluating it it will pass the string to read. – db48x May 25 at 20:28
  • You can see that discussing this is very fun, since to do so we have to use the printed representations of both the code we've typed in, and the lisp objects that eval is operating on. They're generally the same thing! – db48x May 25 at 20:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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