[kid3] /: Script to apply English title capitalization to tags
Urs Fleisch
null at kde.org
Tue Apr 14 08:36:41 BST 2020
Git commit 5c8f85ca14658d7531ac4d05aae0a5352b1303e0 by Urs Fleisch.
Committed on 14/04/2020 at 06:42.
Pushed by ufleisch into branch 'master'.
Script to apply English title capitalization to tags
BUG: 419890
M +5 -0 doc/en/index.docbook
M +2 -1 src/core/config/configstore.cpp
M +6 -0 src/core/config/useractionsconfig.cpp
M +1 -0 src/qml/CMakeLists.txt
A +125 -0 src/qml/script/TitleCase.qml [License: LGPL]
https://invent.kde.org/kde/kid3/commit/5c8f85ca14658d7531ac4d05aae0a5352b1303e0
diff --git a/doc/en/index.docbook b/doc/en/index.docbook
index cf3b0727..87da30e7 100644
--- a/doc/en/index.docbook
+++ b/doc/en/index.docbook
@@ -4455,6 +4455,11 @@ Helps to find the encoding of ID3v1 tags by showing the tags of the
current file in all available character encodings.
</para></listitem>
<listitem><para>
+<guilabel>English Title Case</guilabel>
+(<filename>TitleCase.qml</filename>):
+Formats text in the tags to English title case.
+</para></listitem>
+<listitem><para>
<guilabel>Export CSV</guilabel>
(<filename>ExportCsv.qml</filename>):
Export recursively all tags of all files to a CSV file.
diff --git a/src/core/config/configstore.cpp b/src/core/config/configstore.cpp
index 6fc7a374..84e7730b 100644
--- a/src/core/config/configstore.cpp
+++ b/src/core/config/configstore.cpp
@@ -37,8 +37,9 @@ namespace {
* 2: 3.2
* 3: 3.3
* 4: 3.7
+ * 5: 3.8.3
*/
-const int CONFIG_VERSION = 4;
+const int CONFIG_VERSION = 5;
}
diff --git a/src/core/config/useractionsconfig.cpp b/src/core/config/useractionsconfig.cpp
index 775da5d0..646d793e 100644
--- a/src/core/config/useractionsconfig.cpp
+++ b/src/core/config/useractionsconfig.cpp
@@ -245,6 +245,12 @@ void UserActionsConfig::setDefaultUserActions(bool upgradeOnly)
QLatin1String("@qml %{qmlpath}/script/ExportPlaylist.qml"),
false, true));
}
+ if (!upgradeOnly || ConfigStore::getConfigVersion() < 5) {
+ m_contextMenuCommands.push_back(
+ UserActionsConfig::MenuCommand(
+ QLatin1String("English Title Case"),
+ QLatin1String("@qml %{qmlpath}/script/TitleCase.qml")));
+ }
#endif
}
diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt
index 68fe922d..04114754 100644
--- a/src/qml/CMakeLists.txt
+++ b/src/qml/CMakeLists.txt
@@ -28,6 +28,7 @@ if(NOT HAVE_QMLDIR_IN_QRC)
script/EmbedAlbumArt.qml
script/EmbedLyrics.qml
script/ExportPlaylist.qml
+ script/TitleCase.qml
)
if(BUILD_QML_APP)
# Only used to add the QML sources to the project.
diff --git a/src/qml/script/TitleCase.qml b/src/qml/script/TitleCase.qml
new file mode 100644
index 00000000..da047dc0
--- /dev/null
+++ b/src/qml/script/TitleCase.qml
@@ -0,0 +1,125 @@
+/**
+ * \file TitleCase.qml
+ * Use English title case in certain tag frames.
+ *
+ * \b Project: Kid3
+ * \author Urs Fleisch
+ * \date 12 Apr 2020
+ *
+ * Copyright (C) 2020 Urs Fleisch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import Kid3 1.1
+
+Kid3Script {
+ onRun: {
+ var consideredTags = [Frame.Tag_1, Frame.Tag_2, Frame.Tag_3]
+ var consideredFrames = ["title", "album"]
+
+ var small = "(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v[.]?|via|vs[.]?)";
+ var punct = "([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]*)";
+ // This array only contains words which cannot be handled by the all lower
+ // and upper case handling at the end of the toTitleCase() function.
+ var unmodifiableWords = ["Pi-hsien"];
+
+ /*
+ * Title Caps
+ *
+ * Adapted for audio tag use case by Urs Fleisch - 12 Apr 2020
+ * Ported to JavaScript By John Resig - http://ejohn.org/ - 21 May 2008
+ * Original by John Gruber - http://daringfireball.net/ - 10 May 2008
+ * License: http://www.opensource.org/licenses/mit-license.php
+ */
+ function toTitleCase(title) {
+ var parts = [], split = /[:.;?!] |(?: |^)["\xab]/g, index = 0;
+
+ while (true) {
+ var m = split.exec(title);
+ var part = title.substring(index, m ? m.index : title.length);
+
+ parts.push(unmodifiableWords.indexOf(part) !== -1 ? part : part
+ .replace(/\b([A-Za-z][a-z.'`()\u2019]*)\b/g,
+ function(all) {
+ return /[A-Za-z]\.[A-Za-z]/.test(all) ? all : capitalize(all);
+ })
+ .replace(new RegExp("\\b" + small + "\\b", "ig"),
+ function(word) {
+ return word.toLowerCase();
+ })
+ .replace(new RegExp("^" + punct + small + "\\b", "ig"),
+ function(all, punct, word) {
+ return punct + capitalize(word);
+ })
+ .replace(new RegExp("([-\\u2013\\u2014]\\s+)" + punct + small + "\\b", "ig"),
+ function(all, dash, punct, word) {
+ return dash + punct + capitalize(word);
+ })
+ .replace(new RegExp("\\b" + small + punct + "$", "ig"), capitalize));
+
+ index = split.lastIndex;
+
+ if (m) {
+ parts.push(m[0]);
+ } else {
+ break;
+ }
+ }
+
+ return parts.join("")
+ .replace(/ V(s?)\. /ig, " v$1. ")
+ .replace(/(['`\u2019])S\b/ig, "$1s")
+ .replace(/\b(de|von|van|feat|n|http:\/\/)\b/ig, function(all) {
+ return all.toLowerCase();
+ })
+ .replace(/\b(AT&T|Q&A|OYF’N)\b/ig, function(all) {
+ return all.toUpperCase();
+ });
+ ;
+ };
+
+ function capitalize(word) {
+ return word.substr(0, 1).toUpperCase() + word.substr(1);
+ }
+
+ function doWork() {
+ for (var ti = 0; ti < consideredTags.length; ++ti) {
+ var tagNr = consideredTags[ti]
+ var tagMask = script.toTagVersion(1 << tagNr);
+ if (app.selectionInfo.tag(tagNr).tagFormat) {
+ for (var fi = 0; fi < consideredFrames.length; ++fi) {
+ var name = consideredFrames[fi];
+ var oldTxt = app.getFrame(tagMask, name)
+ var newTxt = toTitleCase(oldTxt)
+ if (newTxt !== oldTxt) {
+ app.setFrame(tagMask, name, newTxt)
+ }
+ }
+ }
+ }
+ if (!nextFile()) {
+ if (isStandalone()) {
+ // Save the changes if the script is started stand-alone, not from Kid3.
+ app.saveDirectory()
+ }
+ Qt.quit()
+ } else {
+ setTimeout(doWork, 1)
+ }
+ }
+
+ firstFile()
+ doWork()
+ }
+}
More information about the kde-doc-english
mailing list