[Top][All Lists]
[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<?))
Re: define-grobs.scm properties not alphabetical, Carl D. Sorensen, 2009/06/19