Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src/anki/ankiclient: add {pitch-categories} marker #253

Merged
merged 1 commit into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 68 additions & 2 deletions src/anki/ankiclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1124,9 +1124,12 @@ QJsonObject AnkiClient::createAnkiNoteObject(
);

QString pitch;
QString pitchCategories;
QString pitchGraph;
QString pitchPosition;
buildPitchInfo(term.pitches, pitch, pitchGraph, pitchPosition);
const bool canBeKifuku{isKifukuApplicable(term.definitions)};
buildPitchInfo(term.pitches, canBeKifuku, pitch, pitchCategories,
pitchGraph, pitchPosition);

QString tags, tagsBrief;
buildTags(term.tags, tags, tagsBrief);
Expand All @@ -1152,6 +1155,7 @@ QJsonObject AnkiClient::createAnkiNoteObject(
value.replace(REPLACE_GLOSSARY_BRIEF, glossaryBrief);
value.replace(REPLACE_GLOSSARY_COMPACT, glossaryCompact);
value.replace(REPLACE_PITCH, pitch);
value.replace(REPLACE_PITCH_CATEGORIES, pitchCategories);
value.replace(REPLACE_PITCH_GRAPHS, pitchGraph);
value.replace(REPLACE_PITCH_POSITIONS, pitchPosition);
value.replace(REPLACE_READING, reading);
Expand Down Expand Up @@ -1556,7 +1560,9 @@ void AnkiClient::buildCommonNote(
#define PITCH_FORMAT (QString("<span style=\"%1\">%2</span>"))

void AnkiClient::buildPitchInfo(const QList<Pitch> &pitches,
const bool canBeKifuku,
QString &pitch,
QString &pitchCategories,
QString &pitchGraph,
QString &pitchPosition)
{
Expand All @@ -1569,6 +1575,8 @@ void AnkiClient::buildPitchInfo(const QList<Pitch> &pitches,
pitchGraph += "<span>";
pitchPosition += "<span>";

QSet<QString> pitchCategoriesSet{};

const bool multipleDicts = pitches.size() > 1;

if (multipleDicts)
Expand Down Expand Up @@ -1611,10 +1619,11 @@ void AnkiClient::buildPitchInfo(const QList<Pitch> &pitches,
pitchPosition += "<li>";
}

/* Build {pitch} marker */
/* Build {pitch} and {pitch-categories} markers */
switch (pos)
{
case 0:
pitchCategoriesSet << "heiban";
pitch += p.mora.first();
if (p.mora.size() > 1)
{
Expand All @@ -1624,6 +1633,7 @@ void AnkiClient::buildPitchInfo(const QList<Pitch> &pitches,
}
break;
case 1:
pitchCategoriesSet << (canBeKifuku ? "kifuku" : "atamadaka");
pitch += PITCH_FORMAT.arg(HL_STYLE).arg(p.mora.first());
if (p.mora.size() > 1)
{
Expand All @@ -1632,6 +1642,18 @@ void AnkiClient::buildPitchInfo(const QList<Pitch> &pitches,
break;
default:
{
if (p.mora.size() == pos)
{
pitchCategoriesSet << "odaka";
}
else if (canBeKifuku)
{
pitchCategoriesSet << "kifuku";
}
else
{
pitchCategoriesSet << "nakadaka";
}
QString text = p.mora.first();
pitch += text;

Expand Down Expand Up @@ -1698,6 +1720,20 @@ void AnkiClient::buildPitchInfo(const QList<Pitch> &pitches,
pitch += "</span>";
pitchGraph += "</span>";
pitchPosition += "</span>";

bool isFirstPitchCategory{true};
for (const QString &pitchCategory : pitchCategoriesSet)
{
if (isFirstPitchCategory)
{
pitchCategories += pitchCategory;
isFirstPitchCategory = false;
}
else
{
pitchCategories += "," + pitchCategory;
}
}
}

#undef HL_STYLE
Expand Down Expand Up @@ -1905,4 +1941,34 @@ QString AnkiClient::fileToBase64(const QString &path)
return file.readAll().toBase64();
}

bool AnkiClient::isKifukuApplicable(const QList<TermDefinition> &defs)
{
bool canBeKifuku{false};

for (const TermDefinition &def : defs)
{
for (const QString &rule : def.rules)
{
/* See http://www.edrdg.org/jmwsgi/edhelp.py?svc=jmdict&sid=#kw_pos
* for more information on the meaning of JMDict part-of-speech tags
* such as "v1", "adj-i", etc.
*/
if (rule == "v1" || // Ichidan verb
rule == "v5" || // Godan verb
rule == "vk" || // Kuru verb - special class
rule == "vz" || // Ichidan verb - zuru verb (alternative form of -jiru verb)
rule == "adj-i") // I-adjective (keiyoushi)
{
canBeKifuku = true;
}
else if (rule == "vs") // Noun or participle which takes the aux. verb suru
{
return false;
}
}
}

return canBeKifuku;
}

/* End Note Helpers */
29 changes: 21 additions & 8 deletions src/anki/ankiclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
#define REPLACE_GLOSSARY_BRIEF "{glossary-brief}"
#define REPLACE_GLOSSARY_COMPACT "{glossary-compact}"
#define REPLACE_PITCH "{pitch}"
#define REPLACE_PITCH_CATEGORIES "{pitch-categories}"
#define REPLACE_PITCH_GRAPHS "{pitch-graph}"
#define REPLACE_PITCH_POSITIONS "{pitch-position}"
#define REPLACE_READING "{reading}"
Expand Down Expand Up @@ -477,17 +478,23 @@ private Q_SLOTS:
int getFrequencyAverage(const QList<Frequency> &freq);

/**
* Creates the HTML representation of the pitch, pitch graph, and pitch
* position for the given pitches.
* @param pitches The pitches to turn into HTML.
* @param[out] pitch The HTML representation of the {pitch} marker.
* @param[out] pitchGraph The HTML representation of the {pitch-graph}
* marker.
* @param[out] pitchPosition The HTML representation of the {pitch-position}
* marker.
* Creates the HTML representation of the pitch, pitch category, pitch graph,
* and pitch position for the given pitches.
* @param pitches The pitches to turn into HTML.
* @param canBeKifuku Is the term an i-adjective or a verb whose
* pitch accent is either kifuku or heiban.
* @param[out] pitch The HTML representation of the {pitch} marker.
* @param[out] pitchCategories The comma-separated representation of the
* {pitch-categories} marker.
* @param[out] pitchGraph The HTML representation of the {pitch-graph}
* marker.
* @param[out] pitchPosition The HTML representation of the {pitch-position}
* marker.
*/
void buildPitchInfo(const QList<Pitch> &pitches,
const bool canBeKifuku,
QString &pitch,
QString &pitchCategories,
QString &pitchGraph,
QString &pitchPosition);

Expand Down Expand Up @@ -530,6 +537,12 @@ private Q_SLOTS:
*/
static QString fileToBase64(const QString &path);

/**
* Helper method to determine if the kifuku pitch accent pattern
* is potentially applicable to a term, by checking its part-of-speech.
*/
bool isKifukuApplicable(const QList<TermDefinition> &defs);

/* true if a config exists, false otherwise */
bool m_configExists = false;

Expand Down
1 change: 1 addition & 0 deletions src/gui/widgets/settings/ankisettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ AnkiSettings::AnkiSettings(QWidget *parent)
REPLACE_GLOSSARY_BRIEF,
REPLACE_GLOSSARY_COMPACT,
REPLACE_PITCH,
REPLACE_PITCH_CATEGORIES,
REPLACE_PITCH_GRAPHS,
REPLACE_PITCH_POSITIONS,
REPLACE_READING,
Expand Down
Loading
Loading