[Kieren]
The page in the Internals Reference doesn't
list all the properties that the grob would
support, only those for which it has a specific
default. You have to explore the interfaces to
find other interesting properties that you can
tweak. In this case, click "Item" ("This object
is of class Item"). You'll find extra-spacing-width
in the item-interface.
This is something I’ve asked a couple times before, but been dismissed… Maybe 
you can help?

Is there an Automagic™ way to print out a “complete tree” of all properties 
that a grob supports, including any default values?


Sure. How about the attached?

Bear in mind that this may stop working in future
versions (in fact I have a branch somewhere that
would definitely break it if I ever manage to
complete the work).


[Paolo]
Thanks.

However, when looking for a property or function that might fit what I need, I always check for inherited stuff. In this case, unfortunately, the search is a bit cumbersome and tricky and it's not the first time, especially when the properties are so many and I have to write the code quickly, that I don't find the right property. Suppose that an object has many settable properties: there is a main page of this object, let's call it "A", and other pages with inherited properties (B, C, D, E etc.) When I do a search, I first look inside A: if I don't find anything useful, I look in B and if I don't find anything useful here too, I go back to A and then I go to C etc. You can understand that, when there are so many properties, jumping back and forth from page to page is inconvenient to remember what is available as a sum of things. In many automatic documentation of other libraries I use, the inherited properties and functions are listed grouped (with relative links), sometimes in small format, at the bottom of the page to avoid this inconvenience. It is true that the resulting page is longer, but it is not heavier to read. Furthermore, in this way you can read only the names, without the descriptions, of these properties and this allows you to decide whether or not to jump to the page that defines the inherited property to try. Mine is a suggestion, and I think it's useful to add it to the documentation (or at least explain how to create this "extra" documentation automatically)


Would the attached mock a good way to format
this documentation in your opinion?

Best,
Jean
\version "2.23.4"

#(define (indent n lines)
   (let ((padding (make-string n #\space)))
     (string-join
       (map
         (lambda (line)
           (string-append padding line))
         lines)
       "\n")))

#(define (wrap n str)
   (let ((components (filter
                       (lambda (s)
                         (not (string-null? s)))
                       (apply append
                            (map (lambda (s)
                                   (string-split s #\space))
                                 (string-split str #\newline))))))
     (let loop ((rest components)
                (lines-acc '())
                (current-line-acc '())
                (pos 0))
       (if (null? rest)
           (map (lambda (line)
                  (string-join line " "))
                (reverse! (cons (reverse! current-line-acc)
                                lines-acc)))
           (let* ((next (car rest))
                  (remaining (cdr rest))
                  (added-len (1+ (string-length next)))
                  (new-pos (+ pos added-len)))
             (if (>= new-pos n)
                 (loop remaining
                       (cons (reverse! current-line-acc)
                             lines-acc)
                       (list next)
                       added-len)
                 (loop remaining
                       lines-acc
                       (cons next current-line-acc)
                       new-pos)))))))

#(define (format-symbol-list lst)
   (string-join (map symbol->string lst)
                ", "))

#(define (format-default default)
   (cond
     ((unspecified? default)
       "")
     ((procedure? default)
      (format #f "  ~a\n" (procedure-name default)))
     (else
      (indent 2 (string-split (format #f "~y" default)
                              #\newline)))))

#(define (format-property-entry property default interfaces)
   (format #f
           "\
* ~a (from ~a)
  ~a
~a
~a"
           property
           (format-symbol-list interfaces)
           (make-string (string-length (symbol->string property))
                        #\-)
           (format-default default)
           (indent 5 (wrap 74 (object-property property 'backend-doc)))))

#(define (basic-doc name classes interfaces)
   (format #f
           "

~a
~a

~a

Classes: ~a

"
           name
           (make-string (string-length (symbol->string name))
                        #\=)
           (let* ((formatted-list (format-symbol-list interfaces))
                  (formatted-text (format #f "Interfaces supported: ~a" formatted-list)))
             (string-join (wrap 79 formatted-text)
                          "\n"))
           (format-symbol-list classes)))

info =
#(define-void-function (grob-name) (symbol?)
   (let* ((definition (assq-ref all-grob-descriptions grob-name))
          (meta (assq-ref definition 'meta))
          (properties (alist->hash-table (assq-remove! definition 'meta)))
          (classes (assq-ref meta 'classes))
          (interfaces (assq-ref meta 'interfaces))
          (basic (basic-doc grob-name classes interfaces))
          (property-interfaces-table (make-hash-table))
          (all-interfaces (ly:all-grob-interfaces)))
     (for-each
       (lambda (interface)
         (let ((interface-properties (third (hashq-ref all-interfaces interface))))
           (for-each
             (lambda (property)
               (if (not (object-property property 'backend-internal))
                  (hashq-set! property-interfaces-table
                              property
                              (cons interface
                                    (hashq-ref property-interfaces-table property '())))))
             interface-properties)))
       interfaces)
     (let* ((property-alist (hash-map->list cons property-interfaces-table))
            (sorted-property-alist
              (sort property-alist
                    (comparator-from-key (lambda (pair)
                                            (symbol->string (car pair)))
                                         string-ci<?)))
            (property-descriptions
              (map
                (lambda (entry)
                  (let* ((property (car entry))
                         (interfaces (cdr entry))
                         (default-handle (hashq-get-handle properties property))
                         (default (if default-handle
                                      (cdr default-handle)
                                      *unspecified*)))
                    (format-property-entry property default interfaces)))
                sorted-property-alist)))
       (display (string-append basic
                               (string-join property-descriptions "\n\n")
                               "\n")
                (current-error-port)))))


\info BarLine

Reply via email to