mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-09 09:33:57 -07:00
[DeckList] Refactor load from plaintext to take normalizer as param
This commit is contained in:
parent
b36ab66583
commit
7782b35f6e
5 changed files with 73 additions and 37 deletions
|
|
@ -19,6 +19,7 @@ set(cockatrice_SOURCES
|
||||||
src/client/settings/card_counter_settings.cpp
|
src/client/settings/card_counter_settings.cpp
|
||||||
src/client/settings/shortcut_treeview.cpp
|
src/client/settings/shortcut_treeview.cpp
|
||||||
src/client/settings/shortcuts_settings.cpp
|
src/client/settings/shortcuts_settings.cpp
|
||||||
|
src/interface/deck_loader/card_name_normalizer.cpp
|
||||||
src/interface/deck_loader/card_node_function.cpp
|
src/interface/deck_loader/card_node_function.cpp
|
||||||
src/interface/deck_loader/deck_file_format.cpp
|
src/interface/deck_loader/deck_file_format.cpp
|
||||||
src/interface/deck_loader/deck_loader.cpp
|
src/interface/deck_loader/deck_loader.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
#include "card_name_normalizer.h"
|
||||||
|
|
||||||
|
#include "libcockatrice/card/database/card_database_manager.h"
|
||||||
|
|
||||||
|
QString CardNameNormalizer::operator()(const QString &cardNameString) const
|
||||||
|
{
|
||||||
|
QString cardName = cardNameString;
|
||||||
|
|
||||||
|
// Regex for advanced card parsing
|
||||||
|
static const QRegularExpression reSplitCard(R"( ?\/\/ ?)");
|
||||||
|
static const QRegularExpression reBrace(R"( ?[\[\{][^\]\}]*[\]\}] ?)"); // not nested
|
||||||
|
static const QRegularExpression reRoundBrace(R"(^\([^\)]*\) ?)"); // () are only matched at start of string
|
||||||
|
static const QRegularExpression reDigitBrace(R"( ?\(\d*\) ?)"); // () are matched if containing digits
|
||||||
|
static const QRegularExpression reBraceDigit(
|
||||||
|
R"( ?\([\dA-Z]+\) *\d+$)"); // () are matched if containing setcode then a number
|
||||||
|
static const QRegularExpression reDoubleFacedMarker(R"( ?\(Transform\) ?)");
|
||||||
|
|
||||||
|
static const QHash<QRegularExpression, QString> differences{{QRegularExpression("’"), "'"},
|
||||||
|
{QRegularExpression("Æ"), "Ae"},
|
||||||
|
{QRegularExpression("æ"), "ae"},
|
||||||
|
{QRegularExpression(" ?[|/]+ ?"), " // "}};
|
||||||
|
|
||||||
|
// Handle advanced card types
|
||||||
|
if (cardName.contains(reSplitCard)) {
|
||||||
|
cardName = cardName.split(reSplitCard).join(" // ");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardName.contains(reDoubleFacedMarker)) {
|
||||||
|
QStringList faces = cardName.split(reDoubleFacedMarker);
|
||||||
|
cardName = faces.first().trimmed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unnecessary characters
|
||||||
|
cardName.remove(reBrace);
|
||||||
|
cardName.remove(reRoundBrace); // I'll be entirely honest here, these are split to accommodate just three cards
|
||||||
|
cardName.remove(reDigitBrace); // from un-sets that have a word in between round braces at the end
|
||||||
|
cardName.remove(reBraceDigit); // very specific format with the set code in () and collectors number after
|
||||||
|
|
||||||
|
// Normalize characters
|
||||||
|
for (auto diff = differences.constBegin(); diff != differences.constEnd(); ++diff) {
|
||||||
|
cardName.replace(diff.key(), diff.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
return cardName;
|
||||||
|
}
|
||||||
15
cockatrice/src/interface/deck_loader/card_name_normalizer.h
Normal file
15
cockatrice/src/interface/deck_loader/card_name_normalizer.h
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef COCKATRICE_CARD_NAME_NORMALIZER_H
|
||||||
|
#define COCKATRICE_CARD_NAME_NORMALIZER_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functor that normalizes the raw card name parsed during a plaintext deck import into the card name that Cockatrice
|
||||||
|
* uses.
|
||||||
|
*/
|
||||||
|
struct CardNameNormalizer
|
||||||
|
{
|
||||||
|
QString operator()(const QString &cardNameString) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // COCKATRICE_CARD_NAME_NORMALIZER_H
|
||||||
|
|
@ -199,9 +199,12 @@ bool DeckList::saveToFile_Native(QIODevice *device) const
|
||||||
*
|
*
|
||||||
* @param in The text to load
|
* @param in The text to load
|
||||||
* @param preserveMetadata If true, don't clear the existing metadata
|
* @param preserveMetadata If true, don't clear the existing metadata
|
||||||
|
* @param cardNameNormalizer Function that takes the parsed card name string in the text and
|
||||||
* @return False if the input was empty, true otherwise.
|
* @return False if the input was empty, true otherwise.
|
||||||
*/
|
*/
|
||||||
bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
|
bool DeckList::loadFromStream_Plain(QTextStream &in,
|
||||||
|
bool preserveMetadata,
|
||||||
|
const std::function<QString(const QString &)> &cardNameNormalizer)
|
||||||
{
|
{
|
||||||
const QRegularExpression reCardLine(R"(^\s*[\w\[\(\{].*$)", QRegularExpression::UseUnicodePropertiesOption);
|
const QRegularExpression reCardLine(R"(^\s*[\w\[\(\{].*$)", QRegularExpression::UseUnicodePropertiesOption);
|
||||||
const QRegularExpression reEmpty("^\\s*$");
|
const QRegularExpression reEmpty("^\\s*$");
|
||||||
|
|
@ -213,23 +216,11 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
|
||||||
|
|
||||||
// Regex for advanced card parsing
|
// Regex for advanced card parsing
|
||||||
const QRegularExpression reMultiplier(R"(^[xX\(\[]*(\d+)[xX\*\)\]]* ?(.+))");
|
const QRegularExpression reMultiplier(R"(^[xX\(\[]*(\d+)[xX\*\)\]]* ?(.+))");
|
||||||
const QRegularExpression reSplitCard(R"( ?\/\/ ?)");
|
|
||||||
const QRegularExpression reBrace(R"( ?[\[\{][^\]\}]*[\]\}] ?)"); // not nested
|
|
||||||
const QRegularExpression reRoundBrace(R"(^\([^\)]*\) ?)"); // () are only matched at start of string
|
|
||||||
const QRegularExpression reDigitBrace(R"( ?\(\d*\) ?)"); // () are matched if containing digits
|
|
||||||
const QRegularExpression reBraceDigit(
|
|
||||||
R"( ?\([\dA-Z]+\) *\d+$)"); // () are matched if containing setcode then a number
|
|
||||||
const QRegularExpression reDoubleFacedMarker(R"( ?\(Transform\) ?)");
|
|
||||||
|
|
||||||
// Regex for extracting set code and collector number with attached symbols
|
// Regex for extracting set code and collector number with attached symbols
|
||||||
const QRegularExpression reHyphenFormat(R"(\((\w{3,})\)\s+(\w{3,})-(\d+[^\w\s]*))");
|
const QRegularExpression reHyphenFormat(R"(\((\w{3,})\)\s+(\w{3,})-(\d+[^\w\s]*))");
|
||||||
const QRegularExpression reRegularFormat(R"(\((\w{3,})\)\s+(\d+[^\w\s]*))");
|
const QRegularExpression reRegularFormat(R"(\((\w{3,})\)\s+(\d+[^\w\s]*))");
|
||||||
|
|
||||||
const QHash<QRegularExpression, QString> differences{{QRegularExpression("’"), QString("'")},
|
|
||||||
{QRegularExpression("Æ"), QString("Ae")},
|
|
||||||
{QRegularExpression("æ"), QString("ae")},
|
|
||||||
{QRegularExpression(" ?[|/]+ ?"), QString(" // ")}};
|
|
||||||
|
|
||||||
cleanList(preserveMetadata);
|
cleanList(preserveMetadata);
|
||||||
|
|
||||||
auto inputs = in.readAll().trimmed().split('\n');
|
auto inputs = in.readAll().trimmed().split('\n');
|
||||||
|
|
@ -355,26 +346,8 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
|
||||||
cardName = match.captured(2);
|
cardName = match.captured(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle advanced card types
|
// Normalize the card name
|
||||||
if (cardName.contains(reSplitCard)) {
|
cardName = cardNameNormalizer(cardName);
|
||||||
cardName = cardName.split(reSplitCard).join(" // ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cardName.contains(reDoubleFacedMarker)) {
|
|
||||||
QStringList faces = cardName.split(reDoubleFacedMarker);
|
|
||||||
cardName = faces.first().trimmed();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove unnecessary characters
|
|
||||||
cardName.remove(reBrace);
|
|
||||||
cardName.remove(reRoundBrace); // I'll be entirely honest here, these are split to accommodate just three cards
|
|
||||||
cardName.remove(reDigitBrace); // from un-sets that have a word in between round braces at the end
|
|
||||||
cardName.remove(reBraceDigit); // very specific format with the set code in () and collectors number after
|
|
||||||
|
|
||||||
// Normalize names
|
|
||||||
for (auto diff = differences.constBegin(); diff != differences.constEnd(); ++diff) {
|
|
||||||
cardName.replace(diff.key(), diff.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the zone (mainboard/sideboard)
|
// Determine the zone (mainboard/sideboard)
|
||||||
QString zoneName = sideboard ? DECK_ZONE_SIDE : DECK_ZONE_MAIN;
|
QString zoneName = sideboard ? DECK_ZONE_SIDE : DECK_ZONE_MAIN;
|
||||||
|
|
@ -387,10 +360,10 @@ bool DeckList::loadFromStream_Plain(QTextStream &in, bool preserveMetadata)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeckList::loadFromFile_Plain(QIODevice *device)
|
bool DeckList::loadFromFile_Plain(QIODevice *device, const std::function<QString(const QString &)> &cardNameNormalizer)
|
||||||
{
|
{
|
||||||
QTextStream in(device);
|
QTextStream in(device);
|
||||||
return loadFromStream_Plain(in, false);
|
return loadFromStream_Plain(in, false, cardNameNormalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeckList::saveToStream_Plain(QTextStream &stream, bool prefixSideboardCards, bool slashTappedOutSplitCards) const
|
bool DeckList::saveToStream_Plain(QTextStream &stream, bool prefixSideboardCards, bool slashTappedOutSplitCards) const
|
||||||
|
|
|
||||||
|
|
@ -206,8 +206,10 @@ public:
|
||||||
|
|
||||||
/// @name Serialization (Plain text)
|
/// @name Serialization (Plain text)
|
||||||
///@{
|
///@{
|
||||||
bool loadFromStream_Plain(QTextStream &stream, bool preserveMetadata);
|
bool loadFromStream_Plain(QTextStream &stream,
|
||||||
bool loadFromFile_Plain(QIODevice *device);
|
bool preserveMetadata,
|
||||||
|
const std::function<QString(const QString &)> &cardNameNormalizer);
|
||||||
|
bool loadFromFile_Plain(QIODevice *device, const std::function<QString(const QString &)> &cardNameNormalizer);
|
||||||
bool saveToStream_Plain(QTextStream &stream, bool prefixSideboardCards, bool slashTappedOutSplitCards) const;
|
bool saveToStream_Plain(QTextStream &stream, bool prefixSideboardCards, bool slashTappedOutSplitCards) const;
|
||||||
bool
|
bool
|
||||||
saveToFile_Plain(QIODevice *device, bool prefixSideboardCards = true, bool slashTappedOutSplitCards = false) const;
|
saveToFile_Plain(QIODevice *device, bool prefixSideboardCards = true, bool slashTappedOutSplitCards = false) const;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue