Hello,

In the thread about creating custom metronome markups
(http://lists.gnu.org/archive/html/lilypond-user/2008-04/msg00629.html)
and the subsequent discussion at The LilyPond Report, Valentin
expressed the wish for a convenient way to convert duration strings to
durations.  Since I agreed, I thought I'd have a go at implementing an
exported scheme function in duration-scheme.cc which can be used
within lilypond files.

Attached is a patch with "My First C++ Code", which provides this
functionality. :)

Regards,
Neil
From a33b00dd24d4174e6279e9afb66e3ff719767d53 Mon Sep 17 00:00:00 2001
From: Neil Puttock <[EMAIL PROTECTED]>
Date: Fri, 16 May 2008 19:41:36 +0100
Subject: [PATCH] Scheme function ly:string->duration

---
 lily/duration-scheme.cc |   50 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)

diff --git a/lily/duration-scheme.cc b/lily/duration-scheme.cc
index d371475..2b03862 100644
--- a/lily/duration-scheme.cc
+++ b/lily/duration-scheme.cc
@@ -7,8 +7,13 @@
   Han-Wen Nienhuys <[EMAIL PROTECTED]>
 */
 
+#include <sstream>
+using namespace std;
+
 #include "duration.hh"
+#include "international.hh"
 #include "misc.hh"
+#include "warn.hh"
 
 MAKE_SCHEME_CALLBACK (Duration, less_p, 2);
 SCM
@@ -136,3 +141,48 @@ LY_DEFINE (ly_duration_factor, "ly:duration-factor",
   Rational r = unsmob_duration (dur)->factor ();
   return scm_cons (scm_from_int (r.num ()), scm_from_int (r.den ()));
 }
+
+LY_DEFINE (ly_string_2_duration, "ly:string->duration",
+	   1, 0, 0, (SCM str),
+	   "Convert @var{str} to a duration.")
+{
+  LY_ASSERT_TYPE (scm_is_string, str, 1);
+  string s = ly_scm2string (str);
+  stringstream stream (s);
+  int len = 0;
+  int dots = 0;
+  size_t pos = 0;
+
+  while (pos !=NPOS)
+    {
+      pos = s.find (".", pos);
+      if (pos != NPOS)
+	{
+	  dots++;
+	  pos++;
+	}
+    }
+  s = s.substr (0, (s.length () - dots));
+
+  stream >> len;
+  if (!stream.fail () && (len && len == 1 << intlog2 (len)))
+      len = intlog2 (len);
+  else
+    {
+      if (s == "breve")
+	  len = -1;
+      else if (s == "longa")
+	  len = -2;
+      else if (s == "maxima")
+	  len = -3;
+      else
+        {
+	  len = 0;
+	  dots = 0;
+	  warning (_ ("invalid duration string, setting to whole note"));
+	}
+    }
+
+  Duration p (len, dots);
+  return p.smobbed_copy ();
+}
-- 
1.5.4.3

_______________________________________________
lilypond-devel mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to