diff --git a/ext/js/display/display-generator.js b/ext/js/display/display-generator.js
index 15c5787d..2421b88a 100644
--- a/ext/js/display/display-generator.js
+++ b/ext/js/display/display-generator.js
@@ -470,20 +470,20 @@ class DisplayGenerator {
if (devoicePositions.length > 0) { node.dataset.devoiceMoraPosition = devoicePositions.join(' '); }
node.dataset.tagCount = `${tags.length}`;
- let n = node.querySelector('.pitch-accent-position');
- this._setTextContent(n, `${position}`, '');
-
- n = node.querySelector('.pitch-accent-tag-list');
+ let n = node.querySelector('.pitch-accent-tag-list');
this._appendMultiple(n, this._createTag.bind(this), tags);
n = node.querySelector('.pitch-accent-disambiguation-list');
this._createPitchAccentDisambiguations(n, exclusiveTerms, exclusiveReadings);
- n = node.querySelector('.pitch-accent-characters');
- n.lang = 'ja';
- n.appendChild(this._pronunciationGenerator.createPitchAccentHtml(morae, position, nasalPositions, devoicePositions));
+ n = node.querySelector('.pronunciation-downstep-notation-container');
+ n.appendChild(this._pronunciationGenerator.createPronunciationDownstepNotation(position));
- node.querySelector('.pitch-accent-details').appendChild(this._pronunciationGenerator.createPitchGraph(morae, position));
+ n = node.querySelector('.pronunciation-text-container');
+ n.lang = 'ja';
+ n.appendChild(this._pronunciationGenerator.createPronunciationText(morae, position, nasalPositions, devoicePositions));
+
+ node.querySelector('.pronunciation-graph-container').appendChild(this._pronunciationGenerator.createPronunciationGraph(morae, position));
return node;
}
diff --git a/ext/js/display/pronunciation-generator.js b/ext/js/display/pronunciation-generator.js
index 13e3db3e..bab36add 100644
--- a/ext/js/display/pronunciation-generator.js
+++ b/ext/js/display/pronunciation-generator.js
@@ -20,11 +20,12 @@ class PronunciationGenerator {
this._japaneseUtil = japaneseUtil;
}
- createPitchAccentHtml(morae, downstepPosition, nasalPositions, devoicePositions) {
+ createPronunciationText(morae, downstepPosition, nasalPositions, devoicePositions) {
const jp = this._japaneseUtil;
const nasalPositionsSet = nasalPositions.length > 0 ? new Set(nasalPositions) : null;
const devoicePositionsSet = devoicePositions.length > 0 ? new Set(devoicePositions) : null;
- const fragment = document.createDocumentFragment();
+ const container = 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];
@@ -34,48 +35,72 @@ class PronunciationGenerator {
const devoice = devoicePositionsSet !== null && devoicePositionsSet.has(i1);
const n1 = document.createElement('span');
- n1.className = 'pitch-accent-character';
+ n1.className = 'pronunciation-mora';
n1.dataset.position = `${i}`;
n1.dataset.pitch = highPitch ? 'high' : 'low';
n1.dataset.pitchNext = highPitchNext ? 'high' : 'low';
- const n2 = document.createElement('span');
- n2.className = 'pitch-accent-character-inner';
- n2.textContent = mora;
- n1.appendChild(n2);
+ const characterNodes = [];
+ for (const character of mora) {
+ const n2 = document.createElement('span');
+ n2.className = 'pronunciation-character';
+ n2.textContent = character;
+ n1.appendChild(n2);
+ characterNodes.push(n2);
+ }
if (devoice) {
n1.dataset.devoice = 'true';
const n3 = document.createElement('span');
- n3.className = 'pitch-accent-character-devoice-indicator';
+ n3.className = 'pronunciation-devoice-indicator';
n1.appendChild(n3);
}
- if (nasal) {
+ if (nasal && characterNodes.length > 0) {
n1.dataset.nasal = 'true';
- n1.dataset.originalText = mora;
- n2.textContent = this._getPlainMora(mora);
+
+ const group = document.createElement('span');
+ group.className = 'pronunciation-character-group';
+
+ const n2 = characterNodes[0];
+ const character = n2.textContent;
+
+ const characterInfo = jp.getKanaDiacriticInfo(character);
+ if (characterInfo !== null) {
+ n1.dataset.originalText = mora;
+ n2.dataset.originalText = character;
+ n2.textContent = characterInfo.character;
+ }
+
let n3 = document.createElement('span');
- n3.className = 'pitch-accent-character-nasal-diacritic';
+ n3.className = 'pronunciation-nasal-diacritic';
n3.textContent = '\u309a'; // Combining handakuten
- n1.appendChild(n3);
+ group.appendChild(n3);
+
n3 = document.createElement('span');
- n3.className = 'pitch-accent-character-nasal-indicator';
- n1.appendChild(n3);
+ n3.className = 'pronunciation-nasal-indicator';
+ group.appendChild(n3);
+
+ n2.parentNode.replaceChild(group, n2);
+ group.insertBefore(n2, group.firstChild);
}
- fragment.appendChild(n1);
+ const line = document.createElement('span');
+ line.className = 'pronunciation-mora-line';
+ n1.appendChild(line);
+
+ container.appendChild(n1);
}
- return fragment;
+ return container;
}
- createPitchGraph(morae, downstepPosition) {
+ createPronunciationGraph(morae, downstepPosition) {
const jp = this._japaneseUtil;
const ii = morae.length;
const svgns = 'http://www.w3.org/2000/svg';
const svg = document.createElementNS(svgns, 'svg');
svg.setAttribute('xmlns', svgns);
- svg.setAttribute('class', 'pitch-accent-graph');
+ svg.setAttribute('class', 'pronunciation-graph');
svg.setAttribute('focusable', 'false');
svg.setAttribute('viewBox', `0 0 ${50 * (ii + 1)} 100`);
@@ -101,7 +126,7 @@ class PronunciationGenerator {
pathPoints.push(`${x} ${y}`);
}
- path1.setAttribute('class', 'pitch-accent-graph-line');
+ path1.setAttribute('class', 'pronunciation-graph-line');
path1.setAttribute('d', `M${pathPoints.join(' L')}`);
pathPoints.splice(0, ii - 1);
@@ -113,26 +138,51 @@ class PronunciationGenerator {
pathPoints.push(`${x} ${y}`);
}
- path2.setAttribute('class', 'pitch-accent-graph-line-tail');
+ path2.setAttribute('class', 'pronunciation-graph-line-tail');
path2.setAttribute('d', `M${pathPoints.join(' L')}`);
return svg;
}
+ createPronunciationDownstepNotation(downstepPosition) {
+ downstepPosition = `${downstepPosition}`;
+
+ const n1 = document.createElement('span');
+ n1.className = 'pronunciation-downstep-notation';
+ n1.dataset.downstepPosition = downstepPosition;
+
+ let n2 = document.createElement('span');
+ n2.className = 'pronunciation-downstep-notation-prefix';
+ n2.textContent = '[';
+ n1.appendChild(n2);
+
+ n2 = document.createElement('span');
+ n2.className = 'pronunciation-downstep-notation-number';
+ n2.textContent = downstepPosition;
+ n1.appendChild(n2);
+
+ n2 = document.createElement('span');
+ n2.className = 'pronunciation-downstep-notation-suffix';
+ n2.textContent = ']';
+ n1.appendChild(n2);
+
+ return n1;
+ }
+
// Private
_addGraphDot(container, svgns, x, y) {
- container.appendChild(this._createGraphCircle(svgns, 'pitch-accent-graph-dot', x, y, '15'));
+ container.appendChild(this._createGraphCircle(svgns, 'pronunciation-graph-dot', x, y, '15'));
}
_addGraphDotDownstep(container, svgns, x, y) {
- container.appendChild(this._createGraphCircle(svgns, 'pitch-accent-graph-dot-downstep1', x, y, '15'));
- container.appendChild(this._createGraphCircle(svgns, 'pitch-accent-graph-dot-downstep2', x, y, '5'));
+ container.appendChild(this._createGraphCircle(svgns, 'pronunciation-graph-dot-downstep1', x, y, '15'));
+ container.appendChild(this._createGraphCircle(svgns, 'pronunciation-graph-dot-downstep2', x, y, '5'));
}
_addGraphTriangle(container, svgns, x, y) {
const node = document.createElementNS(svgns, 'path');
- node.setAttribute('class', 'pitch-accent-graph-triangle');
+ node.setAttribute('class', 'pronunciation-graph-triangle');
node.setAttribute('d', 'M0 13 L15 -13 L-15 -13 Z');
node.setAttribute('transform', `translate(${x},${y})`);
container.appendChild(node);
@@ -146,11 +196,4 @@ class PronunciationGenerator {
node.setAttribute('r', radius);
return node;
}
-
- _getPlainMora(mora) {
- const first = mora[0];
- const info = this._japaneseUtil.getKanaDiacriticInfo(first);
- if (info === null) { return mora; }
- return `${info.character}${mora.substring(1)}`;
- }
}
diff --git a/ext/pitch-accents-preview.html b/ext/pitch-accents-preview.html
deleted file mode 100644
index 73b9bc8a..00000000
--- a/ext/pitch-accents-preview.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
-
Yomichan Pitch Accents Preview
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Downstep notation -
-
- よ む
-
-
-
- Downstep position -
-
- 1
-
-
-
- Graph -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ext/settings.html b/ext/settings.html
index 7380b753..b45d8c22 100644
--- a/ext/settings.html
+++ b/ext/settings.html
@@ -13,6 +13,7 @@
+
@@ -747,7 +748,35 @@
Pitch accents for terms and expressions can be shown if a dictionary supporting pitch accents is installed.
There are currently three different ways that pitch accents can be presented:
-
+
+
+ Downstep notation -
+
+ よ む
+
+
+
+ Downstep position -
+
+ [ 1 ]
+
+
+
+ Graph -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Less…
diff --git a/test/data/dictionaries/valid-dictionary1/term_meta_bank_1.json b/test/data/dictionaries/valid-dictionary1/term_meta_bank_1.json
index faa1d216..877e5107 100644
--- a/test/data/dictionaries/valid-dictionary1/term_meta_bank_1.json
+++ b/test/data/dictionaries/valid-dictionary1/term_meta_bank_1.json
@@ -62,6 +62,16 @@
]
}
],
+ [
+ "所業",
+ "pitch",
+ {
+ "reading": "しょぎょう",
+ "pitches": [
+ {"position": 0, "nasal": 2}
+ ]
+ }
+ ],
[
"土木工事",
"pitch",
diff --git a/test/test-database.js b/test/test-database.js
index d43f88b1..6a980042 100644
--- a/test/test-database.js
+++ b/test/test-database.js
@@ -162,8 +162,8 @@ async function testDatabase1() {
true
);
vm.assert.deepStrictEqual(counts, {
- counts: [{kanji: 2, kanjiMeta: 2, terms: 15, termMeta: 15, tagMeta: 15, media: 2}],
- total: {kanji: 2, kanjiMeta: 2, terms: 15, termMeta: 15, tagMeta: 15, media: 2}
+ counts: [{kanji: 2, kanjiMeta: 2, terms: 15, termMeta: 16, tagMeta: 15, media: 2}],
+ total: {kanji: 2, kanjiMeta: 2, terms: 15, termMeta: 16, tagMeta: 15, media: 2}
});
// Test find* functions