@@ -183,7 +183,7 @@ static void copyOverlapData(VoiceOverlapDetector& vod, VoiceList& vcLst)
183183// ---------------------------------------------------------
184184
185185MusicXMLParserPass1::MusicXMLParserPass1 (Score* score, MxmlLogger* logger)
186- : _divs(0 ), _score(score), _logger(logger), _hasBeamingInfo(false )
186+ : _divs(0 ), _score(score), _logger(logger), _hasBeamingInfo(false ), _hasInferredHeaderText( false )
187187 {
188188 // nothing
189189 }
@@ -675,27 +675,52 @@ bool isLikelySubtitleText(const QString& text, const bool caseInsensitive = true
675675 QRegularExpression::PatternOption caseOption = caseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption;
676676 return (text.trimmed ().contains (QRegularExpression (" ^[Ff]rom\\ s+(?!$)" , caseOption))
677677 || text.trimmed ().contains (QRegularExpression (" ^Theme from\\ s+(?!$)" , caseOption))
678- || text.trimmed ().contains (QRegularExpression (" (Op\\ .?\\ s?\\ d+)\\ s?(No\\ .?\\ s?\\ d+)?" , caseOption))
679- || text.trimmed ().contains (QRegularExpression (" ^\\ (.*[Ff]rom\\ s.*\\ )$" , caseOption)));
678+ || text.trimmed ().contains (QRegularExpression (" (((Op\\ .?\\ s?\\ d+)|(No\\ .?\\ s?\\ d+))\\ s?)+" , caseOption))
679+ || text.trimmed ().contains (QRegularExpression (" \\ (.*[Ff]rom\\ s.*\\ )" , caseOption)));
680+ }
681+
682+ // ---------------------------------------------------------
683+ // isLikelyCreditText
684+ // ---------------------------------------------------------
685+
686+ bool isLikelyCreditText (const QString& text, const bool caseInsensitive = true )
687+ {
688+ QRegularExpression::PatternOption caseOption = caseInsensitive ? QRegularExpression::CaseInsensitiveOption : QRegularExpression::NoPatternOption;
689+ return (text.trimmed ().contains (QRegularExpression (" ^((Words|Music|Lyrics|Composed),?(\\ sand|\\ s&|\\ s&)?\\ s)*[Bb]y\\ s+(?!$)" , caseOption))
690+ || text.trimmed ().contains (QRegularExpression (" ^(Traditional|Trad\\ .)" , caseOption)));
680691 }
681692
682693// ---------------------------------------------------------
683694// inferSubTitleFromTitle
684695// ---------------------------------------------------------
685696
686- // Extracts a likely subtitle from the title string
687- // Returns the inferred subtitle
697+ // Extracts likely subtitle and credits from the title string
688698
689- static QString inferSubTitleFromTitle ( const QString& title)
699+ static void inferFromTitle ( QString& title, QString& inferredSubtitle, QString& inferredCredits )
690700 {
691- QString inferredSubTitle = " " ;
692- for (auto line : title.split (QRegularExpression (" \\ n" ))) {
701+ QStringList subtitleLines;
702+ QStringList creditLines;
703+ QStringList titleLines = title.split (QRegularExpression (" \\ n" ));
704+ for (int i = titleLines.length () - 1 ; i > 0 ; --i) {
705+ QString line = titleLines[i];
706+ if (isLikelyCreditText (line, true )) {
707+ for (int j = titleLines.length () - 1 ; j >= i; --j) {
708+ creditLines.push_front (titleLines[j]);
709+ titleLines.removeAt (j);
710+ }
711+ continue ;
712+ }
693713 if (isLikelySubtitleText (line, true )) {
694- inferredSubTitle = line;
695- break ;
714+ for (int j = titleLines.length () - 1 ; j >= i; --j) {
715+ subtitleLines.push_front (titleLines[j]);
716+ titleLines.removeAt (j);
717+ }
718+ continue ;
696719 }
697720 }
698- return inferredSubTitle;
721+ title = titleLines.join (" \n " );
722+ inferredSubtitle = subtitleLines.join (" \n " );
723+ inferredCredits = creditLines.join (" \n " );
699724 }
700725// ---------------------------------------------------------
701726// addCreditWords
@@ -759,11 +784,12 @@ static VBox* addCreditWords(Score* const score, const CreditWordsList& crWords,
759784// createMeasuresAndVboxes
760785// ---------------------------------------------------------
761786
762- static void createDefaultHeader (Score* const score)
787+ void MusicXMLParserPass1:: createDefaultHeader (Score* const score)
763788 {
764789 QString strTitle;
765790 QString strSubTitle;
766791 QString inferredStrSubTitle;
792+ QString inferredStrComposer;
767793 QString strComposer;
768794 QString strPoet;
769795 QString strTranslator;
@@ -772,21 +798,25 @@ static void createDefaultHeader(Score* const score)
772798 strTitle = score->metaTag (" movementTitle" );
773799 if (strTitle.isEmpty ())
774800 strTitle = score->metaTag (" workTitle" );
775- inferredStrSubTitle = inferSubTitleFromTitle (strTitle);
801+ inferFromTitle (strTitle, inferredStrSubTitle, inferredStrComposer );
776802 }
777803 if (!(score->metaTag (" movementNumber" ).isEmpty () && score->metaTag (" workNumber" ).isEmpty ())) {
778804 strSubTitle = score->metaTag (" movementNumber" );
779805 if (strSubTitle.isEmpty ())
780806 strSubTitle = score->metaTag (" workNumber" );
781807 }
782- else if (!inferredStrSubTitle.isEmpty ()) {
808+ if (!inferredStrSubTitle.isEmpty ()) {
783809 strSubTitle = inferredStrSubTitle;
784- strTitle. replace (inferredStrSubTitle, " " ) ;
810+ _hasInferredHeaderText = true ;
785811 }
786812 QString metaComposer = score->metaTag (" composer" );
787813 QString metaPoet = score->metaTag (" poet" );
788814 QString metaTranslator = score->metaTag (" translator" );
789815 if (!metaComposer.isEmpty ()) strComposer = metaComposer;
816+ if (!inferredStrComposer.isEmpty ()) {
817+ strComposer = inferredStrComposer;
818+ _hasInferredHeaderText = true ;
819+ }
790820 if (metaPoet.isEmpty ()) metaPoet = score->metaTag (" lyricist" );
791821 if (!metaPoet.isEmpty ()) strPoet = metaPoet;
792822 if (!metaTranslator.isEmpty ()) strTranslator = metaTranslator;
@@ -807,7 +837,7 @@ static void createDefaultHeader(Score* const score)
807837 Create required measures with correct number, start tick and length for Score \a score.
808838 */
809839
810- static void createMeasuresAndVboxes (Score* const score,
840+ void MusicXMLParserPass1:: createMeasuresAndVboxes (Score* const score,
811841 const QVector<Fraction>& ml, const QVector<Fraction>& ms,
812842 const std::set<int >& systemStartMeasureNrs,
813843 const std::set<int >& pageStartMeasureNrs,
0 commit comments