lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: define-grobs.scm properties not alphabetical


From: Mark Polesky
Subject: Re: define-grobs.scm properties not alphabetical
Date: Sun, 21 Jun 2009 01:50:48 -0700 (PDT)

Graham Percival wrote:
> > > I prefer case-insensitive so X-offset and Y-offset are near the
> > > bottom (where I expect to find them). Let me know if you object.
> > 
> > Please use the alphabetical ordering used in other SCM files.  I don't
> > mind if you move around the uppercased properties in all SCM files,
> > but it should be consistent -- maybe it makes sense to document the
> > ordering in the SCM files itself...
> 
> Either in the SCM files, or the "programming" chapter of the CG.
> I lean towards the CG, but this would require that new programmers
> read the CG first.

I have an even better idea. We can specify a sorting order as
specific as we want (to suit our own purposes), and then define
sorting predicates like ly:symbol<? and ly:symbol-ci<? to use with
sorting procedures to sort all our alists and organize everything
predictably. We could define-public these in lily-library.scm.

I know what you're thinking, well, don't all volunteer at once!
I've actually explored this a little bit, and here are some of my 
ideas...

I (somewhat arbitrarily) ranked certain non-alphanumeric
characters in terms of where they're likely to be found within a
scheme symbol. For example, ! and ? are most likely to be found
at the end of a symbol; - and : are most likely to be found in the
middle of a symbol, and : is a stronger separator than - (consider
ly:staff-symbol::print, for example).

It may be counterintuitive, but it works best to put symbol
terminators *earlier* in the sorting order than weak separators,
so that, for example, ! is "less than" -.

Consider the two symbols ly:grob? and ly:grob-array?. In ASCII, 
- comes before ?, so these symbols are normally sorted this way:
  ly:grob-array?
  ly:grob?

But with the terminator ? set earlier than the separator -, the
sorting order becomes more intuitive (to me, at least).
  ly:grob?
  ly:grob-array?

Similarly, strong separators like : ought to be "less than" weak
separators like -. For example, in ASCII, - comes before :. This
leads to the following sort-order:
  ly:staff-symbol-referencer::callback
  ly:staff-symbol::print

With : earlier than -, the sort-order becomes more intuitive:
 ly:staff-symbol::print
 ly:staff-symbol-referencer::callback

Here is my ranking of the non-alphanumeric characters that seemed
most likely to be found in scheme symbols:

symbol tokenizers
[space]

symbol terminators
!?

symbol terminators/separators
<=>

strong symbol separators
:

weak symbol separators (maybe _ doesn't belong here, I don't know)
-_


I then took these characters out of their positions in ASCII, and
put them at the front of the list, so to speak.

ASCII order:
 !"#$%&'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^_
`abcdefghijklmno
pqrstuvwxyz{|}~

My order:
 !?<=>:-_
  "#$%&'()*+, ./
0123456789;
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\]^
`abcdefghijklmno
pqrstuvwxyz{|}~


Then I took 10 symbols found in the LilyPond source and compared
the normal ASCII sort with my sort:

ASCII sort:
  ly:module->alist
  ly:module-copy
  ly:moment-sub
  ly:moment<?
  ly:moment?
  ly:otf->cff
  ly:otf-font-glyph-info
  ly:otf-font?
  ly:staff-symbol-referencer::callback
  ly:staff-symbol::print

My sort:
  ly:module->alist
  ly:module-copy
  ly:moment?
  ly:moment<?
  ly:moment-sub
  ly:otf->cff
  ly:otf-font?
  ly:otf-font-glyph-info
  ly:staff-symbol::print
  ly:staff-symbol-referencer::callback

Isn't this better? Then we can change line 2286 in
define-grobs.scm from this:

(set! all-grob-descriptions
      (sort all-grob-descriptions alist-ci<?))

to this:

(set! all-grob-descriptions
      (sort all-grob-descriptions ly:alist-ci<?))

It's easy enough to write similar procedures for sorting the
properties and interfaces, too.

Here's a suite of procedures to demonstrate my basic sorting
algorithm.

Comments appreciated.
- Mark

________________________________________________


(define (ly:char<? a b)
  (let* ((init-list (string->list " !?<=>:-_"))
         (mem-a (member a init-list))
         (mem-b (member b init-list)))
    (if mem-a
        (if mem-b
            (< (length mem-b) (length mem-a))
            #t)
        (char<? a b))))

(define (mismatch str0 str1 ci?)
  (let loop ((a (string->list str0)) (b (string->list str1)))
    (cond ((null? a) (if (null? b) #f (cons #f (car b))))
          ((null? b) (cons (car a) #f))
          (((if ci? char-ci=? char=?) (car a) (car b))
              (loop (cdr a) (cdr b)))
          (else (cons (car a) (car b))))))

(define-public (ly:string<? a b)
  "Move the characters <space> !?<=>:-_ to the front of the ASCII set,
   then do a case-sensitive comparison using the new order."
  (let ((mismatch (mismatch a b #f)))
    (if mismatch
        (if (car mismatch)
            (if (cdr mismatch)
                (ly:char<? (car mismatch) (cdr mismatch))
                #f)
           (if (cdr mismatch) #t #f))
       #f)))
       
(define-public (ly:string-ci<? a b)
  "Move the characters <space> !?<=>:-_ to the front of the ASCII set,
   then do a case-insensitive comparison using the new order."
  (let ((mismatch (mismatch a b #t)))
    (if mismatch
        (if (car mismatch)
            (if (cdr mismatch)
                (ly:char<? (car mismatch) (cdr mismatch))
                #f)
           (if (cdr mismatch) #t #f))
       #f)))
             
(define-public (ly:symbol<? a b)
  (ly:string<? (symbol->string a) (symbol->string b)))
  
(define-public (ly:symbol-ci<? a b)
  (ly:string-ci<? (symbol->string a) (symbol->string b)))

(define-public (ly:alist<? a b)
  (ly:string<? (symbol->string (car a))
               (symbol->string (car b))))
               
(define-public (ly:alist-ci<? a b)
  (ly:string-ci<? (symbol->string (car a))
                  (symbol->string (car b))))

;;;;;; demonstration ;;;;;;

(use-modules (ice-9 pretty-print))
(pretty-print
  (sort
    '(ly:module->alist
      ly:module-copy
      ly:moment-sub
      ly:moment<?
      ly:moment?
      ly:otf->cff
      ly:otf-font-glyph-info
      ly:otf-font?
      ly:staff-symbol-referencer::callback
      ly:staff-symbol::print)
    ;; replace with ly:symbol-ci<? to see the difference
    symbol-ci<?))



      




reply via email to

[Prev in Thread] Current Thread [Next in Thread]