feat: Add terms to kanji view
This commit is contained in:
parent
e92549b504
commit
99fedadd81
|
@ -124,6 +124,7 @@ class KanjiController extends AbstractController
|
||||||
"{$this->getParameter('kernel.project_dir')}/data/kanken-links.json",
|
"{$this->getParameter('kernel.project_dir')}/data/kanken-links.json",
|
||||||
), true);
|
), true);
|
||||||
|
|
||||||
|
$terms = $this->anki->searchTerms($charStr);
|
||||||
|
|
||||||
$ebookRef = require "$this->varBasepath/ebook-ref.php";
|
$ebookRef = require "$this->varBasepath/ebook-ref.php";
|
||||||
|
|
||||||
|
@ -131,6 +132,7 @@ class KanjiController extends AbstractController
|
||||||
'char' => $charStr,
|
'char' => $charStr,
|
||||||
'codepoint' => $codepoint,
|
'codepoint' => $codepoint,
|
||||||
'info' => $charInfo,
|
'info' => $charInfo,
|
||||||
|
'terms' => $terms,
|
||||||
'ref' => $ebookRef[$charStr] ?? [],
|
'ref' => $ebookRef[$charStr] ?? [],
|
||||||
'jiten_href' => key_exists($charStr, $jiten)
|
'jiten_href' => key_exists($charStr, $jiten)
|
||||||
? "https://kanji.jitenon.jp/kanji{$jiten[$charStr]}"
|
? "https://kanji.jitenon.jp/kanji{$jiten[$charStr]}"
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Service;
|
||||||
use App\Entity\Note;
|
use App\Entity\Note;
|
||||||
use App\Entity\SentenceListeningNote;
|
use App\Entity\SentenceListeningNote;
|
||||||
use App\Entity\SentenceNote;
|
use App\Entity\SentenceNote;
|
||||||
|
use App\Entity\Term;
|
||||||
use App\Entity\UnicodeNote;
|
use App\Entity\UnicodeNote;
|
||||||
use App\Utils\Japanese;
|
use App\Utils\Japanese;
|
||||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||||
|
@ -203,4 +204,24 @@ class AnkiService
|
||||||
|
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @return Term[] */
|
||||||
|
public function searchTerms(string $query): array
|
||||||
|
{
|
||||||
|
$ret = [];
|
||||||
|
|
||||||
|
$ids = $this->request('findNotes', ['query' => "VocabKanji:*$query*"]);
|
||||||
|
$notes = $this->getNotes($ids);
|
||||||
|
|
||||||
|
foreach ($notes as $note) {
|
||||||
|
if (!$note instanceof SentenceNote) continue;
|
||||||
|
|
||||||
|
foreach ($note->getTerms() as $term) {
|
||||||
|
$ret[$term->getKanji()] = $term;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Twig\Extension;
|
namespace App\Twig\Extension;
|
||||||
|
|
||||||
use App\Twig\Runtime\AppExtensionRuntime;
|
use App\Twig\Runtime\AppExtensionRuntime;
|
||||||
|
use App\Utils\Japanese;
|
||||||
use Twig\Extension\AbstractExtension;
|
use Twig\Extension\AbstractExtension;
|
||||||
use Twig\TwigFilter;
|
use Twig\TwigFilter;
|
||||||
use Twig\TwigFunction;
|
use Twig\TwigFunction;
|
||||||
|
@ -16,6 +17,7 @@ class AppExtension extends AbstractExtension
|
||||||
// parameter: ['is_safe' => ['html']]
|
// parameter: ['is_safe' => ['html']]
|
||||||
// Reference: https://twig.symfony.com/doc/3.x/advanced.html#automatic-escaping
|
// Reference: https://twig.symfony.com/doc/3.x/advanced.html#automatic-escaping
|
||||||
new TwigFilter('basename', basename(...)),
|
new TwigFilter('basename', basename(...)),
|
||||||
|
new TwigFilter('ruby', self::ankiRubyToHtml(...)),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,4 +27,13 @@ class AppExtension extends AbstractExtension
|
||||||
//new TwigFunction('function_name', [AppExtensionRuntime::class, 'doSomething']),
|
//new TwigFunction('function_name', [AppExtensionRuntime::class, 'doSomething']),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function ankiRubyToHtml(string $str): string
|
||||||
|
{
|
||||||
|
return preg_replace(
|
||||||
|
'/ ?([^ ><\[\n]+)\[([^\[]+)\]/',
|
||||||
|
'<ruby>$1<rp>(</rp><rt>$2<rt><rp>)</rp></ruby>',
|
||||||
|
$str
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
<div class="d-flex flex-column gap-2 p-3 align-items-start">
|
<div class="d-flex flex-column gap-2 p-3 align-items-start">
|
||||||
<div class="d-flex gap-2 w-100">
|
<div class="d-flex gap-2 w-100">
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
<div class="card-header text-center">
|
||||||
|
{{ codepoint }}
|
||||||
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div style="font-size: 6em;">{{ char }}</div>
|
<div style="font-size: 6em;">{{ char }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer">
|
||||||
{{ codepoint }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-grow-1">
|
|
||||||
<h2>Lists</h2>
|
|
||||||
<ul>
|
|
||||||
{% for list in info|keys %}
|
{% for list in info|keys %}
|
||||||
<li>{{ list }}</li>
|
<div class="badge text-bg-secondary">{{ list }}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<h2>Links</h2>
|
<h2>Links</h2>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -92,6 +91,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column">
|
||||||
|
<div class="d-flex flex-column">
|
||||||
|
<h2>Terms</h2>
|
||||||
|
{% for term in terms|slice(0,5) %}
|
||||||
|
<div>
|
||||||
|
<div class="text">{{ term.toAnkiVocabDef|ruby|raw }}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<h2>Appeareances</h2>
|
<h2>Appeareances</h2>
|
||||||
{% for refname, refcount in ref %}
|
{% for refname, refcount in ref %}
|
||||||
<div>{{ refname|basename }}: {{ refcount }}</div>
|
<div>{{ refname|basename }}: {{ refcount }}</div>
|
||||||
|
|
Loading…
Reference in New Issue