Lilypond macro that outputs a \score block - lilypond

I have the following Lilypond source file consisting of a few blocks of the following form:
global = \relative { ... }
Soprano = \relative { ... }
Alto = \relative { ... } % ditto Tenor, Bass
\score { \new StaffGroup <<
\new Staff << \clef "G" \global \Soprano >>
\new Staff << \clef "G" \global \Alto >>
\new Staff << \clef "G_8" \global \Tenor >>
\new Staff << \clef "F" \global \Bass >>
>> \layout { } }
Obviously the global, Soprano, Alto, Tenor, Bass definitions change each time, but the \score block remains the same.
I want to factor that block in a Scheme macro. However, the simplest definition I tried,
#(define (Choral) (ly:make-score #{ \new StaffGroup <<
\new Staff << \clef "G" \global \Soprano >>
\new Staff << \clef "G" \global \Alto >>
\new Staff << \clef "G_8" \global \Tenor >>
\new Staff << \clef "F" \global \Bass >>
>> #} ))
has the following inconvenients: (1) it must be invoked by #(Choral) instead of the more natural \Choral, and worse, (2) it produces no output whatsoever. If I try to put a \layout { } block in the (Choral) definition lilypond produces the following error: error: syntax error, unexpected \layout.
Is there a simple way to write a macro that produces a \score block with attached \layout ?

Why a Scheme macro? You can just use \include (it's like pasting the content of a file in the line you put it). So you might use the same score block file:
% myScoreBlock.ly file
\score {
\new StaffGroup <<
\new Staff << \clef "G" \global \Soprano >>
\new Staff << \clef "G" \global \Alto >>
\new Staff << \clef "G_8" \global \Tenor >>
\new Staff << \clef "F" \global \Bass >>
>> \layout { }
}
to be included in any other file which have the same variables:
% example of a piece
\version "2.19.54"
global = { \time 2/4 }
Soprano = \relative { d2 }
Alto = \relative { f2 }
Tenor = \relative { e2 }
Bass = \relative { g2 }
\include "myScoreBlock.ly"
Another option to reduce the size of the input is using built-in templates. There's also a built-in template for SATB scores.

Related

how to detect "​" (combination of unicode) in c++ string

I am trying to detect some of the combination of Unicode character (like ​) to cleanup the string, For a single Unicode character it is detecting but combination of Unicode is not detecting.
These string I am using to make HTML page from another HTML page which need to be cleanup. I want to clean only string which have these kind of unicode that not even visible in html page in browser.
below is the sample code:
void detect_Unicode(string& str) {
if(!str.empty() && str.find_first_not_of(" \t\n\r\f\v\u00A0\u00C2\u00E2\u20AC\u2039")==string::npos)
str.assign(" ");
return;
}
Input string:
1. " ​ ​ " ;
2. "are   there is something    ​ combination ​"
3. " Â Â "
4. "​   ​"
5 . "Â Â â â"
Expected Output:
1. " "
2. "are   there is something    ​ combination ​"
3. " "
4. " "
5. " "
Please let me know other ways too.
OK, following on from the comments above, I think it's highly likely that the input string is in UTF-8 (after all, in an HTML context, what else would it be?).
On that basis, I humbly submit this:
#include <string>
#include <codecvt>
#include <locale>
std::string narrow (const std::wstring& ws)
{
std::wstring_convert <std::codecvt_utf8 <wchar_t>, wchar_t> convert;
return convert.to_bytes (ws);
}
std::wstring widen (const std::string& s)
{
std::wstring_convert <std::codecvt_utf8 <wchar_t>, wchar_t> convert;
return convert.from_bytes (s);
}
std::string detect_Unicode (const std::string& s)
{
std::wstring ws = widen (s);
if (ws.empty() || ws.find_first_not_of (L" \t\n\r\f\v\u00A0\u00C2\u00E2\u20AC\u2039") != std::wstring::npos)
return " ";
return s;
}
#include <iostream>
int main ()
{
std::cout << narrow (L"\u00A0 \u00C2 \u00E2 \u20AC \u2039\n\n");
std::cout << "0.\t\"" << detect_Unicode (u8"abcde") << "\"\n";
std::cout << "1.\t\"" << detect_Unicode (u8" ​ ​ ") << "\"\n";
std::cout << "2.\t\"" << detect_Unicode (u8"are   there is something    ​ combination ​") << "\"\n";
std::cout << "3.\t\"" << detect_Unicode (u8" Â Â ") << "\"\n";
std::cout << "4.\t\"" << detect_Unicode (u8"​   ​") << "\"\n";
std::cout << "5.\t\"" << detect_Unicode (u8"Â Â â â") << "\"\n";
}
Output:
 ⠀ ‹
0. " "
1. " ​ ​ "
2. " "
3. " Â Â "
4. "​   ​"
5. "Â Â â â"
Now this is not the output the OP expects, but I think that's simply because the logic (as opposed to the implementation) of detect_Unicode() looks flawed. The point here is that converting the input string to a wide string means that you can use standard basic_string operations on it reliably, because there are no multibyte issues now.
An alternative, slightly radical, implementation of detect_Unicode() might be:
for (auto wide_char : ws)
{
if (wide_char > 0xff)
return " ";
}
return s;
But really, now you have a wide string to hand in detect_Unicode, anything is possible, so go wild OP.
Other notes:
std::codecvt is deprecated in C++17, but since there is no other obvious choice you might as well run with it. You can always change the implementations of narrow and widen if it comes to it.
Depending on platform, std::wstring might not be the best choice but it's probably fine. You could also look at std::u16string and std::u32string.
Live demo.
Inspiration taken from here.

Foreach output into a file

Here is the code I tried
foreach_in_collection t1 [ ga ...] {
set f1 [ga $t1 type_name]
set f2 [ga $t1 bb]
puts $f1
puts $f2
puts $file1 $f1 $f2
}
I want to write two output $f1 and $f2 to $file1, please let me know
above puts $file1 [list $f1 $f2] also doesn't works..
Try this:
set fd [open out.txt w]
foreach {x y} [list a b c d e] {
puts x=$x
puts y=$y
puts $fd $x
puts $fd $y
}
close $fd
Output file (before):
$ cat out.txt
cat: out.txt: No such file or directory
$
Execution output:
$ tclsh foo.tcl
x=a
y=b
x=c
y=d
x=e
y=
$
Output file (after):
$ cat out.txt
a
b
c
d
e
$
Sharad's solution is perfect. There is one more way if you want to try.
SBORDOLO-M-V1VG:EXPERIMENT sbordolo$ cat a11
exec rm -rf out1.txt ;# No need to worry about file is there or not.
exec touch out1.txt
exec chmod 777 out1.txt ;#You can give a write permission here. I have given 777 just like that
foreach {x y} [list a b c d e f] {
puts x=$x
puts y=$y
exec echo $x >> out1.txt
exec echo $y >> out1.txt
}
When you run the script:
SBORDOLO-M-V1VG:EXPERIMENT sbordolo$ tclsh a11
x=a
y=b
x=c
y=d
x=e
y=f
SBORDOLO-M-V1VG:EXPERIMENT sbordolo$ cat out1.txt
a
b
c
d
e
f

Can't build very simple tcl application

I'm trying to write a very simple Tcl application in C++:
#include <tcl.h>
#include <iostream>
int main (int argc, char *argv[])
{
std::cout << "Calling Tcl_FindExecutable." << std::endl;
Tcl_FindExecutable (argv[0]);
std::cout << "Calling Tcl_CreateInterp." << std::endl;
Tcl_Interp *pInterp = Tcl_CreateInterp ();
if (Tcl_Eval (pInterp, "puts stdout {Hello, World!}") != TCL_OK)
{
std::cerr << "Error: " << Tcl_GetStringResult (pInterp) << std::endl;
return (0);
}
if (Tcl_Eval (pInterp, "puts stdout [info nameofexecutable]") != TCL_OK)
{
std::cerr << "Error: " << Tcl_GetStringResult (pInterp) << std::endl;
return (0);
}
return (1);
}
I can compile it via g++ -c Wall -I/opt/ActiveTcl-8.6/include noddy.cpp -o noddy.o
but when I link it, with g++ -L/opt/ActiveTcl-8.6/lib -ltcl8.6 -o noddy noddy.o
I get errors saying that all the Tcl library procedures are undefined.
What am I doing wrong, please?
Edit
The actual commands were
$ g++ -c -Wall -I/opt/ActiveTcl-8.6/include noddy.cpp -o noddy.o
$ g++ -L/opt/ActiveTcl-8.6/lib -ltcl8.6 -o noddy noddy.o
noddy.o: In function 'main':
noddy.cpp:(.text+0x37): undefined reference to 'Tcl_FindExecutable'
noddy.cpp:(.text+0x60): undefined reference to 'Tcl_CreateInterp'
noddy.cpp:(.text+0x78): undefined reference to 'Tcl_Eval'
noddy.cpp:(.text+0x8d): undefined reference to 'Tcl_GetStringResult'
noddy.cpp:(.text+0xda): undefined reference to 'Tcl_Eval'
noddy.cpp:(.text+0xef): undefined reference to 'Tcl_GetStringResult'
collect2: ld returned 1 exit status
In link statements the order of object modules and libraries is significant. You should include the object first and then the libraries (redone as C to avoid installing g++):
> gcc -Wall -I/opt/tcl/include -c noddy.c
> gcc -o noddy.exe noddy.o -L/opt/tcl/lib -ltcl86
> noddy
Calling Tcl_FindExecutable.
Calling Tcl_CreateInterp.
Hello, World!
C:/Code/noddy.exe
But:
> gcc -o noddy.exe -L/opt/tcl/lib -ltcl86 noddy.o
noddy.o:noddy.c:(.text+0x23): undefined reference to '_imp__Tcl_FindExecutable'
noddy.o:noddy.c:(.text+0x36): undefined reference to '_imp__Tcl_CreateInterp'
noddy.o:noddy.c:(.text+0x50): undefined reference to '_imp__Tcl_Eval'
noddy.o:noddy.c:(.text+0x62): undefined reference to '_imp__Tcl_GetStringResult'
noddy.o:noddy.c:(.text+0x9b): undefined reference to '_imp__Tcl_Eval'
noddy.o:noddy.c:(.text+0xad): undefined reference to '_imp__Tcl_GetStringResult'
e:/opt/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: noddy.o: bad reloc address 0x20 in section '.eh_frame'
e:/opt/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status

Lilypond function; add a rhythm to a note

How can you write a Lilypond function that takes in a note and outputs a note with a rhythm? say:
input: c'
output: c'8 c'16 c'
In the LilyPond documentation you can find this example:
rhythm =
#(define-music-function (parser location p) (ly:pitch?)
"Make the rhythm in Mars (the Planets) at the given pitch"
#{ \tuplet 3/2 { $p 8 $p $p } $p 4 $p $p 8 $p $p 4 #})
\new Staff {
\time 5/4
\rhythm c'
\rhythm c''
\rhythm g
}
Hopefully that can be adapted to do what you want! Replace the Mars rhythm with your own. And please note that a space is needed between the variable $p and the durations.

MySql connection threw c++ in ubuntu

I have installed necessary packages
sudo apt-get install mysql-server
sudo apt-get install libmysqlcppconn-dev
here is my code:
/* Standard C++ includes */
#include <stdlib.h>
#include <iostream>
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace std;
int main(void)
{
cout << endl;
cout << "Running 'SELECT 'Hello World!' AS _message'..." << endl;
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:11840", "root", "n");
/* Connect to the MySQL test database */
con->setSchema("test");
stmt = con->createStatement();
res = stmt->executeQuery("SELECT 'Hello World!' AS _message"); // replace with your statement
while (res->next()) {
cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
cout << res->getString("_message") << endl;
cout << "\t... MySQL says it again: ";
/* Access column fata by numeric offset, 1 is the first column */
cout << res->getString(1) << endl;
}``
delete res;
delete stmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
//cout << "(" << __FUNCTION__ << ") on line " »
// << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout << endl;
return EXIT_SUCCESS;
}
I compiled using:
sudo g++ -Wall -I/usr/include/cppconn -o testapp mysql_connect1.cpp -L/usr/lib -lmysqlcppconn
it got compiled successfully
when I run:
./testapp
Running 'SELECT 'Hello World!' AS _message'...
# ERR: SQLException in mysql_connect1.cpp# ERR:
Can't connect to MySQL server on '127.0.0.1' (111)
(MySQL error code: 2003, SQLState: HY000 )
I get the above error
I made the below changes as suggested here:
run the command vim /etc/mysql/my.cnf
comment bind-address = 127.0.0.1 using the # symbol
restart your mysql server once.
But it still didn't work
output of:
root#knils-HP:/home/knils# sudo netstat -tap | grep mysql
tcp 0 0 *:mysql *:* LISTEN 11840/mysqld
root#knils-HP:/home/knils#
Please can someone help me with this?
Are you sure your server runs on 11840 and the user account you are using is allowed to connect from localhost?
con = driver->connect("tcp://127.0.0.1:11840", "root", "n");
Your console output that more looked like a processID or internal port for me.
MySQL usually runs on 3306 except you changed that on your own.
Can you try:
con = driver->connect("tcp://127.0.0.1:3306", "root", "n");
?