Warning, /multimedia/kid3/src/qml/script/TitleCase.qml is written in an unsupported language. File is not indexed.
0001 /**
0002 * \file TitleCase.qml
0003 * Use English title case in certain tag frames.
0004 *
0005 * \b Project: Kid3
0006 * \author Urs Fleisch
0007 * \date 12 Apr 2020
0008 *
0009 * Copyright (C) 2020-2024 Urs Fleisch
0010 *
0011 * This program is free software; you can redistribute it and/or modify
0012 * it under the terms of the GNU Lesser General Public License as published by
0013 * the Free Software Foundation; version 3.
0014 *
0015 * This program is distributed in the hope that it will be useful,
0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0018 * GNU Lesser General Public License for more details.
0019 *
0020 * You should have received a copy of the GNU Lesser General Public License
0021 * along with this program. If not, see <http://www.gnu.org/licenses/>.
0022 */
0023
0024 import Kid3 1.1
0025
0026 Kid3Script {
0027 onRun: {
0028 var consideredTags = [Frame.Tag_1, Frame.Tag_2, Frame.Tag_3]
0029 var consideredFrames = ["title", "album"]
0030
0031 var small = "(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v[.]?|via|vs[.]?)";
0032 var punct = "([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]*)";
0033 // This array only contains words which cannot be handled by the all lower
0034 // and upper case handling at the end of the toTitleCase() function.
0035 var unmodifiableWords = ["Pi-hsien"];
0036
0037 /*
0038 * Title Caps
0039 *
0040 * Adapted for audio tag use case by Urs Fleisch - 12 Apr 2020
0041 * Ported to JavaScript By John Resig - http://ejohn.org/ - 21 May 2008
0042 * Original by John Gruber - https://daringfireball.net/ - 10 May 2008
0043 * License: https://www.opensource.org/licenses/mit-license.php
0044 */
0045 function toTitleCase(title) {
0046 var parts = [], split = /[:.;?!] |(?: |^)["\xab]/g, index = 0;
0047
0048 while (true) {
0049 var m = split.exec(title);
0050 var part = title.substring(index, m ? m.index : title.length);
0051
0052 parts.push(unmodifiableWords.indexOf(part) !== -1 ? part : part
0053 .replace(/\b([A-Za-z][a-z.'`()\u2019]*)\b/g,
0054 function(all) {
0055 return /[A-Za-z]\.[A-Za-z]/.test(all) ? all : capitalize(all);
0056 })
0057 .replace(new RegExp("\\b" + small + "\\b", "ig"),
0058 function(word) {
0059 return word.toLowerCase();
0060 })
0061 .replace(new RegExp("^" + punct + small + "\\b", "ig"),
0062 function(all, punct, word) {
0063 return punct + capitalize(word);
0064 })
0065 .replace(new RegExp("([-\\u2013\\u2014]\\s+)" + punct + small + "\\b", "ig"),
0066 function(all, dash, punct, word) {
0067 return dash + punct + capitalize(word);
0068 })
0069 .replace(new RegExp("\\b" + small + punct + "$", "ig"), capitalize));
0070
0071 index = split.lastIndex;
0072
0073 if (m) {
0074 parts.push(m[0]);
0075 } else {
0076 break;
0077 }
0078 }
0079
0080 return parts.join("")
0081 .replace(/ V(s?)\. /ig, " v$1. ")
0082 .replace(/(['`\u2019])S\b/ig, "$1s")
0083 .replace(/\b(de|von|van|feat|n|http:\/\/)\b/ig, function(all) {
0084 return all.toLowerCase();
0085 })
0086 .replace(/\b(AT&T|Q&A|OYF’N)\b/ig, function(all) {
0087 return all.toUpperCase();
0088 });
0089 };
0090
0091 function capitalize(word) {
0092 return word.substr(0, 1).toUpperCase() + word.substr(1);
0093 }
0094
0095 function doWork() {
0096 for (var ti = 0; ti < consideredTags.length; ++ti) {
0097 var tagNr = consideredTags[ti]
0098 var tagMask = script.toTagVersion(1 << tagNr);
0099 if (app.selectionInfo.tag(tagNr).tagFormat) {
0100 for (var fi = 0; fi < consideredFrames.length; ++fi) {
0101 var name = consideredFrames[fi];
0102 var oldTxt = app.getFrame(tagMask, name)
0103 var newTxt = toTitleCase(oldTxt)
0104 if (newTxt !== oldTxt) {
0105 app.setFrame(tagMask, name, newTxt)
0106 }
0107 }
0108 }
0109 }
0110 if (!nextFile()) {
0111 if (isStandalone()) {
0112 // Save the changes if the script is started stand-alone, not from Kid3.
0113 app.saveDirectory()
0114 }
0115 Qt.quit()
0116 } else {
0117 setTimeout(doWork, 1)
0118 }
0119 }
0120
0121 firstFile()
0122 doWork()
0123 }
0124 }