1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-07-01 23:53:48 +02:00

Change tokenization of header comment lines & translate strings ...

... allowing (_ "...") for single strings, and allowing a sequence of such
inside outer ( ) for choice controls, but still accepting the old syntax too
This commit is contained in:
Paul Licameli 2018-02-27 18:32:59 -05:00
parent 0879949904
commit ba8e6bd465
2 changed files with 126 additions and 52 deletions

View File

@ -329,7 +329,7 @@ bool NyquistEffect::DefineParams( ShuttleParams & S )
}
else if (ctrl.type == NYQ_CTRL_CHOICE)
{
wxArrayString choices = ParseChoice(ctrl);
const wxArrayString &choices = ctrl.choices;
int x=d;
//parms.WriteEnum(ctrl.var, (int) d, choices);
S.DefineEnum( x, static_cast<const wxChar*>( ctrl.var.c_str() ), 0, choices );
@ -378,7 +378,7 @@ bool NyquistEffect::GetAutomationParameters(CommandParameters & parms)
}
else if (ctrl.type == NYQ_CTRL_CHOICE)
{
wxArrayString choices = ParseChoice(ctrl);
const wxArrayString &choices = ctrl.choices;
parms.WriteEnum(ctrl.var, (int) d, choices);
}
else if (ctrl.type == NYQ_CTRL_STRING)
@ -428,7 +428,7 @@ bool NyquistEffect::SetAutomationParameters(CommandParameters & parms)
else if (ctrl.type == NYQ_CTRL_CHOICE)
{
int val;
wxArrayString choices = ParseChoice(ctrl);
const wxArrayString &choices = ctrl.choices;
good = parms.ReadEnum(ctrl.var, &val, choices) &&
val != wxNOT_FOUND;
}
@ -468,7 +468,7 @@ bool NyquistEffect::SetAutomationParameters(CommandParameters & parms)
else if (ctrl.type == NYQ_CTRL_CHOICE)
{
int val {0};
wxArrayString choices = ParseChoice(ctrl);
const wxArrayString &choices = ctrl.choices;
parms.ReadEnum(ctrl.var, &val, choices);
ctrl.val = (double) val;
}
@ -1469,13 +1469,25 @@ wxString NyquistEffect::EscapeString(const wxString & inStr)
return str;
}
wxArrayString NyquistEffect::ParseChoice(const NyqControl & ctrl)
wxArrayString NyquistEffect::ParseChoice(const wxString & text)
{
wxArrayString choices = wxStringTokenize(ctrl.label, wxT(","));
for (size_t i = 0, cnt = choices.GetCount();i < cnt; i++)
{
choices[i] = choices[i].Trim(true).Trim(false);
wxArrayString choices;
if (text[0] == wxT('(')) {
// New style: expecting a Lisp-like list of strings
Tokenize(text, choices, 1, 1);
for (auto &choice : choices)
choice = UnQuote(choice);
}
else {
// Old style: expecting a comma-separated list of
// un-internationalized names, ignoring leading and trailing spaces
// on each; and the whole may be quoted
choices = wxStringTokenize(
text[0] == wxT('"') ? text.Mid(1, text.Length() - 2) : text,
wxT(",")
);
for (auto &choice : choices)
choice = choice.Trim(true).Trim(false);
}
return choices;
@ -1508,16 +1520,28 @@ void NyquistEffect::Stop()
mStop = true;
}
wxString NyquistEffect::UnQuote(const wxString &s)
wxString NyquistEffect::UnQuote(
const wxString &s, bool allowParens, bool translate)
{
wxString out;
int len = s.Length();
if (len >= 2 && s[0] == wxT('\"') && s[len - 1] == wxT('\"')) {
return s.Mid(1, len - 2);
auto unquoted = s.Mid(1, len - 2);
return translate ? GetCustomTranslation( unquoted ) : unquoted;
}
return s;
else if (allowParens &&
len >= 2 && s[0] == wxT('(') && s[len - 1] == wxT(')')) {
wxArrayString tokens;
Tokenize(s, tokens, 1, 1);
if (tokens.size() > 1)
// Assume the first token was _ -- we don't check that
// And the second is the string, which is internationalized
return UnQuote( tokens[1], false, true );
else
return {};
}
else
// If string was not quoted, assume no translation exists
return s;
}
double NyquistEffect::GetCtrlValue(const wxString &s)
@ -1540,51 +1564,83 @@ double NyquistEffect::GetCtrlValue(const wxString &s)
return Internat::CompatibleToDouble(s);
}
void NyquistEffect::Parse(const wxString &line)
void NyquistEffect::Tokenize(
const wxString &line, wxArrayString &tokens,
size_t trimStart, size_t trimEnd)
{
wxArrayString tokens;
int i;
int len = line.Length();
bool sl = false;
bool q = false;
wxString tok = wxT("");
int paren = 0;
for (i = 1; i < len; i++) {
wxChar c = line[i];
auto endToken = [&]{
if (!tok.empty()) {
tokens.push_back(tok);
tok = wxT("");
}
};
if (c == wxT('\\')) {
for (auto c :
make_iterator_range(line.begin() + trimStart, line.end() - trimEnd)) {
if (q && c == wxT('\\')) {
// begin escaped character, only within quotes
sl = true;
continue;
}
else if (c == wxT('"')) {
q = !q;
else if (sl && c == wxT('n'))
c = wxT('\n');
if (!sl && !paren && c == wxT('"')) {
if (!q)
// finish previous token; begin token, including the delimiter
endToken(), q = true, tok += c;
else
// end token, including the delimiter
tok += c, q = false, endToken();
}
else {
if ((!q && !sl && c == wxT(' ')) || c == wxT('\t')) {
tokens.Add(tok);
tok = wxT("");
}
else if (sl && c == wxT('n')) {
tok += wxT('\n');
}
else {
else if (!q && !paren && (c == wxT(' ') || c == wxT('\t')))
// Separate tokens; don't accumulate this character
endToken();
else if (!q && c == wxT('(')) {
if (++paren == 1)
// finish previous token; begin list, including the delimiter
endToken(), tok += c;
else
// defer tokenizing of nested list to a later pass over the token
tok += c;
}
sl = false;
}
else if (!q && c == wxT(')')) {
if (--paren == 0)
// finish list, including the delimiter
tok += c, endToken();
else if (paren < 0)
// forgive unbalanced right paren
paren = 0, endToken();
else
// nested list; deferred tokenizing
tok += c;
}
else
tok += c;
sl = false;
}
if (tok != wxT("")) {
tokens.Add(tok);
}
// Finish -- this just forgives unbalanced open quotes or left parens
endToken();
}
len = tokens.GetCount();
void NyquistEffect::Parse(const wxString &line)
{
wxArrayString tokens;
Tokenize(line, tokens, 1, 0);
int len = tokens.size();
if (len < 1) {
return;
}
// Consistency decission is for "plug-in" as the correct spelling
// Consistency decision is for "plug-in" as the correct spelling
// "plugin" (deprecated) is allowed as an undocumented convenience.
if (len == 2 && tokens[0] == wxT("nyquist") &&
(tokens[1] == wxT("plug-in") || tokens[1] == wxT("plugin"))) {
@ -1665,9 +1721,7 @@ void NyquistEffect::Parse(const wxString &line)
if (len >= 2 && tokens[0] == wxT("name")) {
mName = UnQuote(tokens[1]);
if (mName.EndsWith(wxT("...")))
{
mName = mName.RemoveLast(3);
}
return;
}
@ -1739,14 +1793,16 @@ void NyquistEffect::Parse(const wxString &line)
// TODO: Document.
// Page name in Audacity development manual
if (len >= 2 && tokens[0] == wxT("manpage")) {
mManPage = UnQuote(tokens[1]);
// do not translate
mManPage = UnQuote(tokens[1], false, false);
return;
}
// TODO: Document.
// Local Help file
if (len >= 2 && tokens[0] == wxT("helpfile")) {
mHelpFile = UnQuote(tokens[1]);
// do not translate
mHelpFile = UnQuote(tokens[1], false, false);
return;
}
@ -1763,18 +1819,31 @@ void NyquistEffect::Parse(const wxString &line)
NyqControl ctrl;
ctrl.var = tokens[1];
ctrl.name = tokens[2];
ctrl.name = UnQuote( tokens[2] );
// 3 is type, below
ctrl.label = tokens[4];
// valStr may or may not be a quoted string
ctrl.valStr = tokens[5];
ctrl.val = GetCtrlValue(ctrl.valStr);
if (ctrl.valStr[0] == wxT('(') || ctrl.valStr[0] == wxT('"'))
ctrl.valStr = UnQuote( ctrl.valStr );
// 6 is minimum, below
// 7 is maximum, below
if (tokens[3] == wxT("string")) {
ctrl.type = NYQ_CTRL_STRING;
ctrl.label = UnQuote( ctrl.label );
}
else if (tokens[3] == wxT("choice")) {
ctrl.type = NYQ_CTRL_CHOICE;
ctrl.choices = ParseChoice(ctrl.label);
ctrl.label = wxT("");
}
else {
ctrl.label = UnQuote( ctrl.label );
if (len < 8) {
return;
}
@ -2124,7 +2193,7 @@ bool NyquistEffect::TransferDataToEffectWindow()
if (ctrl.type == NYQ_CTRL_CHOICE)
{
wxArrayString choices = ParseChoice(ctrl);
const wxArrayString &choices = ctrl.choices;
int val = (int)ctrl.val;
if (val < 0 || val >= (int)choices.GetCount())
@ -2288,7 +2357,7 @@ void NyquistEffect::BuildEffectWindow(ShuttleGui & S)
{
S.AddSpace(10, 10);
wxArrayString choices = wxStringTokenize(ctrl.label, wxT(","));
const wxArrayString &choices = ctrl.choices;
S.Id(ID_Choice + i).AddChoice( {}, wxT(""), &choices);
}
else

View File

@ -56,6 +56,7 @@ public:
wxString var;
wxString name;
wxString label;
wxArrayString choices;
wxString valStr;
wxString lowStr;
wxString highStr;
@ -141,7 +142,7 @@ private:
static wxString NyquistToWxString(const char *nyqString);
wxString EscapeString(const wxString & inStr);
wxArrayString ParseChoice(const NyqControl & ctrl);
static wxArrayString ParseChoice(const wxString & text);
static int StaticGetCallback(float *buffer, int channel,
long start, long len, long totlen,
@ -162,9 +163,13 @@ private:
void ParseFile();
bool ParseCommand(const wxString & cmd);
bool ParseProgram(wxInputStream & stream);
static void Tokenize(
const wxString &line, wxArrayString &tokens,
size_t trimStart, size_t trimEnd);
void Parse(const wxString &line);
wxString UnQuote(const wxString &s);
static wxString UnQuote(const wxString &s,
bool allowParens = true, bool translate = true);
double GetCtrlValue(const wxString &s);
void OnLoad(wxCommandEvent & evt);