~ubuntu-branches/ubuntu/vivid/frescobaldi/vivid

« back to all changes in this revision

Viewing changes to python/ly/duration.py

  • Committer: Package Import Robot
  • Author(s): Ryan Kavanagh
  • Date: 2012-01-03 16:20:11 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120103162011-tsjkwl4sntwmprea
Tags: 2.0.0-1
* New upstream release 
* Drop the following uneeded patches:
  + 01_checkmodules_no_python-kde4_build-dep.diff
  + 02_no_pyc.diff
  + 04_no_binary_lilypond_upgrades.diff
* Needs new dependency python-poppler-qt4
* Update debian/watch for new download path
* Update copyright file with new holders and years

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# This file is part of the Frescobaldi project, http://www.frescobaldi.org/
2
 
#
3
 
# Copyright (c) 2008, 2009, 2010 by Wilbert Berendsen
4
 
#
5
 
# This program is free software; you can redistribute it and/or
6
 
# modify it under the terms of the GNU General Public License
7
 
# as published by the Free Software Foundation; either version 2
8
 
# of the License, or (at your option) any later version.
9
 
#
10
 
# This program is distributed in the hope that it will be useful,
11
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
# GNU General Public License for more details.
14
 
#
15
 
# You should have received a copy of the GNU General Public License
16
 
# along with this program; if not, write to the Free Software
17
 
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
# See http://www.gnu.org/licenses/ for more information.
19
 
 
20
 
from __future__ import unicode_literals
21
 
 
22
 
""" LilyPond information and logic concerning durations """
23
 
 
24
 
import ly.rx
25
 
 
26
 
 
27
 
durations = ['\\maxima', '\\longa', '\\breve',
28
 
    '1', '2', '4', '8', '16', '32', '64', '128', '256', '512', '1024', '2048']
29
 
 
30
 
def editRhythm(func):
31
 
    """
32
 
    Decorator to handle functions that are the callback for the regexp.
33
 
    """
34
 
    def decorator(text):
35
 
        def repl(m):
36
 
            return m.group('duration') and func(m) or m.group()
37
 
        return ly.rx.chord_rest.sub(repl, text)
38
 
    return decorator
39
 
 
40
 
@editRhythm
41
 
def doubleDurations(m):
42
 
    chord, dur, dots, scale = m.group('chord', 'dur', 'dots', 'scale')
43
 
    if dur in durations:
44
 
        i = durations.index(dur)
45
 
        if i > 0:
46
 
            dur = durations[i - 1]
47
 
    return ''.join(i or '' for i in (chord, dur, dots, scale))
48
 
 
49
 
@editRhythm
50
 
def halveDurations(m):
51
 
    chord, dur, dots, scale = m.group('chord', 'dur', 'dots', 'scale')
52
 
    if dur in durations:
53
 
        i = durations.index(dur)
54
 
        if i < len(durations) - 1:
55
 
            dur = durations[i + 1]
56
 
    return ''.join(i or '' for i in (chord, dur, dots, scale))
57
 
 
58
 
@editRhythm
59
 
def dotDurations(m):
60
 
    chord, dur, dots, scale = m.group('chord', 'dur', 'dots', 'scale')
61
 
    dots = (dots or '') + '.'
62
 
    return ''.join(i or '' for i in (chord, dur, dots, scale))
63
 
 
64
 
@editRhythm
65
 
def undotDurations(m):
66
 
    chord, dur, dots, scale = m.group('chord', 'dur', 'dots', 'scale')
67
 
    if dots:
68
 
        dots = dots[1:]
69
 
    return ''.join(i or '' for i in (chord, dur, dots, scale))
70
 
 
71
 
@editRhythm
72
 
def removeScaling(m):
73
 
    return ''.join(i or '' for i in m.group('chord', 'dur', 'dots'))
74
 
 
75
 
@editRhythm
76
 
def removeDurations(m):
77
 
    return m.group('chord')
78
 
 
79
 
def makeImplicit(text):
80
 
    old = ['']
81
 
    def repl(m):
82
 
        chord, duration = m.group('chord', 'duration')
83
 
        if chord:
84
 
            if not duration or duration == old[0]:
85
 
                return chord
86
 
            else:
87
 
                old[0] = duration
88
 
                return chord + duration
89
 
        return m.group()
90
 
    return ly.rx.chord_rest.sub(repl, text)
91
 
 
92
 
def makeImplicitPerLine(text):
93
 
    return '\n'.join(makeImplicit(t) for t in makeExplicit(text).split('\n'))
94
 
    
95
 
def makeExplicit(text):
96
 
    old = ['']
97
 
    def repl(m):
98
 
        chord, duration = m.group('chord', 'duration')
99
 
        if chord:
100
 
            if not duration:
101
 
                return chord + old[0]
102
 
            else:
103
 
                old[0] = duration
104
 
                return chord + duration
105
 
        return m.group()
106
 
    return ly.rx.chord_rest.sub(repl, text)
107
 
 
108
 
def applyRhythm(text, rhythm):
109
 
    """ Adds the entered rhythm to the selected music."""
110
 
    durs = [m.group() for m in ly.rx.finddurs.finditer(rhythm)]
111
 
    if not durs:
112
 
        return text
113
 
    def durgen():
114
 
        old = ''
115
 
        while True:
116
 
            for i in durs:
117
 
                yield i != old and i or ''
118
 
                old = i
119
 
    durations = durgen()
120
 
    def repl(m):
121
 
        if m.group('chord'):
122
 
            return m.group('chord') + next(durations)
123
 
        return m.group()
124
 
    return ly.rx.chord_rest.sub(repl, text)
125
 
 
126
 
def extractRhythm(text):
127
 
    """ Iterate over a rhythm from text, returning only the durations """
128
 
    duration = ''
129
 
    for m in ly.rx.chord_rest.finditer(text):
130
 
        if m.group('chord'):
131
 
            if m.group('duration'):
132
 
                duration = m.group('duration')
133
 
            yield duration
134