fix:mdx embeded @font-face support

This commit is contained in:
Xiao YiFang 2022-10-03 20:28:16 +08:00
parent e8764d322c
commit 98769b6dd2
3 changed files with 73 additions and 35 deletions

View file

@ -56,3 +56,6 @@ QRegularExpression Mdx::srcRe2( "([\\s\"'](?:src|srcset)\\s*=)\\s*(?![\\s\"']|\\
QRegularExpression Mdx::links( "url\\(\\s*(['\"]?)([^'\"]*)(['\"]?)\\s*\\)", QRegularExpression Mdx::links( "url\\(\\s*(['\"]?)([^'\"]*)(['\"]?)\\s*\\)",
QRegularExpression::CaseInsensitiveOption ); QRegularExpression::CaseInsensitiveOption );
QRegularExpression Mdx::fontFace( "(?:url\\s*\\(\\s*\\\"(.*?)\\\"\\s*)\\)",
QRegularExpression::CaseInsensitiveOption|QRegularExpression::DotMatchesEverythingOption );

View file

@ -37,6 +37,7 @@ public:
static QRegularExpression srcRe2; static QRegularExpression srcRe2;
static QRegularExpression links; static QRegularExpression links;
static QRegularExpression fontFace;
}; };
} // namespace RX } // namespace RX

94
mdx.cc
View file

@ -301,6 +301,10 @@ private:
/// Process resource links (images, audios, etc) /// Process resource links (images, audios, etc)
QString & filterResource( QString const & articleId, QString & article ); QString & filterResource( QString const & articleId, QString & article );
void replaceLinks( QString & id, const QString & articleId, QString & article );
//@font-face
void replaceFontLinks( QString & id, QString & article );
void removeDirectory( QString const & directory ); void removeDirectory( QString const & directory );
friend class MdxHeadwordsRequest; friend class MdxHeadwordsRequest;
@ -954,12 +958,19 @@ void MdxDictionary::loadArticle( uint32_t offset, string & articleText, bool noF
QString & MdxDictionary::filterResource( QString const & articleId, QString & article ) QString & MdxDictionary::filterResource( QString const & articleId, QString & article )
{ {
QString id = QString::fromStdString( getId() ); QString id = QString::fromStdString( getId() );
replaceLinks( id, articleId, article );
replaceFontLinks( id, article);
return article;
}
void MdxDictionary::replaceLinks( QString & id, const QString & articleId, QString & article )
{
QString uniquePrefix = QString::fromLatin1( "g" ) + id + "_" + articleId + "_"; QString uniquePrefix = QString::fromLatin1( "g" ) + id + "_" + articleId + "_";
QString articleNewText; QString articleNewText;
int linkPos = 0; int linkPos = 0;
QRegularExpressionMatchIterator it = RX::Mdx::allLinksRe.globalMatch( article ); QRegularExpressionMatchIterator it = RX::Mdx::allLinksRe.globalMatch( article );
QMap<QString,QString> idMap; QMap< QString, QString > idMap;
while( it.hasNext() ) while( it.hasNext() )
{ {
QRegularExpressionMatch allLinksMatch = it.next(); QRegularExpressionMatch allLinksMatch = it.next();
@ -996,19 +1007,18 @@ QString & MdxDictionary::filterResource( QString const & articleId, QString & ar
if( match.hasMatch() ) if( match.hasMatch() )
{ {
// sounds and audio link script // sounds and audio link script
QString newTxt = match.captured( 1 ) + match.captured( 2 ) QString newTxt =
+ "gdau://" + id + "/" match.captured( 1 ) + match.captured( 2 ) + "gdau://" + id + "/" + match.captured( 3 ) + match.captured( 2 );
+ match.captured( 3 ) + match.captured( 2 ); newLink =
newLink = QString::fromUtf8( addAudioLink( "\"gdau://" + getId() + "/" + match.captured( 3 ).toUtf8().data() + "\"", getId() ).c_str() ) QString::fromUtf8(
addAudioLink( "\"gdau://" + getId() + "/" + match.captured( 3 ).toUtf8().data() + "\"", getId() ).c_str() )
+ newLink.replace( match.capturedStart(), match.capturedLength(), newTxt ); + newLink.replace( match.capturedStart(), match.capturedLength(), newTxt );
} }
match = RX::Mdx::wordCrossLink.match( newLink ); match = RX::Mdx::wordCrossLink.match( newLink );
if( match.hasMatch() ) if( match.hasMatch() )
{ {
QString newTxt = match.captured( 1 ) + match.captured( 2 ) QString newTxt = match.captured( 1 ) + match.captured( 2 ) + "gdlookup://localhost/" + match.captured( 3 );
+ "gdlookup://localhost/"
+ match.captured( 3 );
if( match.lastCapturedIndex() >= 4 && !match.captured( 4 ).isEmpty() ) if( match.lastCapturedIndex() >= 4 && !match.captured( 4 ).isEmpty() )
newTxt += QString( "?gdanchor=" ) + uniquePrefix + match.captured( 4 ).mid( 1 ); newTxt += QString( "?gdanchor=" ) + uniquePrefix + match.captured( 4 ).mid( 1 );
@ -1017,25 +1027,20 @@ QString & MdxDictionary::filterResource( QString const & articleId, QString & ar
newLink.replace( match.capturedStart(), match.capturedLength(), newTxt ); newLink.replace( match.capturedStart(), match.capturedLength(), newTxt );
} }
} }
else else if( linkType.compare( "link" ) == 0 )
if( linkType.compare( "link" ) == 0 )
{ {
// stylesheets // stylesheets
QRegularExpressionMatch match = RX::Mdx::stylesRe.match( linkTxt ); QRegularExpressionMatch match = RX::Mdx::stylesRe.match( linkTxt );
if( match.hasMatch() ) if( match.hasMatch() )
{ {
QString newText = match.captured( 1 ) + match.captured( 2 ) QString newText =
+ "bres://" + id + "/" match.captured( 1 ) + match.captured( 2 ) + "bres://" + id + "/" + match.captured( 3 ) + match.captured( 2 );
+ match.captured( 3 ) + match.captured( 2 );
newLink = linkTxt.replace( match.capturedStart(), match.capturedLength(), newText ); newLink = linkTxt.replace( match.capturedStart(), match.capturedLength(), newText );
} }
else else
newLink = linkTxt.replace( RX::Mdx::stylesRe2, newLink = linkTxt.replace( RX::Mdx::stylesRe2, "\\1\"bres://" + id + "/\\2\"" );
"\\1\"bres://" + id + "/\\2\"" );
} }
else else if( linkType.compare( "script" ) == 0 || linkType.compare( "img" ) == 0 || linkType.compare( "source" ) == 0 )
if( linkType.compare( "script" ) == 0 || linkType.compare( "img" ) == 0
|| linkType.compare( "source" ) == 0 )
{ {
// javascripts and images // javascripts and images
QRegularExpressionMatch match = RX::Mdx::inlineScriptRe.match( linkTxt ); QRegularExpressionMatch match = RX::Mdx::inlineScriptRe.match( linkTxt );
@ -1063,20 +1068,17 @@ QString & MdxDictionary::filterResource( QString const & articleId, QString & ar
QString filename = match.captured( 3 ); QString filename = match.captured( 3 );
QString newName = getCachedFileName( filename ); QString newName = getCachedFileName( filename );
newName.replace( '\\', '/' ); newName.replace( '\\', '/' );
newText = match.captured( 1 ) + match.captured( 2 ) newText = match.captured( 1 ) + match.captured( 2 ) + "file:///" + newName + match.captured( 2 );
+ "file:///" + newName + match.captured( 2 );
} }
else else
{ {
newText = match.captured( 1 ) + match.captured( 2 ) newText = match.captured( 1 ) + match.captured( 2 ) + "bres://" + id + "/" + match.captured( 3 )
+ "bres://" + id + "/" + match.captured( 2 );
+ match.captured( 3 ) + match.captured( 2 );
} }
newLink = linkTxt.replace( match.capturedStart(), match.capturedLength(), newText ); newLink = linkTxt.replace( match.capturedStart(), match.capturedLength(), newText );
} }
else else
newLink = linkTxt.replace( RX::Mdx::srcRe2, newLink = linkTxt.replace( RX::Mdx::srcRe2, "\\1\"bres://" + id + "/\\2\"" );
"\\1\"bres://" + id + "/\\2\"" );
} }
} }
if( !newLink.isEmpty() ) if( !newLink.isEmpty() )
@ -1092,14 +1094,46 @@ QString & MdxDictionary::filterResource( QString const & articleId, QString & ar
article = articleNewText; article = articleNewText;
} }
//some built-in javascript may reference this id. replace "idxxx" with "unique_idxxx" // some built-in javascript may reference this id. replace "idxxx" with "unique_idxxx"
foreach ( const auto& key, idMap.keys() ) foreach( const auto & key, idMap.keys() )
{ {
const auto& value = idMap[ key ]; const auto & value = idMap[ key ];
article.replace("\""+key+"\"","\""+value+"\""); article.replace( "\"" + key + "\"", "\"" + value + "\"" );
} }
}
return article; void MdxDictionary::replaceFontLinks( QString & id, QString & article )
{
//article = article.replace( RX::Mdx::fontFace, "src:url(\"bres://" + id + "/" + "\\1\")" );
QString articleNewText;
int linkPos = 0;
QRegularExpressionMatchIterator it = RX::Mdx::fontFace.globalMatch( article );
while( it.hasNext() )
{
QRegularExpressionMatch allLinksMatch = it.next();
if( allLinksMatch.capturedEnd() < linkPos )
continue;
articleNewText += article.mid( linkPos, allLinksMatch.capturedStart() - linkPos );
linkPos = allLinksMatch.capturedEnd();
QString linkTxt = allLinksMatch.captured();
QString linkType = allLinksMatch.captured( 1 );
QString newLink = linkTxt;
//skip remote url
if( !linkType.contains( ":" ) )
{
newLink = QString( "url(\"bres://%1/%2\")" ).arg( id, linkType );
}
articleNewText += newLink;
}
if( linkPos )
{
articleNewText += article.mid( linkPos );
article = articleNewText;
}
} }