You can extract properties from a given position of a string or buffer with function
text-properties-at. Here's its docstring (
C-h f text-properties-at):
text-properties-at is a built-in function in ‘C source code’.
(text-properties-at POSITION &optional OBJECT)
Return the list of properties of the character at POSITION in OBJECT.
If the optional second argument OBJECT is a buffer (or nil, which means
the current buffer), POSITION is a buffer position (integer or marker).
If OBJECT is a string, POSITION is a 0-based index into it.
If POSITION is at the end of OBJECT, the value is nil.
Once you have the properties (it's a list) you can turn it into a string using
format. For example (from @Drew):
(setq mystrg (propertize "abcd" 'foo 'foo-prop 'bar 'bar-prop))
(text-properties-at 0 mystrg) ; ==> (foo foo-prop bar bar-prop)
(setq prop-strg (format "%s" (text-properties-at 0 mystrg)))
For more info, see the section of elisp manual on Examining Text Properties.
However if you're interested in showing all the properties and where they apply in the string (that is, you want to get as a string the part about properties of the printed representation of the string) then you can get the printed representation with
prin1-to-string then extract the part with properties (that is, after the representation of the string itself).
It turns out to be not so simple, because the printed representation differs according to the presence of properties of not, and the length of the text part varies if escapes are present. For a straight string the text representation is:
while for a string with properties it is:
#("the string" 0 3 (properties) ...)
but can also be:
#("a string with a \" inside" 0 3 (properties) ...)
Here is a tentative function:
(defun get-string-properties-as-string (st)
"Return a string showing the properties of ST."
(let ((p (prin1-to-string st)))
(if (eq (elt p 0) ?#)
(let ((nb (length (seq-filter (lambda (c) (eq c ?\")) st))) ;; how many " in ST
(p (substring p 2 (1- (length p))))) ;; remove #( and )
(loop for i from 1 to (+ 2 nb) do
;; remove characters up to the next "
(setq p (seq-drop p (1+ (seq-position p ?\")))))
;; string with no properties
Maybe someone will propose a better way to do that, it looks rather ugly I think.