Skip to content
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
15 changes: 12 additions & 3 deletions ext/data/schemas/dictionary-term-meta-bank-v3-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,18 @@
"additionalProperties": false,
"properties": {
"position": {
"type": "integer",
"description": "Mora position of the pitch accent downstep. A value of 0 indicates that the word does not have a downstep (heiban).",
"minimum": 0
"oneOf": [
{
"type": "integer",
"description": "Mora position of the pitch accent downstep. A value of 0 indicates that the word does not have a downstep (heiban).",
"minimum": 0
},
{
"type": "string",
"description": "Pitch level of each mora with H representing high and L representing low. For example: HHLL for a 4 mora word.",
"pattern": "^[HL]+$"
}
]
},
"nasal": {
"oneOf": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@

{{#*inline "glossary-plain-no-dictionary"~}}
{{~> glossary-plain noDictionaryTag=true ~}}
{{/inline}}
{{/inline}}
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,4 @@
{{~/unless~}}
{{~/each~}}
{{/if}}
{{/inline}}
{{/inline}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{{<<<<<<<}}
{{#*inline "pitch-accent-item"}}
{{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}
{{=======}}
{{#*inline "pitch-accent-item"}}
{{~pronunciation format=format reading=reading pitchPositions=positions nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}
{{>>>>>>>}}
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@

{{! Pitch Accents }}
{{#*inline "pitch-accent-item"}}
{{~pronunciation format=format reading=reading downstepPosition=position nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{~pronunciation format=format reading=reading pitchPositions=positions nasalPositions=nasalPositions devoicePositions=devoicePositions~}}
{{/inline}}

{{#*inline "pitch-accent-item-disambiguation"}}
Expand Down
8 changes: 4 additions & 4 deletions ext/js/data/anki-note-data-creator.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,12 @@ function getPitches(dictionaryEntry) {
for (const groupedPronunciation of pronunciations) {
const {pronunciation} = groupedPronunciation;
if (pronunciation.type !== 'pitch-accent') { continue; }
const {position, nasalPositions, devoicePositions, tags} = pronunciation;
const {positions, nasalPositions, devoicePositions, tags} = pronunciation;
const {terms, reading, exclusiveTerms, exclusiveReadings} = groupedPronunciation;
pitches.push({
expressions: terms,
reading,
position,
positions,
nasalPositions,
devoicePositions,
tags: convertPitchTags(tags),
Expand Down Expand Up @@ -664,10 +664,10 @@ function getTermPitches(dictionaryEntry) {
*/
function getTermPitchesInner(pitches) {
const results = [];
for (const {position, tags} of pitches) {
for (const {positions, tags} of pitches) {
const cachedTags = createCachedValue(convertTags.bind(null, tags));
results.push({
position,
positions,
get tags() { return getCachedValue(cachedTags); },
});
}
Expand Down
9 changes: 9 additions & 0 deletions ext/js/data/options-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ export class OptionsUtil {
this._updateVersion65,
this._updateVersion66,
this._updateVersion67,
this._updateVersion68,
];
/* eslint-enable @typescript-eslint/unbound-method */
if (typeof targetVersion === 'number' && targetVersion < result.length) {
Expand Down Expand Up @@ -1754,6 +1755,14 @@ export class OptionsUtil {
await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v67.handlebars');
}

/**
* - Changed pitch-accent-item param name
* @type {import('options-util').UpdateFunction}
*/
async _updateVersion68(options) {
await this._applyAnkiFieldTemplatesPatch(options, '/data/templates/anki-field-templates-upgrade-v68.handlebars');
}

/**
* @param {string} url
* @returns {Promise<chrome.tabs.Tab>}
Expand Down
2 changes: 1 addition & 1 deletion ext/js/dictionary/dictionary-data-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ function arePronunciationsEquivalent({pronunciation: pronunciation1}, pronunciat
// This cast is valid based on the type check at the start of the function.
const pitchAccent2 = /** @type {import('dictionary').PitchAccent} */ (pronunciation2);
return (
pronunciation1.position === pitchAccent2.position &&
pronunciation1.positions === pitchAccent2.positions &&
areArraysEqual(pronunciation1.nasalPositions, pitchAccent2.nasalPositions) &&
areArraysEqual(pronunciation1.devoicePositions, pitchAccent2.devoicePositions)
);
Expand Down
12 changes: 6 additions & 6 deletions ext/js/display/display-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -799,13 +799,13 @@ export class DisplayGenerator {
* @returns {HTMLElement}
*/
_createPronunciationPitchAccent(pitchAccent, details) {
const {position, nasalPositions, devoicePositions, tags} = pitchAccent;
const {positions, nasalPositions, devoicePositions, tags} = pitchAccent;
const {reading, exclusiveTerms, exclusiveReadings} = details;
const morae = getKanaMorae(reading);

const node = this._instantiate('pronunciation');

node.dataset.pitchAccentDownstepPosition = `${position}`;
node.dataset.pitchAccentDownstepPosition = `${positions}`;
node.dataset.pronunciationType = pitchAccent.type;
if (nasalPositions.length > 0) { node.dataset.nasalMoraPosition = nasalPositions.join(' '); }
if (devoicePositions.length > 0) { node.dataset.devoiceMoraPosition = devoicePositions.join(' '); }
Expand All @@ -818,15 +818,15 @@ export class DisplayGenerator {
this._createPronunciationDisambiguations(n, exclusiveTerms, exclusiveReadings);

n = this._querySelector(node, '.pronunciation-downstep-notation-container');
n.appendChild(this._pronunciationGenerator.createPronunciationDownstepPosition(position));
n.appendChild(this._pronunciationGenerator.createPronunciationDownstepPosition(positions));

n = this._querySelector(node, '.pronunciation-text-container');

n.lang = this._language;
n.appendChild(this._pronunciationGenerator.createPronunciationText(morae, position, nasalPositions, devoicePositions));
n.appendChild(this._pronunciationGenerator.createPronunciationText(morae, positions, nasalPositions, devoicePositions));

n = this._querySelector(node, '.pronunciation-graph-container');
n.appendChild(this._pronunciationGenerator.createPronunciationGraph(morae, position));
n.appendChild(this._pronunciationGenerator.createPronunciationGraph(morae, positions));

return node;
}
Expand Down Expand Up @@ -1138,7 +1138,7 @@ export class DisplayGenerator {
if (termPronunciation.headwordIndex !== headwordIndex) { continue; }
for (const pronunciation of termPronunciation.pronunciations) {
if (pronunciation.type !== 'pitch-accent') { continue; }
const category = getPitchCategory(reading, pronunciation.position, isVerbOrAdjective);
const category = getPitchCategory(reading, pronunciation.positions, isVerbOrAdjective);
if (category !== null) {
categories.add(category);
}
Expand Down
36 changes: 19 additions & 17 deletions ext/js/display/pronunciation-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import {getKanaDiacriticInfo, isMoraPitchHigh} from '../language/ja/japanese.js';
import {getDownstepPositions, getKanaDiacriticInfo, isMoraPitchHigh} from '../language/ja/japanese.js';

export class PronunciationGenerator {
/**
Expand All @@ -30,21 +30,21 @@ export class PronunciationGenerator {

/**
* @param {string[]} morae
* @param {number} downstepPosition
* @param {number | string} pitchPositions
* @param {number[]} nasalPositions
* @param {number[]} devoicePositions
* @returns {HTMLSpanElement}
*/
createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions) {
createPronunciationText(morae, pitchPositions, nasalPositions, devoicePositions) {
const nasalPositionsSet = nasalPositions.length > 0 ? new Set(nasalPositions) : null;
const devoicePositionsSet = devoicePositions.length > 0 ? new Set(devoicePositions) : null;
const container = this._document.createElement('span');
container.className = 'pronunciation-text';
for (let i = 0, ii = morae.length; i < ii; ++i) {
const i1 = i + 1;
const mora = morae[i];
const highPitch = isMoraPitchHigh(i, downstepPosition);
const highPitchNext = isMoraPitchHigh(i1, downstepPosition);
const highPitch = isMoraPitchHigh(i, pitchPositions);
const highPitchNext = isMoraPitchHigh(i1, pitchPositions);
const nasal = nasalPositionsSet !== null && nasalPositionsSet.has(i1);
const devoice = devoicePositionsSet !== null && devoicePositionsSet.has(i1);

Expand Down Expand Up @@ -109,10 +109,10 @@ export class PronunciationGenerator {

/**
* @param {string[]} morae
* @param {number} downstepPosition
* @param {number | string} pitchPositions
* @returns {SVGSVGElement}
*/
createPronunciationGraph(morae, downstepPosition) {
createPronunciationGraph(morae, pitchPositions) {
const ii = morae.length;

const svgns = 'http://www.w3.org/2000/svg';
Expand All @@ -132,8 +132,8 @@ export class PronunciationGenerator {

const pathPoints = [];
for (let i = 0; i < ii; ++i) {
const highPitch = isMoraPitchHigh(i, downstepPosition);
const highPitchNext = isMoraPitchHigh(i + 1, downstepPosition);
const highPitch = isMoraPitchHigh(i, pitchPositions);
const highPitchNext = isMoraPitchHigh(i + 1, pitchPositions);
const x = i * 50 + 25;
const y = highPitch ? 25 : 75;
if (highPitch && !highPitchNext) {
Expand All @@ -149,7 +149,7 @@ export class PronunciationGenerator {

pathPoints.splice(0, ii - 1);
{
const highPitch = isMoraPitchHigh(ii, downstepPosition);
const highPitch = isMoraPitchHigh(ii, pitchPositions);
const x = ii * 50 + 25;
const y = highPitch ? 25 : 75;
this._addGraphTriangle(svg, svgns, x, y);
Expand All @@ -163,11 +163,12 @@ export class PronunciationGenerator {
}

/**
* @param {number} downstepPosition
* @param {number | string} downstepPositions
* @returns {HTMLSpanElement}
*/
createPronunciationDownstepPosition(downstepPosition) {
const downstepPositionString = `${downstepPosition}`;
createPronunciationDownstepPosition(downstepPositions) {
const downsteps = typeof downstepPositions === 'string' ? getDownstepPositions(downstepPositions) : downstepPositions;
const downstepPositionString = `${downsteps}`;

const n1 = this._document.createElement('span');
n1.className = 'pronunciation-downstep-notation';
Expand Down Expand Up @@ -198,11 +199,11 @@ export class PronunciationGenerator {
/**
* Create a pronounciation graph in the style of Jidoujisho
* @param {string[]} mora
* @param {number} downstepPosition
* @param {number | string} pitchPositions
* @returns {SVGSVGElement}
*/
createPronunciationGraphJJ(mora, downstepPosition) {
const patt = this._pitchValueToPattJJ(mora.length, downstepPosition);
createPronunciationGraphJJ(mora, pitchPositions) {
const patt = this._pitchValueToPattJJ(mora.length, pitchPositions);

const positions = Math.max(mora.length, patt.length);
const stepWidth = 35;
Expand Down Expand Up @@ -325,10 +326,11 @@ export class PronunciationGenerator {
/**
* Get H&L pattern
* @param {number} numberOfMora
* @param {number} pitchValue
* @param {number | string} pitchValue
* @returns {string}
*/
_pitchValueToPattJJ(numberOfMora, pitchValue) {
if (typeof pitchValue === 'string') { return pitchValue + pitchValue[pitchValue.length - 1]; }
if (numberOfMora >= 1) {
if (pitchValue === 0) {
// Heiban
Expand Down
34 changes: 28 additions & 6 deletions ext/js/language/ja/japanese.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,24 +352,28 @@ export function isStringPartiallyJapanese(str) {

/**
* @param {number} moraIndex
* @param {number} pitchAccentDownstepPosition
* @param {number | string} pitchAccentValue
* @returns {boolean}
*/
export function isMoraPitchHigh(moraIndex, pitchAccentDownstepPosition) {
switch (pitchAccentDownstepPosition) {
export function isMoraPitchHigh(moraIndex, pitchAccentValue) {
if (typeof pitchAccentValue === 'string') {
return pitchAccentValue[moraIndex] === 'H';
}
switch (pitchAccentValue) {
case 0: return (moraIndex > 0);
case 1: return (moraIndex < 1);
default: return (moraIndex > 0 && moraIndex < pitchAccentDownstepPosition);
default: return (moraIndex > 0 && moraIndex < pitchAccentValue);
}
}

/**
* @param {string} text
* @param {number} pitchAccentDownstepPosition
* @param {number | string} pitchAccentValue
* @param {boolean} isVerbOrAdjective
* @returns {?import('japanese-util').PitchCategory}
*/
export function getPitchCategory(text, pitchAccentDownstepPosition, isVerbOrAdjective) {
export function getPitchCategory(text, pitchAccentValue, isVerbOrAdjective) {
const pitchAccentDownstepPosition = typeof pitchAccentValue === 'string' ? getDownstepPositions(pitchAccentValue)[0] : pitchAccentValue;
if (pitchAccentDownstepPosition === 0) {
return 'heiban';
}
Expand All @@ -385,6 +389,24 @@ export function getPitchCategory(text, pitchAccentDownstepPosition, isVerbOrAdje
return null;
}

/**
* @param {string} pitchString
* @returns {number[]}
*/
export function getDownstepPositions(pitchString) {
const downsteps = [];
const moraCount = pitchString.length;
for (let i = 0; i < moraCount; i++) {
if (i > 0 && pitchString[i - 1] === 'H' && pitchString[i] === 'L') {
downsteps.push(i);
}
}
if (downsteps.length === 0) {
downsteps.push(pitchString.startsWith('L') ? 0 : -1);
}
return downsteps;
}

/**
* @param {string} text
* @returns {string[]}
Expand Down
2 changes: 1 addition & 1 deletion ext/js/language/translator.js
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,7 @@ export class Translator {
const devoicePositions = this._toNumberArray(devoice);
pitches.push({
type: 'pitch-accent',
position,
positions: position,
nasalPositions,
devoicePositions,
tags: tags2,
Expand Down
16 changes: 8 additions & 8 deletions ext/js/templates/anki-template-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,8 @@ export class AnkiTemplateRenderer {
const {reading, wordClasses} = headwords[headwordIndex];
const isVerbOrAdjective = isNonNounVerbOrAdjective(wordClasses);
const pitches = getPronunciationsOfType(pronunciations, 'pitch-accent');
for (const {position} of pitches) {
const category = getPitchCategory(reading, position, isVerbOrAdjective);
for (const {positions} of pitches) {
const category = getPitchCategory(reading, positions, isVerbOrAdjective);
if (category !== null) {
categories.add(category);
}
Expand Down Expand Up @@ -843,12 +843,12 @@ export class AnkiTemplateRenderer {
* @type {import('template-renderer').HelperFunction<string>}
*/
_pronunciation(_args, _context, options) {
const {format, reading, downstepPosition} = options.hash;
const {format, reading, pitchPositions} = options.hash;

if (
typeof reading !== 'string' ||
reading.length === 0 ||
typeof downstepPosition !== 'number'
(typeof pitchPositions !== 'number' && typeof pitchPositions !== 'string')
) {
return '';
}
Expand All @@ -859,14 +859,14 @@ export class AnkiTemplateRenderer {
{
const nasalPositions = this._getValidNumberArray(options.hash.nasalPositions);
const devoicePositions = this._getValidNumberArray(options.hash.devoicePositions);
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions));
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationText(morae, pitchPositions, nasalPositions, devoicePositions));
}
case 'graph':
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationGraph(morae, downstepPosition));
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationGraph(morae, pitchPositions));
case 'graph-jj':
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationGraphJJ(morae, downstepPosition));
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationGraphJJ(morae, pitchPositions));
case 'position':
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationDownstepPosition(downstepPosition));
return this._getPronunciationHtml(this._pronunciationGenerator.createPronunciationDownstepPosition(pitchPositions));
default:
return '';
}
Expand Down
Loading