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 }