diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..a4af997 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "unofficial-jisho-api-dart", + "request": "launch", + "type": "dart", + "program": "example/api/phrase_search_copy.dart" + } + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cb2f47..d7f1d09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 2.0.0 + +- Upgrade library to use null-safety +- Wrap the result data in "Data" classes that are nullable if no result was found +- Add sound data to phrase scrape results + ## 1.1.0 - Export object interfaces for both libraries diff --git a/analysis_options.yaml b/analysis_options.yaml index 0262cd6..9dd74f3 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -8,8 +8,6 @@ include: package:effective_dart/analysis_options.yaml # Uncomment to specify additional rules. linter: rules: - public_member_api_docs: false lines_longer_than_80_chars: false - omit_local_variable_types: false analyzer: diff --git a/example/api/example_search.dart b/example/api/example_search.dart index 7861318..5dad90f 100644 --- a/example/api/example_search.dart +++ b/example/api/example_search.dart @@ -1,8 +1,8 @@ import 'dart:convert' show jsonEncode; import 'package:unofficial_jisho_api/api.dart' as jisho; -void main() async { - await jisho.searchForExamples('日').then((result) { +void main() { + jisho.searchForExamples('日').then((result) { print('Jisho Uri: ${result.uri}'); print(''); diff --git a/example/api/kanji_search.dart b/example/api/kanji_search.dart index 085358b..015d216 100644 --- a/example/api/kanji_search.dart +++ b/example/api/kanji_search.dart @@ -1,23 +1,27 @@ import 'dart:convert' show jsonEncode; import 'package:unofficial_jisho_api/api.dart' as jisho; -void main() async { - await jisho.searchForKanji('語').then((result) { +void main() { + jisho.searchForKanji('語').then((result) { print('Found: ${result.found}'); - print('Taught in: ${result.taughtIn}'); - print('JLPT level: ${result.jlptLevel}'); - print('Newspaper frequency rank: ${result.newspaperFrequencyRank}'); - print('Stroke count: ${result.strokeCount}'); - print('Meaning: ${result.meaning}'); - print('Kunyomi: ${jsonEncode(result.kunyomi)}'); - print('Kunyomi example: ${jsonEncode(result.kunyomiExamples[0])}'); - print('Onyomi: ${jsonEncode(result.onyomi)}'); - print('Onyomi example: ${jsonEncode(result.onyomiExamples[0])}'); - print('Radical: ${jsonEncode(result.radical)}'); - print('Parts: ${jsonEncode(result.parts)}'); - print('Stroke order diagram: ${result.strokeOrderDiagramUri}'); - print('Stroke order SVG: ${result.strokeOrderSvgUri}'); - print('Stroke order GIF: ${result.strokeOrderGifUri}'); - print('Jisho Uri: ${result.uri}'); + + final data = result.data; + if (data != null) { + print('Taught in: ${data.taughtIn}'); + print('JLPT level: ${data.jlptLevel}'); + print('Newspaper frequency rank: ${data.newspaperFrequencyRank}'); + print('Stroke count: ${data.strokeCount}'); + print('Meaning: ${data.meaning}'); + print('Kunyomi: ${jsonEncode(data.kunyomi)}'); + print('Kunyomi example: ${jsonEncode(data.kunyomiExamples[0])}'); + print('Onyomi: ${jsonEncode(data.onyomi)}'); + print('Onyomi example: ${jsonEncode(data.onyomiExamples[0])}'); + print('Radical: ${jsonEncode(data.radical)}'); + print('Parts: ${jsonEncode(data.parts)}'); + print('Stroke order diagram: ${data.strokeOrderDiagramUri}'); + print('Stroke order SVG: ${data.strokeOrderSvgUri}'); + print('Stroke order GIF: ${data.strokeOrderGifUri}'); + print('Jisho Uri: ${data.uri}'); + } }); } \ No newline at end of file diff --git a/example/api/phrase_scrape.dart b/example/api/phrase_scrape.dart index 6f475fd..7b86bdc 100644 --- a/example/api/phrase_scrape.dart +++ b/example/api/phrase_scrape.dart @@ -2,8 +2,8 @@ import 'dart:convert'; import 'package:unofficial_jisho_api/api.dart' as jisho; final JsonEncoder encoder = JsonEncoder.withIndent(' '); -void main() async { - await jisho.scrapeForPhrase('谷').then((data) { +void main() { + jisho.scrapeForPhrase('谷').then((data) { print(encoder.convert(data)); }); } \ No newline at end of file diff --git a/example/api/phrase_search.dart b/example/api/phrase_search.dart index 809e995..b1ae45f 100644 --- a/example/api/phrase_search.dart +++ b/example/api/phrase_search.dart @@ -2,8 +2,9 @@ import 'dart:convert'; import 'package:unofficial_jisho_api/api.dart' as jisho; final JsonEncoder encoder = JsonEncoder.withIndent(' '); -void main() async { - await jisho.searchForPhrase('日').then((result) { +void main() { + jisho.searchForPhrase('日').then((result) { + // jisho.searchForPhrase('する').then((result) { print(encoder.convert(result)); }); } \ No newline at end of file diff --git a/example/parser/parse_example_page.dart b/example/parser/parse_example_page.dart index 136c7e6..f13b19b 100644 --- a/example/parser/parse_example_page.dart +++ b/example/parser/parse_example_page.dart @@ -5,13 +5,14 @@ import 'package:unofficial_jisho_api/parser.dart' as jisho_parser; final JsonEncoder encoder = JsonEncoder.withIndent(' '); const String searchExample = '保護者'; -final String searchURI = jisho_parser.uriForExampleSearch(searchExample); +final Uri searchURI = jisho_parser.uriForExampleSearch(searchExample); -void main() async { - await http.get(searchURI).then((result) { - final parsedResult = jisho_parser.parseExamplePageData(result.body, searchExample); +void main() { + http.get(searchURI).then((result) { + final parsedResult = + jisho_parser.parseExamplePageData(result.body, searchExample); print('English: ${parsedResult.results[0].english}'); print('Kanji ${parsedResult.results[0].kanji}'); print('Kana: ${parsedResult.results[0].kana}'); }); -} \ No newline at end of file +} diff --git a/example/parser/parse_kanji_page.dart b/example/parser/parse_kanji_page.dart index 01a7e63..7a1e16b 100644 --- a/example/parser/parse_kanji_page.dart +++ b/example/parser/parse_kanji_page.dart @@ -5,13 +5,17 @@ import 'package:unofficial_jisho_api/parser.dart' as jisho_parser; final JsonEncoder encoder = JsonEncoder.withIndent(' '); const String searchKanji = '車'; -final String searchURI = jisho_parser.uriForKanjiSearch(searchKanji); +final Uri searchURI = jisho_parser.uriForKanjiSearch(searchKanji); -void main() async { - await http.get(searchURI).then((result) { - final parsedResult = jisho_parser.parseKanjiPageData(result.body, searchKanji); - print('JLPT level: ${parsedResult.jlptLevel}'); - print('Stroke count: ${parsedResult.strokeCount}'); - print('Meaning: ${parsedResult.meaning}'); +void main() { + http.get(searchURI).then((result) { + final parsedResult = + jisho_parser.parseKanjiPageData(result.body, searchKanji); + final data = parsedResult.data; + if (data != null) { + print('JLPT level: ${data.jlptLevel}'); + print('Stroke count: ${data.strokeCount}'); + print('Meaning: ${data.meaning}'); + } }); -} \ No newline at end of file +} diff --git a/example/parser/parse_phrase_page.dart b/example/parser/parse_phrase_page.dart index 2f71744..d8e36a1 100644 --- a/example/parser/parse_phrase_page.dart +++ b/example/parser/parse_phrase_page.dart @@ -5,12 +5,12 @@ import 'package:unofficial_jisho_api/parser.dart' as jisho_parser; final JsonEncoder encoder = JsonEncoder.withIndent(' '); const String searchExample = '保護者'; -final String searchURI = jisho_parser.uriForPhraseScrape(searchExample); +final Uri searchURI = jisho_parser.uriForPhraseScrape(searchExample); -void main() async { - - await http.get(searchURI).then((result) { - final parsedResult = jisho_parser.parsePhrasePageData(result.body, searchExample); +void main() { + http.get(searchURI).then((result) { + final parsedResult = + jisho_parser.parsePhrasePageData(result.body, searchExample); print(encoder.convert(parsedResult)); }); -} \ No newline at end of file +} diff --git a/lib/api.dart b/lib/api.dart index 68d8643..088e770 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -7,11 +7,11 @@ library unofficial_jisho_api; import 'dart:convert'; import 'package:http/http.dart' as http; -import './src/exampleSearch.dart'; -import './src/kanjiSearch.dart'; +import './src/example_search.dart'; +import './src/kanji_search.dart'; import './src/objects.dart'; -import './src/phraseScrape.dart'; -import './src/phraseSearch.dart'; +import './src/phrase_scrape.dart'; +import './src/phrase_search.dart'; export './src/objects.dart'; diff --git a/lib/parser.dart b/lib/parser.dart index ff099fe..bf53821 100644 --- a/lib/parser.dart +++ b/lib/parser.dart @@ -5,9 +5,8 @@ /// for providing HTML. library unofficial_jisho_parser; -export './src/exampleSearch.dart' - show uriForExampleSearch, parseExamplePageData; -export './src/kanjiSearch.dart' show uriForKanjiSearch, parseKanjiPageData; export './src/objects.dart'; -export './src/phraseScrape.dart' show uriForPhraseScrape, parsePhrasePageData; -export './src/phraseSearch.dart'; +export 'src/example_search.dart' show uriForExampleSearch, parseExamplePageData; +export 'src/kanji_search.dart' show uriForKanjiSearch, parseKanjiPageData; +export 'src/phrase_scrape.dart' show uriForPhraseScrape, parsePhrasePageData; +export 'src/phrase_search.dart'; diff --git a/lib/src/base_uri.dart b/lib/src/base_uri.dart index b1bd652..9e1ea69 100644 --- a/lib/src/base_uri.dart +++ b/lib/src/base_uri.dart @@ -1,4 +1,6 @@ -const String JISHO_API = 'https://jisho.org/api/v1/search/words'; -const String SCRAPE_BASE_URI = 'https://jisho.org/search/'; -const String STROKE_ORDER_DIAGRAM_BASE_URI = +// ignore_for_file: public_member_api_docs + +const String jishoApi = 'https://jisho.org/api/v1/search/words'; +const String scrapeBaseUri = 'https://jisho.org/search/'; +const String strokeOrderDiagramBaseUri = 'https://classic.jisho.org/static/images/stroke_diagrams/'; diff --git a/lib/src/exampleSearch.dart b/lib/src/example_search.dart similarity index 60% rename from lib/src/exampleSearch.dart rename to lib/src/example_search.dart index a6e552b..a860521 100644 --- a/lib/src/exampleSearch.dart +++ b/lib/src/example_search.dart @@ -1,14 +1,15 @@ -import 'package:html/parser.dart'; import 'package:html/dom.dart'; +import 'package:html/parser.dart'; import './base_uri.dart'; import './objects.dart'; +import './scraping.dart'; final RegExp _kanjiRegex = RegExp(r'[\u4e00-\u9faf\u3400-\u4dbf]'); /// Provides the URI for an example search -String uriForExampleSearch(String phrase) { - return '$SCRAPE_BASE_URI${Uri.encodeComponent(phrase)}%23sentences'; +Uri uriForExampleSearch(String phrase) { + return Uri.parse('$scrapeBaseUri${Uri.encodeComponent(phrase)}%23sentences'); } List _getChildrenAndSymbols(Element ul) { @@ -16,7 +17,7 @@ List _getChildrenAndSymbols(Element ul) { final ulCharArray = ulText.split(''); final ulChildren = ul.children; var offsetPointer = 0; - List result = []; + final result = []; for (var element in ulChildren) { if (element.text != @@ -40,8 +41,13 @@ List _getChildrenAndSymbols(Element ul) { return result; } -ExampleResultData _getKanjiAndKana(Element div) { - final ul = div.querySelector('ul'); +/// Although return type is List, it is to be interpreted as (String, String) +List _getKanjiAndKana(Element div) { + final ul = assertNotNull( + variable: div.querySelector('ul'), + errorMessage: + "Could not parse kanji/kana div. Is the provided document corrupt, or has Jisho been updated?", + ); final contents = _getChildrenAndSymbols(ul); var kanji = ''; @@ -51,7 +57,11 @@ ExampleResultData _getKanjiAndKana(Element div) { if (content.localName == 'li') { final li = content; final furigana = li.querySelector('.furigana')?.text; - final unlifted = li.querySelector('.unlinked')?.text; + final unlifted = assertNotNull( + variable: li.querySelector('.unlinked')?.text, + errorMessage: + "Could not parse a piece of the example sentence. Is the provided document corrupt, or has Jisho been updated?", + ); if (furigana != null) { kanji += unlifted; @@ -74,39 +84,49 @@ ExampleResultData _getKanjiAndKana(Element div) { } } else { final text = content.text.trim(); - if (text != null) { - kanji += text; - kana += text; - } + kanji += text; + kana += text; } } - return ExampleResultData( - kanji: kanji, - kana: kana, - ); + return [kanji, kana]; } List getPieces(Element sentenceElement) { final pieceElements = sentenceElement.querySelectorAll('li.clearfix'); - final List pieces = []; - for (var pieceIndex = 0; pieceIndex < pieceElements.length; pieceIndex += 1) { - final pieceElement = pieceElements[pieceIndex]; - pieces.add(ExampleSentencePiece( - lifted: pieceElement.querySelector('.furigana')?.text, - unlifted: pieceElement.querySelector('.unlinked')?.text, - )); - } - return pieces; + return pieceElements.map((var e) { + final unlifted = assertNotNull( + variable: e.querySelector('.unlinked')?.text, + errorMessage: + "Could not parse a piece of the example sentence. Is the provided document corrupt, or has Jisho been updated?", + ); + + return ExampleSentencePiece( + lifted: e.querySelector('.furigana')?.text, + unlifted: unlifted, + ); + }).toList(); } ExampleResultData _parseExampleDiv(Element div) { final result = _getKanjiAndKana(div); - result.english = div.querySelector('.english').text; - result.pieces = getPieces(div) ?? []; + final kanji = result[0]; + final kana = result[1]; - return result; + final english = assertNotNull( + variable: div.querySelector('.english')?.text, + errorMessage: + "Could not parse translation. Is the provided document corrupt, or has Jisho been updated?", + ); + final pieces = getPieces(div); + + return ExampleResultData( + english: english, + kanji: kanji, + kana: kana, + pieces: pieces, + ); } /// Parses a jisho example sentence search page to an object @@ -117,9 +137,8 @@ ExampleResults parseExamplePageData(String pageHtml, String phrase) { final results = divs.map(_parseExampleDiv).toList(); return ExampleResults( - query: phrase, - found: results.isNotEmpty, - results: results ?? [], - uri: uriForExampleSearch(phrase) - ); + query: phrase, + found: results.isNotEmpty, + results: results, + uri: uriForExampleSearch(phrase).toString()); } diff --git a/lib/src/kanjiSearch.dart b/lib/src/kanjiSearch.dart deleted file mode 100644 index 7f3d198..0000000 --- a/lib/src/kanjiSearch.dart +++ /dev/null @@ -1,235 +0,0 @@ -import 'package:html_unescape/html_unescape.dart' as html_entities; - -import './base_uri.dart'; -import './objects.dart'; - -final _htmlUnescape = html_entities.HtmlUnescape(); - -const _onyomiLocatorSymbol = 'On'; -const _kunyomiLocatorSymbol = 'Kun'; - -String _removeNewlines(String str) { - return str.replaceAll(RegExp(r'(?:\r|\n)'), '').trim(); -} - -/// Provides the URI for a kanji search -String uriForKanjiSearch(String kanji) { - return '$SCRAPE_BASE_URI${Uri.encodeComponent(kanji)}%23kanji'; -} - -String _getUriForStrokeOrderDiagram(String kanji) { - return '$STROKE_ORDER_DIAGRAM_BASE_URI${kanji.codeUnitAt(0)}_frames.png'; -} - -bool _containsKanjiGlyph(String pageHtml, String kanji) { - final kanjiGlyphToken = - '

$kanji

'; - return pageHtml.contains(kanjiGlyphToken); -} - -String _getStringBetweenIndicies(String data, int startIndex, int endIndex) { - final result = data.substring(startIndex, endIndex); - return _removeNewlines(result).trim(); -} - -String _getStringBetweenStrings( - String data, String startString, String endString) { - final regex = RegExp( - '${RegExp.escape(startString)}(.*?)${RegExp.escape(endString)}', - dotAll: true); - final match = regex.allMatches(data).toList(); - - return match.isNotEmpty ? match[0].group(1).toString() : null; -} - -int _getIntBetweenStrings( - String pageHtml, String startString, String endString) { - final stringBetweenStrings = - _getStringBetweenStrings(pageHtml, startString, endString); - return int.parse(stringBetweenStrings); -} - -List _getAllGlobalGroupMatches(String str, RegExp regex) { - var regexResults = regex.allMatches(str).toList(); - List results = []; - for (var match in regexResults) { - results.add(match.group(1)); - } - - return results; -} - -List _parseAnchorsToArray(String str) { - final regex = RegExp(r'(.*?)<\/a>'); - return _getAllGlobalGroupMatches(str, regex); -} - -List _getYomi(String pageHtml, String yomiLocatorSymbol) { - final yomiSection = _getStringBetweenStrings( - pageHtml, '
$yomiLocatorSymbol:
', ''); - return _parseAnchorsToArray(yomiSection ?? ''); -} - -List _getKunyomi(String pageHtml) { - return _getYomi(pageHtml, _kunyomiLocatorSymbol); -} - -List _getOnyomi(String pageHtml) { - return _getYomi(pageHtml, _onyomiLocatorSymbol); -} - -List _getYomiExamples(String pageHtml, String yomiLocatorSymbol) { - final locatorString = '

$yomiLocatorSymbol reading compounds

'; - final exampleSection = - _getStringBetweenStrings(pageHtml, locatorString, ''); - if (exampleSection == null) { - return null; - } - - final regex = RegExp(r'
  • (.*?)<\/li>', dotAll: true); - final regexResults = - _getAllGlobalGroupMatches(exampleSection, regex).map((s) => s.trim()); - - final examples = regexResults.map((regexResult) { - final examplesLines = regexResult.split('\n').map((s) => s.trim()).toList(); - return YomiExample( - example: examplesLines[0], - reading: examplesLines[1].replaceAll('【', '').replaceAll('】', ''), - meaning: _htmlUnescape.convert(examplesLines[2]), - ); - }); - - return examples.toList(); -} - -List _getOnyomiExamples(String pageHtml) { - return _getYomiExamples(pageHtml, _onyomiLocatorSymbol); -} - -List _getKunyomiExamples(String pageHtml) { - return _getYomiExamples(pageHtml, _kunyomiLocatorSymbol); -} - -Radical _getRadical(String pageHtml) { - const radicalMeaningStartString = ''; - const radicalMeaningEndString = ''; - - var radicalMeaning = _getStringBetweenStrings( - pageHtml, - radicalMeaningStartString, - radicalMeaningEndString, - ).trim(); - - if (radicalMeaning != null) { - final radicalMeaningStartIndex = - pageHtml.indexOf(radicalMeaningStartString); - - final radicalMeaningEndIndex = pageHtml.indexOf( - radicalMeaningEndString, - radicalMeaningStartIndex, - ); - - final radicalSymbolStartIndex = - radicalMeaningEndIndex + radicalMeaningEndString.length; - const radicalSymbolEndString = ''; - final radicalSymbolEndIndex = - pageHtml.indexOf(radicalSymbolEndString, radicalSymbolStartIndex); - - final radicalSymbolsString = _getStringBetweenIndicies( - pageHtml, - radicalSymbolStartIndex, - radicalSymbolEndIndex, - ); - - if (radicalSymbolsString.length > 1) { - final radicalForms = radicalSymbolsString - .substring(1) - .replaceAll('(', '') - .replaceAll(')', '') - .trim() - .split(', '); - - return Radical( - symbol: radicalSymbolsString[0], - forms: radicalForms ?? [], - meaning: radicalMeaning); - } - - return Radical(symbol: radicalSymbolsString, meaning: radicalMeaning); - } - - return null; -} - -List _getParts(String pageHtml) { - const partsSectionStartString = '
    Parts:
    '; - const partsSectionEndString = ''; - - final partsSection = _getStringBetweenStrings( - pageHtml, - partsSectionStartString, - partsSectionEndString, - ); - - var result = _parseAnchorsToArray(partsSection); - result.sort(); - - return (result); -} - -String _getSvgUri(String pageHtml) { - var svgRegex = RegExp('\/\/.*?.cloudfront.net\/.*?.svg'); - final regexResult = svgRegex.firstMatch(pageHtml).group(0).toString(); - return regexResult.isNotEmpty ? 'https:$regexResult' : null; -} - -String _getGifUri(String kanji) { - final unicodeString = kanji.codeUnitAt(0).toRadixString(16); - final fileName = '$unicodeString.gif'; - final animationUri = - 'https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/$fileName'; - - return animationUri; -} - -int _getNewspaperFrequencyRank(String pageHtml) { - final frequencySection = - _getStringBetweenStrings(pageHtml, '
    ', '
    '); - return (frequencySection != null) - ? int.parse( - _getStringBetweenStrings(frequencySection, '', '')) - : null; -} - -/// Parses a jisho kanji search page to an object -KanjiResult parseKanjiPageData(String pageHtml, String kanji) { - final result = KanjiResult(); - result.query = kanji; - result.found = _containsKanjiGlyph(pageHtml, kanji); - if (result.found == false) { - return result; - } - - result.taughtIn = - _getStringBetweenStrings(pageHtml, 'taught in ', ''); - result.jlptLevel = - _getStringBetweenStrings(pageHtml, 'JLPT level ', ''); - result.newspaperFrequencyRank = _getNewspaperFrequencyRank(pageHtml); - result.strokeCount = - _getIntBetweenStrings(pageHtml, '', ' strokes'); - result.meaning = _htmlUnescape.convert(_removeNewlines( - _getStringBetweenStrings( - pageHtml, '
    ', '
    ')) - .trim()); - result.kunyomi = _getKunyomi(pageHtml) ?? []; - result.onyomi = _getOnyomi(pageHtml) ?? []; - result.onyomiExamples = _getOnyomiExamples(pageHtml) ?? []; - result.kunyomiExamples = _getKunyomiExamples(pageHtml) ?? []; - result.radical = _getRadical(pageHtml); - result.parts = _getParts(pageHtml) ?? []; - result.strokeOrderDiagramUri = _getUriForStrokeOrderDiagram(kanji); - result.strokeOrderSvgUri = _getSvgUri(pageHtml); - result.strokeOrderGifUri = _getGifUri(kanji); - result.uri = uriForKanjiSearch(kanji); - return result; -} diff --git a/lib/src/kanji_search.dart b/lib/src/kanji_search.dart new file mode 100644 index 0000000..2466966 --- /dev/null +++ b/lib/src/kanji_search.dart @@ -0,0 +1,243 @@ +import 'package:html_unescape/html_unescape.dart' as html_entities; + +import './base_uri.dart'; +import './objects.dart'; +import './scraping.dart'; + +final _htmlUnescape = html_entities.HtmlUnescape(); + +const _onyomiLocatorSymbol = 'On'; +const _kunyomiLocatorSymbol = 'Kun'; + +/// Provides the URI for a kanji search +Uri uriForKanjiSearch(String kanji) { + return Uri.parse('$scrapeBaseUri${Uri.encodeComponent(kanji)}%23kanji'); +} + +String _getUriForStrokeOrderDiagram(String kanji) { + return '$strokeOrderDiagramBaseUri${kanji.codeUnitAt(0)}_frames.png'; +} + +bool _containsKanjiGlyph(String pageHtml, String kanji) { + final kanjiGlyphToken = + '

    $kanji

    '; + return pageHtml.contains(kanjiGlyphToken); +} + +List _getYomi(String pageHtml, String yomiLocatorSymbol) { + final yomiSection = getStringBetweenStrings( + pageHtml, '
    $yomiLocatorSymbol:
    ', ''); + return parseAnchorsToArray(yomiSection ?? ''); +} + +List _getKunyomi(String pageHtml) { + return _getYomi(pageHtml, _kunyomiLocatorSymbol); +} + +List _getOnyomi(String pageHtml) { + return _getYomi(pageHtml, _onyomiLocatorSymbol); +} + +List _getYomiExamples(String pageHtml, String yomiLocatorSymbol) { + final locatorString = '

    $yomiLocatorSymbol reading compounds

    '; + final exampleSection = + getStringBetweenStrings(pageHtml, locatorString, ''); + if (exampleSection == null) { + return []; + } + + final regex = RegExp(r'
  • (.*?)<\/li>', dotAll: true); + final regexResults = + getAllGlobalGroupMatches(exampleSection, regex).map((s) => s.trim()); + + final examples = regexResults.map((regexResult) { + final examplesLines = regexResult.split('\n').map((s) => s.trim()).toList(); + return YomiExample( + example: examplesLines[0], + reading: examplesLines[1].replaceAll('【', '').replaceAll('】', ''), + meaning: _htmlUnescape.convert(examplesLines[2]), + ); + }); + + return examples.toList(); +} + +List _getOnyomiExamples(String pageHtml) { + return _getYomiExamples(pageHtml, _onyomiLocatorSymbol); +} + +List _getKunyomiExamples(String pageHtml) { + return _getYomiExamples(pageHtml, _kunyomiLocatorSymbol); +} + +Radical? _getRadical(String pageHtml) { + const radicalMeaningStartString = ''; + const radicalMeaningEndString = ''; + + var radicalMeaning = getStringBetweenStrings( + pageHtml, + radicalMeaningStartString, + radicalMeaningEndString, + )?.trim(); + + if (radicalMeaning == null) { + return null; + } + + final radicalMeaningStartIndex = pageHtml.indexOf(radicalMeaningStartString); + + final radicalMeaningEndIndex = pageHtml.indexOf( + radicalMeaningEndString, + radicalMeaningStartIndex, + ); + + final radicalSymbolStartIndex = + radicalMeaningEndIndex + radicalMeaningEndString.length; + const radicalSymbolEndString = ''; + final radicalSymbolEndIndex = + pageHtml.indexOf(radicalSymbolEndString, radicalSymbolStartIndex); + + final radicalSymbolsString = getStringBetweenIndicies( + pageHtml, + radicalSymbolStartIndex, + radicalSymbolEndIndex, + ); + + if (radicalSymbolsString.length > 1) { + final radicalForms = radicalSymbolsString + .substring(1) + .replaceAll('(', '') + .replaceAll(')', '') + .trim() + .split(', '); + + return Radical( + symbol: radicalSymbolsString[0], + forms: radicalForms, + meaning: radicalMeaning, + ); + } + + return Radical(symbol: radicalSymbolsString, meaning: radicalMeaning); +} + +String _getMeaning(String pageHtml) { + final rawMeaning = assertNotNull( + variable: getStringBetweenStrings( + pageHtml, + '
    ', + '
    ', + ), + errorMessage: + "Could not parse meaning. Is the provided document corrupt, or has Jisho been updated?", + ); + + return _htmlUnescape.convert(removeNewlines(rawMeaning).trim()); +} + +List _getParts(String pageHtml) { + const partsSectionStartString = '
    Parts:
    '; + const partsSectionEndString = ''; + + final partsSection = getStringBetweenStrings( + pageHtml, + partsSectionStartString, + partsSectionEndString, + ); + + if (partsSection == null) { + return []; + } + + var result = parseAnchorsToArray(partsSection); + result.sort(); + + return result; +} + +String _getSvgUri(String pageHtml) { + var svgRegex = RegExp('\/\/.*?.cloudfront.net\/.*?.svg'); + + final regexResult = assertNotNull( + variable: svgRegex.firstMatch(pageHtml)?.group(0)?.toString(), + errorMessage: + "Could not find SVG URI. Is the provided document corrupt, or has Jisho been updated?", + ); + + return 'https:$regexResult'; +} + +String _getGifUri(String kanji) { + final unicodeString = kanji.codeUnitAt(0).toRadixString(16); + final fileName = '$unicodeString.gif'; + final animationUri = + 'https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/$fileName'; + + return animationUri; +} + +int? _getNewspaperFrequencyRank(String pageHtml) { + final frequencySection = getStringBetweenStrings( + pageHtml, + '
    ', + '
    ', + ); + + // ignore: avoid_returning_null + if (frequencySection == null) return null; + + final frequencyRank = + getStringBetweenStrings(frequencySection, '', ''); + + return frequencyRank != null ? int.parse(frequencyRank) : null; +} + +int _getStrokeCount(String pageHtml) { + final strokeCount = assertNotNull( + variable: getIntBetweenStrings(pageHtml, '', ' strokes'), + errorMessage: + "Could not parse stroke count. Is the provided document corrupt, or has Jisho been updated?", + ); + + return strokeCount; +} + +String? _getTaughtIn(String pageHtml) { + return getStringBetweenStrings(pageHtml, 'taught in ', ''); +} + +String? _getJlptLevel(String pageHtml) { + return getStringBetweenStrings(pageHtml, 'JLPT level ', ''); +} + +/// Parses a jisho kanji search page to an object +KanjiResult parseKanjiPageData(String pageHtml, String kanji) { + final result = KanjiResult( + query: kanji, + found: _containsKanjiGlyph(pageHtml, kanji), + ); + + if (result.found == false) { + return result; + } + + result.data = KanjiResultData( + strokeCount: _getStrokeCount(pageHtml), + meaning: _getMeaning(pageHtml), + strokeOrderDiagramUri: _getUriForStrokeOrderDiagram(kanji), + strokeOrderSvgUri: _getSvgUri(pageHtml), + strokeOrderGifUri: _getGifUri(kanji), + uri: uriForKanjiSearch(kanji).toString(), + parts: _getParts(pageHtml), + taughtIn: _getTaughtIn(pageHtml), + jlptLevel: _getJlptLevel(pageHtml), + newspaperFrequencyRank: _getNewspaperFrequencyRank(pageHtml), + kunyomi: _getKunyomi(pageHtml), + onyomi: _getOnyomi(pageHtml), + kunyomiExamples: _getKunyomiExamples(pageHtml), + onyomiExamples: _getOnyomiExamples(pageHtml), + radical: _getRadical(pageHtml), + ); + + return result; +} diff --git a/lib/src/objects.dart b/lib/src/objects.dart index e3d6109..2b0943f 100644 --- a/lib/src/objects.dart +++ b/lib/src/objects.dart @@ -2,96 +2,157 @@ /* searchForKanji related classes */ /* -------------------------------------------------------------------------- */ +/// An example of a word that contains the kanji in question. class YomiExample { /// The original text of the example. String example; + /// The reading of the example. String reading; + /// The meaning of the example. String meaning; - YomiExample({this.example, this.reading, this.meaning}); + // ignore: public_member_api_docs + YomiExample({ + required this.example, + required this.reading, + required this.meaning, + }); - Map toJson() => - {'example': example, 'reading': reading, 'meaning': meaning}; + // ignore: public_member_api_docs + Map toJson() => { + 'example': example, + 'reading': reading, + 'meaning': meaning, + }; } +/// Information regarding the radical of a kanji. class Radical { - /// The radical symbol, if applicable. + /// The radical symbol. String symbol; - /// The radical forms used in this kanji, if applicable. + + /// The radical forms used in this kanji. List forms; - /// The meaning of the radical, if applicable. + + /// The meaning of the radical. String meaning; - Radical({this.symbol, this.forms, this.meaning}); + // ignore: public_member_api_docs + Radical({ + required this.symbol, + this.forms = const [], + required this.meaning, + }); - Map toJson() => - {'symbol': symbol, 'forms': forms, 'meaning': meaning}; + // ignore: public_member_api_docs + Map toJson() => { + 'symbol': symbol, + 'forms': forms, + 'meaning': meaning, + }; } +/// The main wrapper containing data about the query and whether or not it was successful. class KanjiResult { /// True if results were found. String query; + /// The term that you searched for. bool found; - /// The school level that the kanji is taught in, if applicable. - String taughtIn; - /// The lowest JLPT exam that this kanji is likely to appear in, if applicable. - /// - /// 'N5' or 'N4' or 'N3' or 'N2' or 'N1'. - String jlptLevel; - /// A number representing this kanji's frequency rank in newspapers, if applicable. - int newspaperFrequencyRank; - /// How many strokes this kanji is typically drawn in, if applicable. - int strokeCount; - /// The meaning of the kanji, if applicable. - String meaning; - /// This character's kunyomi, if applicable. - List kunyomi; - /// This character's onyomi, if applicable. - List onyomi; - /// Examples of this character's kunyomi being used, if applicable. - List kunyomiExamples; - /// Examples of this character's onyomi being used, if applicable. - List onyomiExamples; - /// Information about this character's radical, if applicable. - Radical radical; - /// The parts used in this kanji, if applicable. - List parts; - /// The URL to a diagram showing how to draw this kanji step by step, if applicable. - String strokeOrderDiagramUri; - /// The URL to an SVG describing how to draw this kanji, if applicable. - String strokeOrderSvgUri; - /// The URL to a gif showing the kanji being draw and its stroke order, if applicable. - String strokeOrderGifUri; - /// The URI that these results were scraped from, if applicable. - String uri; + /// The result data if search was successful. + KanjiResultData? data; - KanjiResult( - {this.query, - this.found, - this.taughtIn, - this.jlptLevel, - this.newspaperFrequencyRank, - this.strokeCount, - this.meaning, - this.kunyomi, - this.onyomi, - this.kunyomiExamples, - this.onyomiExamples, - this.radical, - this.parts, - this.strokeOrderDiagramUri, - this.strokeOrderSvgUri, - this.strokeOrderGifUri, - this.uri}); + // ignore: public_member_api_docs + KanjiResult({ + required this.query, + required this.found, + this.data, + }); + // ignore: public_member_api_docs Map toJson() { return { 'query': query, 'found': found, + 'data': data, + }; + } +} + +/// The main kanji data class, collecting all the result information in one place. +class KanjiResultData { + /// The school level that the kanji is taught in, if applicable. + String? taughtIn; + + /// The lowest JLPT exam that this kanji is likely to appear in, if applicable. + /// + /// 'N5' or 'N4' or 'N3' or 'N2' or 'N1'. + String? jlptLevel; + + /// A number representing this kanji's frequency rank in newspapers, if applicable. + int? newspaperFrequencyRank; + + /// How many strokes this kanji is typically drawn in. + int strokeCount; + + /// The meaning of the kanji. + String meaning; + + /// This character's kunyomi. + List kunyomi; + + /// This character's onyomi. + List onyomi; + + /// Examples of this character's kunyomi being used. + List kunyomiExamples; + + /// Examples of this character's onyomi being used. + List onyomiExamples; + + /// Information about this character's radical, if applicable. + Radical? radical; + + /// The parts used in this kanji. + List parts; + + /// The URL to a diagram showing how to draw this kanji step by step. + String strokeOrderDiagramUri; + + /// The URL to an SVG describing how to draw this kanji. + String strokeOrderSvgUri; + + /// The URL to a gif showing the kanji being draw and its stroke order. + String strokeOrderGifUri; + + /// The URI that these results were scraped from. + String uri; + + // ignore: public_member_api_docs + KanjiResultData({ + this.taughtIn, + this.jlptLevel, + this.newspaperFrequencyRank, + required this.strokeCount, + required this.meaning, + this.kunyomi = const [], + this.onyomi = const [], + this.kunyomiExamples = const [], + this.onyomiExamples = const [], + this.radical, + this.parts = const [], + required this.strokeOrderDiagramUri, + required this.strokeOrderSvgUri, + required this.strokeOrderGifUri, + required this.uri, + }); + + // ignore: public_member_api_docs + Map toJson() { + return { 'taughtIn': taughtIn, 'jlptLevel': jlptLevel, 'newspaperFrequencyRank': newspaperFrequencyRank, @@ -101,12 +162,12 @@ class KanjiResult { 'onyomi': onyomi, 'onyomiExamples': onyomiExamples, 'kunyomiExamples': kunyomiExamples, - 'radical': (radical != null) ? radical.toJson() : null, + 'radical': radical?.toJson(), 'parts': parts, 'strokeOrderDiagramUri': strokeOrderDiagramUri, 'strokeOrderSvgUri': strokeOrderSvgUri, 'strokeOrderGifUri': strokeOrderGifUri, - 'uri': uri + 'uri': uri, }; } } @@ -115,54 +176,90 @@ class KanjiResult { /* searchForExamples related classes */ /* -------------------------------------------------------------------------- */ +/// A word in an example sentence, consisting of either just kana, or kanji with furigana. class ExampleSentencePiece { - /// Baseline text shown on Jisho.org (below the lifted text / furigana) - String lifted; - /// Furigana text shown on Jisho.org (above the unlifted text) + /// Furigana text shown on Jisho.org (above the unlifted text), if applicable. + String? lifted; + + /// Baseline text shown on Jisho.org (below the lifted text / furigana). String unlifted; - ExampleSentencePiece({this.lifted, this.unlifted}); + // ignore: public_member_api_docs + ExampleSentencePiece({ + this.lifted, + required this.unlifted, + }); + // ignore: public_member_api_docs Map toJson() { - return {'lifted': lifted, 'unlifted': unlifted}; + return { + 'lifted': lifted, + 'unlifted': unlifted, + }; } } +/// All data making up one example sentence. class ExampleResultData { /// The example sentence including kanji. String kanji; + /// The example sentence without kanji (only kana). Sometimes this may include some Kanji, as furigana is not always available from Jisho.org. String kana; + /// An English translation of the example. String english; + /// The lifted/unlifted pairs that make up the sentence. Lifted text is furigana, unlifted is the text below the furigana. List pieces; - ExampleResultData({this.english, this.kanji, this.kana, this.pieces}); + // ignore: public_member_api_docs + ExampleResultData({ + required this.english, + required this.kanji, + required this.kana, + required this.pieces, + }); + // ignore: public_member_api_docs Map toJson() { - return {'english': english, 'kanji': kanji, 'kana': kana, 'pieces': pieces}; + return { + 'english': english, + 'kanji': kanji, + 'kana': kana, + 'pieces': pieces, + }; } } - +/// The main wrapper containing data about the query and whether or not it was successful. class ExampleResults { /// The term that you searched for. String query; + /// True if results were found. bool found; + /// The URI that these results were scraped from. String uri; + /// The examples that were found, if any. List results; - ExampleResults({this.query, this.found, this.results, this.uri}); + // ignore: public_member_api_docs + ExampleResults({ + required this.query, + required this.found, + required this.results, + required this.uri, + }); + // ignore: public_member_api_docs Map toJson() { return { 'query': query, 'found': found, 'results': results, - 'uri': uri + 'uri': uri, }; } } @@ -171,96 +268,178 @@ class ExampleResults { /* scrapeForPhrase related classes */ /* -------------------------------------------------------------------------- */ +/// An example sentence. class PhraseScrapeSentence { /// The English meaning of the sentence. String english; + /// The Japanese text of the sentence. String japanese; + /// The lifted/unlifted pairs that make up the sentence. Lifted text is furigana, unlifted is the text below the furigana. List pieces; - PhraseScrapeSentence({this.english, this.japanese, this.pieces}); + // ignore: public_member_api_docs + PhraseScrapeSentence({ + required this.english, + required this.japanese, + required this.pieces, + }); + // ignore: public_member_api_docs Map toJson() => {'english': english, 'japanese': japanese, 'pieces': pieces}; } +/// The data representing one "meaning" or "sense" of the word class PhraseScrapeMeaning { /// The words that Jisho lists as "see also". List seeAlsoTerms; + /// Example sentences for this meaning. List sentences; - /// The definition of the meaning + + /// The definition of the meaning. String definition; + /// Supplemental information. /// For example "usually written using kana alone". List supplemental; + /// An "abstract" definition. /// Often this is a Wikipedia definition. - String definitionAbstract; + String? definitionAbstract; + /// Tags associated with this meaning. List tags; - PhraseScrapeMeaning( - {this.seeAlsoTerms, - this.sentences, - this.definition, - this.supplemental, - this.definitionAbstract, - this.tags}); + // ignore: public_member_api_docs + PhraseScrapeMeaning({ + this.seeAlsoTerms = const [], + required this.sentences, + required this.definition, + this.supplemental = const [], + this.definitionAbstract, + this.tags = const [], + }); + // ignore: public_member_api_docs Map toJson() => { 'seeAlsoTerms': seeAlsoTerms, 'sentences': sentences, 'definition': definition, 'supplemental': supplemental, 'definitionAbstract': definitionAbstract, - 'tags': tags + 'tags': tags, }; } +/// A pair of kanji and potential furigana. class KanjiKanaPair { + /// Kanji String kanji; - String kana; - KanjiKanaPair({this.kanji, this.kana}); + /// Furigana, if applicable. + String? kana; - Map toJson() => {'kanji': kanji, 'kana': kana}; + // ignore: public_member_api_docs + KanjiKanaPair({ + required this.kanji, + this.kana, + }); + + // ignore: public_member_api_docs + Map toJson() => { + 'kanji': kanji, + 'kana': kana, + }; } +/// The main wrapper containing data about the query and whether or not it was successful. class PhrasePageScrapeResult { /// True if a result was found. bool found; + /// The term that you searched for. String query; - /// The URI that these results were scraped from, if a result was found. - String uri; - /// Other forms of the search term, if a result was found. - List tags; - /// Information about the meanings associated with this search result. - List meanings; - /// Tags associated with this search result. - List otherForms; - /// Notes associated with the search result. - List notes; - PhrasePageScrapeResult( - {this.found, - this.query, - this.uri, - this.tags, - this.meanings, - this.otherForms, - this.notes}); + /// The result data if search was successful. + PhrasePageScrapeResultData? data; + // ignore: public_member_api_docs + PhrasePageScrapeResult({ + required this.found, + required this.query, + this.data, + }); + + // ignore: public_member_api_docs Map toJson() => { 'found': found, 'query': query, + 'data': data, + }; +} + +/// Pronounciation audio. +class AudioFile { + /// The uri of the audio file. + String uri; + + /// The mimetype of the audio. + String mimetype; + + // ignore: public_member_api_docs + AudioFile({ + required this.uri, + required this.mimetype, + }); + + // ignore: public_member_api_docs + Map toJson() => { + 'uri': uri, + 'mimetype': mimetype, + }; +} + +/// The main scrape data class, collecting all the result information in one place. +class PhrasePageScrapeResultData { + /// The URI that these results were scraped from. + String uri; + + /// Other forms of the search term. + List tags; + + /// Information about the meanings associated with this search result. + List meanings; + + /// Tags associated with this search result. + List otherForms; + +/// Pronounciation of the search result. + List audio; + + /// Notes associated with the search result. + List notes; + + // ignore: public_member_api_docs + PhrasePageScrapeResultData({ + required this.uri, + this.tags = const [], + this.meanings = const [], + this.otherForms = const [], + this.audio = const [], + this.notes = const [], + }); + + // ignore: public_member_api_docs + Map toJson() => { 'uri': uri, 'tags': tags, 'meanings': meanings, 'otherForms': otherForms, - 'notes': notes + 'audio': audio, + 'notes': notes, }; } @@ -268,85 +447,157 @@ class PhrasePageScrapeResult { /* searchForPhrase related classes */ /* -------------------------------------------------------------------------- */ +/// Kanji/Furigana pair, or just kana as word. +/// +/// Which field acts as kanji and/or kana might be unreliable, which is why both are nullable. class JishoJapaneseWord { - String word; - String reading; + /// Usually kanji or kana. + String? word; - JishoJapaneseWord({this.word, this.reading}); + /// Usually furigana, if applicable. + String? reading; + // ignore: public_member_api_docs + JishoJapaneseWord({ + this.word, + this.reading, + }); + + // ignore: public_member_api_docs factory JishoJapaneseWord.fromJson(Map json) { return JishoJapaneseWord( - word: json['word'] as String, reading: json['reading'] as String); + word: json['word'] as String?, + reading: json['reading'] as String?, + ); } - Map toJson() => {'word': word, 'reading': reading}; + // ignore: public_member_api_docs + Map toJson() => { + 'word': word, + 'reading': reading, + }; } +/// Relevant links of the search result. class JishoSenseLink { + /// Description of the linked webpage. String text; + + /// Link to the webpage. String url; - JishoSenseLink({this.text, this.url}); + // ignore: public_member_api_docs + JishoSenseLink({required this.text, required this.url}); + // ignore: public_member_api_docs factory JishoSenseLink.fromJson(Map json) { return JishoSenseLink( - text: json['text'] as String, url: json['url'] as String); + text: json['text'] as String, + url: json['url'] as String, + ); } - Map toJson() => {'text': text, 'url': url}; + // ignore: public_member_api_docs + Map toJson() => { + 'text': text, + 'url': url, + }; } +/// Origin of the word (from other languages). +class JishoWordSource { + /// Origin language. + String language; + + /// Origin word, if present. + String? word; + + // ignore: public_member_api_docs + JishoWordSource({ + required this.language, + this.word, + }); + + // ignore: public_member_api_docs + Map toJson() => { + 'language:': language, + 'word': word, + }; +} + +/// One sense of the word. class JishoWordSense { - List english_definitions; - List parts_of_speech; + /// The meaning(s) of the word. + List englishDefinitions; + + /// Type of word (Noun, Verb, etc.). + List partsOfSpeech; + + /// Relevant links. List links; + + /// Relevant tags. List tags; - List see_also; + + /// Relevant words (might include synonyms). + List seeAlso; + + /// Words with opposite meaning. List antonyms; - List source; + + /// Origins of the word (from other languages). + List source; + + /// Additional info. List info; - List restrictions; - JishoWordSense( - {this.english_definitions, - this.parts_of_speech, - this.links, - this.tags, - this.see_also, - this.antonyms, - this.source, - this.info, - this.restrictions}); + /// Restrictions as to which variants of the japanese words are usable for this sense. + List restrictions; + // ignore: public_member_api_docs + JishoWordSense({ + required this.englishDefinitions, + required this.partsOfSpeech, + this.links = const [], + this.tags = const [], + this.seeAlso = const [], + this.antonyms = const [], + this.source = const [], + this.info = const [], + this.restrictions = const [], + }); + + // ignore: public_member_api_docs factory JishoWordSense.fromJson(Map json) { return JishoWordSense( - english_definitions: (json['english_definitions'] as List) + englishDefinitions: (json['english_definitions'] as List) .map((result) => result as String) .toList(), - parts_of_speech: (json['parts_of_speech'] as List) + partsOfSpeech: (json['parts_of_speech'] as List) .map((result) => result as String) .toList(), links: (json['links'] as List) .map((result) => JishoSenseLink.fromJson(result)) .toList(), tags: (json['tags'] as List).map((result) => result as String).toList(), - see_also: (json['see_also'] as List) + seeAlso: (json['see_also'] as List) .map((result) => result as String) .toList(), antonyms: (json['antonyms'] as List) .map((result) => result as String) .toList(), - source: json['source'] as List, + source: json['source'] as List, info: (json['info'] as List).map((result) => result as String).toList(), - restrictions: json['restrictions'] as List); + restrictions: json['restrictions'] as List); } + // ignore: public_member_api_docs Map toJson() => { - 'english_definitions': english_definitions, - 'parts_of_speech': parts_of_speech, + 'english_definitions': englishDefinitions, + 'parts_of_speech': partsOfSpeech, 'links': links, 'tags': tags, - 'see_also': see_also, + 'see_also': seeAlso, 'antonyms': antonyms, 'source': source, 'info': info, @@ -354,88 +605,143 @@ class JishoWordSense { }; } +/// The original source(s) of the result. class JishoAttribution { + /// Whether jmdict was a source. bool jmdict; + + /// Whether jmnedict was a source. bool jmnedict; - String dbpedia; - JishoAttribution({this.jmdict, this.jmnedict, this.dbpedia}); + /// Additional sources, if applicable. + String? dbpedia; + // ignore: public_member_api_docs + JishoAttribution({ + required this.jmdict, + required this.jmnedict, + this.dbpedia, + }); + + // ignore: public_member_api_docs factory JishoAttribution.fromJson(Map json) { return JishoAttribution( - jmdict: (json['jmdict'].toString() == 'true'), - jmnedict: (json['jmnedict'].toString() == 'true'), - dbpedia: (json['dbpedia'].toString() != 'false') - ? json['dbpedia'].toString() - : null); + jmdict: (json['jmdict'].toString() == 'true'), + jmnedict: (json['jmnedict'].toString() == 'true'), + dbpedia: (json['dbpedia'].toString() != 'false') + ? json['dbpedia'].toString() + : null, + ); } - Map toJson() => - {'jmdict': jmdict, 'jmnedict': jmnedict, 'dbpedia': dbpedia}; + // ignore: public_member_api_docs + Map toJson() => { + 'jmdict': jmdict, + 'jmnedict': jmnedict, + 'dbpedia': dbpedia, + }; } +/// The main API data class, collecting all information of one result in one place. class JishoResult { + /// The main version of the word + /// + /// This value might sometimes appear as some kind of hash or encoded version of the word. + /// Whenever it happens, the word usually originates taken from dbpedia String slug; - bool is_common; + + /// Whether the word is common. + /// + /// Dbpedia sometimes omit this value. + bool? isCommon; + + /// Related tags. List tags; + + /// Relevant jlpt levels. List jlpt; + + /// Japanese versions of the word. List japanese; + + /// Translations of the word. List senses; + + /// Sources. JishoAttribution attribution; - JishoResult( - {this.slug, - this.is_common, - this.tags, - this.jlpt, - this.japanese, - this.senses, - this.attribution}); + // ignore: public_member_api_docs + JishoResult({ + required this.slug, + required this.isCommon, + this.tags = const [], + this.jlpt = const [], + required this.japanese, + required this.senses, + required this.attribution, + }); + // ignore: public_member_api_docs factory JishoResult.fromJson(Map json) { return JishoResult( - slug: json['slug'] as String, - is_common: json['is_common'] as bool, - tags: (json['tags'] as List).map((result) => result as String).toList(), - jlpt: (json['jlpt'] as List).map((result) => result as String).toList(), - japanese: (json['japanese'] as List) - .map((result) => JishoJapaneseWord.fromJson(result)) - .toList(), - senses: (json['senses'] as List) - .map((result) => JishoWordSense.fromJson(result)) - .toList(), - attribution: JishoAttribution.fromJson(json['attribution'])); + slug: json['slug'] as String, + isCommon: json['is_common'] as bool?, + tags: (json['tags'] as List).map((result) => result as String).toList(), + jlpt: (json['jlpt'] as List).map((result) => result as String).toList(), + japanese: (json['japanese'] as List) + .map((result) => JishoJapaneseWord.fromJson(result)) + .toList(), + senses: (json['senses'] as List) + .map((result) => JishoWordSense.fromJson(result)) + .toList(), + attribution: JishoAttribution.fromJson(json['attribution']), + ); } + // ignore: public_member_api_docs Map toJson() => { 'slug': slug, - 'is_common': is_common, + 'is_common': isCommon, 'tags': tags, 'jlpt': jlpt, 'japanese': japanese, 'senses': senses, - 'attribution': attribution + 'attribution': attribution, }; } + /// Metadata with result status. class JishoResultMeta { + /// HTTP status code. int status; - JishoResultMeta({this.status}); + // ignore: public_member_api_docs + JishoResultMeta({required this.status}); + // ignore: public_member_api_docs factory JishoResultMeta.fromJson(Map json) { return JishoResultMeta(status: json['status'] as int); } + // ignore: public_member_api_docs Map toJson() => {'status': status}; } +/// The main API result wrapper containing whether it was successful, and potential results. class JishoAPIResult { + /// Metadata with result status. JishoResultMeta meta; - List data; - JishoAPIResult({this.meta, this.data}); + /// Results. + List? data; + // ignore: public_member_api_docs + JishoAPIResult({ + required this.meta, + this.data, + }); + + // ignore: public_member_api_docs factory JishoAPIResult.fromJson(Map json) { return JishoAPIResult( meta: JishoResultMeta.fromJson(json['meta']), @@ -444,5 +750,6 @@ class JishoAPIResult { .toList()); } + // ignore: public_member_api_docs Map toJson() => {'meta': meta.toJson(), 'data': data}; } diff --git a/lib/src/phraseScrape.dart b/lib/src/phraseScrape.dart deleted file mode 100644 index 85df29b..0000000 --- a/lib/src/phraseScrape.dart +++ /dev/null @@ -1,157 +0,0 @@ -import 'package:html/parser.dart'; -import 'package:html/dom.dart'; - -import './exampleSearch.dart' show getPieces; -import './objects.dart'; - -List _getTags(Document document) { - final List tags = []; - final tagElements = document.querySelectorAll('.concept_light-tag'); - - for (var i = 0; i < tagElements.length; i += 1) { - final tagText = tagElements[i].text; - tags.add(tagText); - } - - return tags; -} - -List _getMostRecentWordTypes(Element child) { - return child.text.split(',').map((s) => s.trim().toLowerCase()).toList(); -} - -List _getOtherForms(Element child) { - return child.text - .split('、') - .map((s) => s.replaceAll('【', '').replaceAll('】', '').split(' ')) - .map((a) => - (KanjiKanaPair(kanji: a[0], kana: (a.length == 2) ? a[1] : null))) - .toList(); -} - -List _getNotes(Element child) => child.text.split('\n'); - -String _getMeaning(Element child) => - child.querySelector('.meaning-meaning').text; - -String _getMeaningAbstract(Element child) { - final meaningAbstract = child.querySelector('.meaning-abstract'); - if (meaningAbstract == null) return null; - - for (var element in meaningAbstract.querySelectorAll('a')) { - element.remove(); - } - - return child.querySelector('.meaning-abstract')?.text; -} - -List _getSupplemental(Element child) { - final supplemental = child.querySelector('.supplemental_info'); - if (supplemental == null) return []; - return supplemental.text.split(',').map((s) => s.trim()).toList(); -} - -List _getSeeAlsoTerms(List supplemental) { - if (supplemental == null) return []; - - final List seeAlsoTerms = []; - for (var i = supplemental.length - 1; i >= 0; i -= 1) { - final supplementalEntry = supplemental[i]; - if (supplementalEntry.startsWith('See also')) { - seeAlsoTerms.add(supplementalEntry.replaceAll('See also ', '')); - supplemental.removeAt(i); - } - } - return seeAlsoTerms; -} - -List _getSentences(Element child) { - final sentenceElements = - child.querySelector('.sentences')?.querySelectorAll('.sentence'); - if (sentenceElements == null) return []; - - final List sentences = []; - for (var sentenceIndex = 0; - sentenceIndex < (sentenceElements?.length ?? 0); - sentenceIndex += 1) { - final sentenceElement = sentenceElements[sentenceIndex]; - - final english = sentenceElement.querySelector('.english').text; - final pieces = getPieces(sentenceElement); - - sentenceElement.querySelector('.english').remove(); - for (var element in sentenceElement.children[0].children) { - element.querySelector('.furigana')?.remove(); - } - - final japanese = sentenceElement.text; - - sentences.add(PhraseScrapeSentence( - english: english, japanese: japanese, pieces: pieces ?? [])); - } - - return sentences; -} - -PhrasePageScrapeResult _getMeaningsOtherFormsAndNotes(Document document) { - final returnValues = PhrasePageScrapeResult(otherForms: [], notes: []); - - final meaningsWrapper = document.querySelector('.meanings-wrapper'); - if (meaningsWrapper == null) return PhrasePageScrapeResult(found: false); - returnValues.found = true; - - final meaningsChildren = meaningsWrapper.children; - - final List meanings = []; - var mostRecentWordTypes = []; - for (var meaningIndex = 0; - meaningIndex < meaningsChildren.length; - meaningIndex += 1) { - final child = meaningsChildren[meaningIndex]; - - if (child.className.contains('meaning-tags')) { - mostRecentWordTypes = _getMostRecentWordTypes(child); - } else if (mostRecentWordTypes[0] == 'other forms') { - returnValues.otherForms = _getOtherForms(child); - } else if (mostRecentWordTypes[0] == 'notes') { - returnValues.notes = _getNotes(child); - } else { - final meaning = _getMeaning(child); - final meaningAbstract = _getMeaningAbstract(child); - final supplemental = _getSupplemental(child); - final seeAlsoTerms = _getSeeAlsoTerms(supplemental); - final sentences = _getSentences(child); - - meanings.add(PhraseScrapeMeaning( - seeAlsoTerms: seeAlsoTerms ?? [], - sentences: sentences ?? [], - definition: meaning, - supplemental: supplemental ?? [], - definitionAbstract: meaningAbstract, - tags: mostRecentWordTypes ?? [], - )); - } - } - - returnValues.meanings = meanings; - - return returnValues; -} - -/// Provides the URI for a phrase scrape -String uriForPhraseScrape(String searchTerm) { - return 'https://jisho.org/word/${Uri.encodeComponent(searchTerm)}'; -} - -/// Parses a jisho word search page to an object -PhrasePageScrapeResult parsePhrasePageData(String pageHtml, String query) { - final document = parse(pageHtml); - final result = _getMeaningsOtherFormsAndNotes(document); - - result.query = query; - if (!result.found) return result; - result.uri = uriForPhraseScrape(query); - result.tags = _getTags(document); - - return result; -} diff --git a/lib/src/phraseSearch.dart b/lib/src/phraseSearch.dart deleted file mode 100644 index 024c86e..0000000 --- a/lib/src/phraseSearch.dart +++ /dev/null @@ -1,6 +0,0 @@ -import './base_uri.dart'; - -/// Provides the URI for a phrase search -String uriForPhraseSearch(String phrase) { - return '$JISHO_API?keyword=${Uri.encodeComponent(phrase)}'; -} diff --git a/lib/src/phrase_scrape.dart b/lib/src/phrase_scrape.dart new file mode 100644 index 0000000..40c30c3 --- /dev/null +++ b/lib/src/phrase_scrape.dart @@ -0,0 +1,202 @@ +import 'package:html/dom.dart'; +import 'package:html/parser.dart'; + +import './example_search.dart' show getPieces; +import './objects.dart'; +import './scraping.dart'; + +List _getTags(Document document) { + final tagElements = document.querySelectorAll('.concept_light-tag'); + final tags = tagElements.map((tagElement) => tagElement.text).toList(); + return tags; +} + +List _getMostRecentWordTypes(Element child) { + return child.text.split(',').map((s) => s.trim().toLowerCase()).toList(); +} + +List _getOtherForms(Element child) { + return child.text + .split('、') + .map((s) => s.replaceAll('【', '').replaceAll('】', '').split(' ')) + .map((a) => (KanjiKanaPair( + kanji: a[0], + kana: (a.length == 2) ? a[1] : null, + ))) + .toList(); +} + +List _getNotes(Element child) => child.text.split('\n'); + +String _getMeaningString(Element child) { + final meaning = assertNotNull( + variable: child.querySelector('.meaning-meaning')?.text, + errorMessage: + "Could not parse meaning div. Is the provided document corrupt, or has Jisho been updated?", + ); + + return meaning; +} + +String? _getMeaningAbstract(Element child) { + final meaningAbstract = child.querySelector('.meaning-abstract'); + if (meaningAbstract == null) return null; + + for (var element in meaningAbstract.querySelectorAll('a')) { + element.remove(); + } + + return child.querySelector('.meaning-abstract')?.text; +} + +List _getSupplemental(Element child) { + final supplemental = child.querySelector('.supplemental_info'); + if (supplemental == null) return []; + return supplemental.text.split(',').map((s) => s.trim()).toList(); +} + +List _getSeeAlsoTerms(List supplemental) { + // if (supplemental == null) return []; + + final seeAlsoTerms = []; + for (var i = supplemental.length - 1; i >= 0; i -= 1) { + final supplementalEntry = supplemental[i]; + if (supplementalEntry.startsWith('See also')) { + seeAlsoTerms.add(supplementalEntry.replaceAll('See also ', '')); + supplemental.removeAt(i); + } + } + return seeAlsoTerms; +} + +PhraseScrapeSentence _getSentence(Element sentenceElement) { + final english = assertNotNull( + variable: sentenceElement.querySelector('.english')?.text, + errorMessage: + 'Could not parse sentence translation. Is the provided document corrupt, or has Jisho been updated?', + ); + + final pieces = getPieces(sentenceElement); + + sentenceElement.querySelector('.english')?.remove(); + + for (var element in sentenceElement.children[0].children) { + element.querySelector('.furigana')?.remove(); + } + + final japanese = sentenceElement.text; + return PhraseScrapeSentence( + english: english, + japanese: japanese, + pieces: pieces, + ); +} + +List _getSentences(Element child) { + final sentenceElements = + child.querySelector('.sentences')?.querySelectorAll('.sentence'); + if (sentenceElements == null) return []; + + return sentenceElements.map(_getSentence).toList(); +} + +PhraseScrapeMeaning _getMeaning(Element child) { + final meaning = _getMeaningString(child); + final meaningAbstract = _getMeaningAbstract(child); + final supplemental = _getSupplemental(child); + final seeAlsoTerms = _getSeeAlsoTerms(supplemental); + final sentences = _getSentences(child); + + return PhraseScrapeMeaning( + seeAlsoTerms: seeAlsoTerms, + sentences: sentences, + definition: meaning, + supplemental: supplemental, + definitionAbstract: meaningAbstract, + // tags: mostRecentWordTypes ?? [], + ); +} + +List _getAudio(Document document) { + return document + .querySelector('.concept_light-status') + ?.querySelectorAll('audio > source') + .map((element) { + final src = assertNotNull( + variable: element.attributes["src"], + errorMessage: + 'Could not parse audio source. Is the provided document corrupt, or has Jisho been updated?', + ); + final type = assertNotNull( + variable: element.attributes['type'], + errorMessage: + 'Could not parse audio type. Is the provided document corrupt, or has Jisho been updated?', + ); + return AudioFile( + uri: 'https:$src', + mimetype: type, + ); + }).toList() ?? + []; +} + +/// Provides the URI for a phrase scrape +Uri uriForPhraseScrape(String searchTerm) { + return Uri.parse('https://jisho.org/word/${Uri.encodeComponent(searchTerm)}'); +} + +PhrasePageScrapeResultData _getMeaningsOtherFormsAndNotes( + String query, Document document) { + final meaningsWrapper = assertNotNull( + variable: document.querySelector('.meanings-wrapper'), + errorMessage: + "Could not parse meanings. Is the provided document corrupt, or has Jisho been updated?", + ); + + final meanings = []; + var mostRecentWordTypes = []; + var otherForms; + var notes; + + for (var child in meaningsWrapper.children) { + if (child.className.contains('meaning-tags')) { + mostRecentWordTypes = _getMostRecentWordTypes(child); + } else if (mostRecentWordTypes[0] == 'other forms') { + otherForms = _getOtherForms(child); + } else if (mostRecentWordTypes[0] == 'notes') { + notes = _getNotes(child); + } else { + meanings.add(_getMeaning(child)); + } + } + + return PhrasePageScrapeResultData( + uri: uriForPhraseScrape(query).toString(), + tags: _getTags(document), + meanings: meanings, + otherForms: otherForms ?? [], + audio: _getAudio(document), + notes: notes ?? [], + ); +} + +bool _resultWasFound(Document document) { + return document.querySelector('.meanings-wrapper') != null; +} + +/// Parses a jisho word search page to an object +PhrasePageScrapeResult parsePhrasePageData(String pageHtml, String query) { + final document = parse(pageHtml); + + if (!_resultWasFound(document)) { + return PhrasePageScrapeResult(found: false, query: query); + } + + final data = _getMeaningsOtherFormsAndNotes(query, document); + + return PhrasePageScrapeResult( + found: true, + query: query, + data: data, + ); +} diff --git a/lib/src/phrase_search.dart b/lib/src/phrase_search.dart new file mode 100644 index 0000000..8a7e6c5 --- /dev/null +++ b/lib/src/phrase_search.dart @@ -0,0 +1,6 @@ +import './base_uri.dart'; + +/// Provides the URI for a phrase search +Uri uriForPhraseSearch(String phrase) { + return Uri.parse('$jishoApi?keyword=${Uri.encodeComponent(phrase)}'); +} diff --git a/lib/src/scraping.dart b/lib/src/scraping.dart new file mode 100644 index 0000000..32f6fce --- /dev/null +++ b/lib/src/scraping.dart @@ -0,0 +1,75 @@ +/// Remove all newlines from a string +String removeNewlines(String str) { + return str.replaceAll(RegExp(r'(?:\r|\n)'), '').trim(); +} + +/// Remove alltext between two positions, and remove all newlines +String getStringBetweenIndicies(String data, int startIndex, int endIndex) { + final result = data.substring(startIndex, endIndex); + return removeNewlines(result).trim(); +} + +/// Try to find a string between two pieces of text +String? getStringBetweenStrings( + String data, + String startString, + String endString, +) { + final regex = RegExp( + '${RegExp.escape(startString)}(.*?)${RegExp.escape(endString)}', + dotAll: true, + ); + + final match = regex.allMatches(data).toList(); + return match.isNotEmpty ? match[0].group(1).toString() : null; +} + +/// Try to find an int inbetween two pieces of text +int? getIntBetweenStrings( + String data, + String startString, + String endString, +) { + final stringBetweenStrings = + getStringBetweenStrings(data, startString, endString); + return stringBetweenStrings != null ? int.parse(stringBetweenStrings) : null; +} + +/// Get all regex matches +List getAllGlobalGroupMatches(String str, RegExp regex) { + final regexResults = regex.allMatches(str).toList(); + final results = []; + for (var match in regexResults) { + final m = match.group(1); + if (m != null) results.add(m); + } + + return results; +} + +/// Get all matches of `
    DATA` +List parseAnchorsToArray(String str) { + final regex = RegExp(r'(.*?)<\/a>'); + return getAllGlobalGroupMatches(str, regex); +} + +/// An exception to be thrown whenever a parser fails by not finding an expected pattern. +class ParserException implements Exception { + /// The error message to report + final String message; + + // ignore: public_member_api_docs + const ParserException(this.message); +} + +/// Throw a `ParserException` if variable is null +dynamic assertNotNull({ + required dynamic variable, + String errorMessage = + "Unexpected null-value occured. Is the provided document corrupt, or has Jisho been updated?", +}) { + if (variable == null) { + throw ParserException(errorMessage); + } + return variable!; +} diff --git a/pubspec.yaml b/pubspec.yaml index 410d7a4..5db72a7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,20 +1,20 @@ name: unofficial_jisho_api -version: 1.1.0 +version: 2.0.0 description: An unofficial api for searching and scraping the japanese dictionary Jisho.org homepage: https://github.com/h7x4ABk3g/unofficial_jisho_api_dart/ issue_tracker: https://github.com/h7x4ABk3g/unofficial_jisho_api_dart/issues environment: - sdk: '>=2.7.0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' dependencies: - http: ^0.12.1 - html_unescape: ^1.0.1+3 - html: ^0.14.0+3 + http: ^0.13.3 + html_unescape: ^2.0.0 + html: ^0.15.0 dev_dependencies: - pedantic: ^1.9.0 - test: ^1.15.0 - path: ^1.7.0 - effective_dart: ^1.2.3 + pedantic: ^1.11.1 + test: ^1.17.10 + path: ^1.8.0 + effective_dart: ^1.3.2 diff --git a/test/create_test_cases.dart b/test/create_test_cases.dart index 05067f2..c64c41b 100644 --- a/test/create_test_cases.dart +++ b/test/create_test_cases.dart @@ -7,7 +7,11 @@ import 'package:unofficial_jisho_api/api.dart'; final JsonEncoder encoder = JsonEncoder.withIndent(' '); final String currentdir = Directory.current.path; -void writeCases(Function apiFunction, String folderName, List queries) async { +void writeCases( + Function apiFunction, + String folderName, + List queries, +) async { final dir = path.join(currentdir, 'test', folderName); for (var testCount = 0; testCount < queries.length; testCount++) { diff --git a/test/example_test_cases/0.json b/test/example_test_cases/0.json index fe79c0f..d73d553 100644 --- a/test/example_test_cases/0.json +++ b/test/example_test_cases/0.json @@ -3,45 +3,249 @@ "found": true, "results": [ { - "english": "The colour and make of the president's car are?", - "kanji": "社長さんの車種と色は?", - "kana": "しゃちょうさんのしゃしゅといろは?", + "english": "If we can't get the money in any other way, we can, as a last resort, sell the car.", + "kanji": "他の方法でお金がつくれなければ最後の手段として車を売り払えばよい。", + "kana": "ほかのほうほうでおかねがつくれなければさいごのしゅだんとしてくるまをうりはらえばよい。", "pieces": [ { - "lifted": "しゃちょう", - "unlifted": "社長" + "lifted": "ほか", + "unlifted": "他の" + }, + { + "lifted": "ほうほう", + "unlifted": "方法" }, { "lifted": null, - "unlifted": "さん" + "unlifted": "で" + }, + { + "lifted": "おかね", + "unlifted": "お金" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": null, + "unlifted": "つくれ" + }, + { + "lifted": null, + "unlifted": "なければ" + }, + { + "lifted": "さいごのしゅだん", + "unlifted": "最後の手段" + }, + { + "lifted": null, + "unlifted": "として" + }, + { + "lifted": "くるま", + "unlifted": "車" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "うりはら", + "unlifted": "売り払えば" + }, + { + "lifted": null, + "unlifted": "よい" + } + ] + }, + { + "english": "Any car will do, as long as it runs.", + "kanji": "走りさえすれば、どんな車でもよいのです。", + "kana": "はしりさえすれば、どんなくるまでもよいのです。", + "pieces": [ + { + "lifted": "はし", + "unlifted": "走り" + }, + { + "lifted": null, + "unlifted": "さえすれば" + }, + { + "lifted": null, + "unlifted": "どんな" + }, + { + "lifted": "くるま", + "unlifted": "車" + }, + { + "lifted": null, + "unlifted": "でも" + }, + { + "lifted": null, + "unlifted": "よい" + }, + { + "lifted": null, + "unlifted": "のです" + } + ] + }, + { + "english": "Looking out the window, I saw a car coming.", + "kanji": "窓の外を見ると、車が1台来るのが見えた。", + "kana": "まどのそとをみると、くるまがいちだいきたるのがみえた。", + "pieces": [ + { + "lifted": "まど", + "unlifted": "窓" }, { "lifted": null, "unlifted": "の" }, { - "lifted": "しゃしゅ", - "unlifted": "車種" + "lifted": "そと", + "unlifted": "外" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "み", + "unlifted": "見る" }, { "lifted": null, "unlifted": "と" }, { - "lifted": "いろ", - "unlifted": "色" + "lifted": "くるま", + "unlifted": "車" }, { "lifted": null, - "unlifted": "は" + "unlifted": "が" + }, + { + "lifted": "いちだい", + "unlifted": "1台" + }, + { + "lifted": "きた", + "unlifted": "来る" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": "み", + "unlifted": "見えた" } ] }, { - "english": "The car wouldn't start.", - "kanji": "その車は動こうとしなかった。", - "kana": "そのくるまはうごこうとしなかった。", + "english": "What a nice car you have! You must have paid a lot for it.", + "kanji": "素敵な車じゃない。ずいぶん高かっただろう?", + "kana": "すてきなくるまじゃない。ずいぶんたかかっただろう?", "pieces": [ + { + "lifted": "すてき", + "unlifted": "素敵な" + }, + { + "lifted": "くるま", + "unlifted": "車" + }, + { + "lifted": null, + "unlifted": "じゃない" + }, + { + "lifted": null, + "unlifted": "ずいぶん" + }, + { + "lifted": "たか", + "unlifted": "高かった" + }, + { + "lifted": null, + "unlifted": "だろう" + } + ] + }, + { + "english": "My grandmother likes traveling by train.", + "kanji": "祖母は列車で旅行をするのが好きだ。", + "kana": "そぼはれっしゃでりょこうをするのがすきだ。", + "pieces": [ + { + "lifted": "そぼ", + "unlifted": "祖母" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "れっしゃ", + "unlifted": "列車" + }, + { + "lifted": null, + "unlifted": "で" + }, + { + "lifted": "りょこう", + "unlifted": "旅行" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": null, + "unlifted": "する" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": "す", + "unlifted": "好き" + }, + { + "lifted": null, + "unlifted": "だ" + } + ] + }, + { + "english": "All of us got into the car.", + "kanji": "全員その車に乗った。", + "kana": "ぜんいんそのくるまにのった。", + "pieces": [ + { + "lifted": "ぜんいん", + "unlifted": "全員" + }, { "lifted": null, "unlifted": "その" @@ -52,204 +256,96 @@ }, { "lifted": null, - "unlifted": "は" + "unlifted": "に" }, { - "lifted": "うご", - "unlifted": "動こう" - }, - { - "lifted": null, - "unlifted": "としなかった" + "lifted": "の", + "unlifted": "乗った" } ] }, { - "english": "Now that I think of it, I've been asked to look at a haiku he'd written by the tipsy bloke sitting next to me on the train.", - "kanji": "そういえば、電車の中で隣に座ったほろ酔いのおっさんに、自分の俳句を見て欲しいと言われたことがある。", - "kana": "そういえば、でんしゃのなかでとなりにすわったほろよいのおっさんに、じぶんのはいくをみてほしいといわれたことがある。", + "english": "I see a red car ahead.", + "kanji": "前方に赤い車が見える。", + "kana": "ぜんぽうにあかいくるまがみえる。", "pieces": [ { - "lifted": null, - "unlifted": "そういえば" + "lifted": "ぜんぽう", + "unlifted": "前方" }, { - "lifted": "でんしゃ", - "unlifted": "電車" + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "あか", + "unlifted": "赤い" + }, + { + "lifted": "くるま", + "unlifted": "車" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": "み", + "unlifted": "見える" + } + ] + }, + { + "english": "He had had his old one for more than ten years.", + "kanji": "前の車は10年以上持っていた。", + "kana": "まえのくるまは10ねんいじょうもっていた。", + "pieces": [ + { + "lifted": "まえ", + "unlifted": "前" }, { "lifted": null, "unlifted": "の" }, { - "lifted": "なか", - "unlifted": "中" + "lifted": "くるま", + "unlifted": "車" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "ねん", + "unlifted": "年" + }, + { + "lifted": "いじょう", + "unlifted": "以上" + }, + { + "lifted": "も", + "unlifted": "持っていた" + } + ] + }, + { + "english": "Traveling by boat takes longer than going by car.", + "kanji": "船で旅行するのは車で旅行するよりも時間がかかる。", + "kana": "ふねでりょこうするのはくるまでりょこうするよりもじかんがかかる。", + "pieces": [ + { + "lifted": "ふね", + "unlifted": "船" }, { "lifted": null, "unlifted": "で" }, { - "lifted": "となり", - "unlifted": "隣" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "すわ", - "unlifted": "座った" - }, - { - "lifted": "ほろよ", - "unlifted": "ほろ酔い" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": null, - "unlifted": "おっさん" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "じぶん", - "unlifted": "自分" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "はいく", - "unlifted": "俳句" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "み", - "unlifted": "見て" - }, - { - "lifted": "ほ", - "unlifted": "欲しい" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "い", - "unlifted": "言われた" - }, - { - "lifted": null, - "unlifted": "ことがある" - } - ] - }, - { - "english": "If you frequently spit-up blood you should call an ambulance or have a nearby physician make a house call.", - "kanji": "ひんぱんに吐血する場合は、救急車を呼ぶか、近くの内科医に往診してもらう。", - "kana": "ひんぱんにとけつするばあいは、きゅうきゅうしゃをよぶか、ちかくのないかいにおうしんしてもらう。", - "pieces": [ - { - "lifted": null, - "unlifted": "ひんぱんに" - }, - { - "lifted": "とけつ", - "unlifted": "吐血" - }, - { - "lifted": null, - "unlifted": "する" - }, - { - "lifted": "ばあい", - "unlifted": "場合" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "きゅうきゅうしゃ", - "unlifted": "救急車" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "よ", - "unlifted": "呼ぶ" - }, - { - "lifted": null, - "unlifted": "か" - }, - { - "lifted": "ちか", - "unlifted": "近く" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ないかい", - "unlifted": "内科医" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "おうしん", - "unlifted": "往診" - }, - { - "lifted": null, - "unlifted": "して" - }, - { - "lifted": null, - "unlifted": "もらう" - } - ] - }, - { - "english": "The front wheel plays an important role in two-wheeled vehicles moving without falling over.", - "kanji": "二輪車が倒れずに走行するのには前輪が大きな役割を演じています。", - "kana": "にりんしゃがたおれずにそうこうするのにはぜんりんがおおきなやくわりをえんじています。", - "pieces": [ - { - "lifted": "にりんしゃ", - "unlifted": "二輪車" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "たお", - "unlifted": "倒れず" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "そうこう", - "unlifted": "走行" + "lifted": "りょこう", + "unlifted": "旅行" }, { "lifted": null, @@ -257,180 +353,200 @@ }, { "lifted": null, - "unlifted": "のに" + "unlifted": "の" }, { "lifted": null, "unlifted": "は" }, { - "lifted": "ぜんりん", - "unlifted": "前輪" + "lifted": "くるま", + "unlifted": "車" + }, + { + "lifted": null, + "unlifted": "で" + }, + { + "lifted": "りょこう", + "unlifted": "旅行" + }, + { + "lifted": null, + "unlifted": "する" + }, + { + "lifted": null, + "unlifted": "よりも" + }, + { + "lifted": "じかん", + "unlifted": "時間がかかる" + } + ] + }, + { + "english": "The train was derailed by a piece of iron on the track.", + "kanji": "線路の上に鉄片があったために列車は脱線した。", + "kana": "せんろのうえにてっぺんがあったためにれっしゃはだっせんした。", + "pieces": [ + { + "lifted": "せんろ", + "unlifted": "線路" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "うえ", + "unlifted": "上" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "てっぺん", + "unlifted": "鉄片" }, { "lifted": null, "unlifted": "が" }, { - "lifted": "おお", - "unlifted": "大きな" + "lifted": null, + "unlifted": "あった" }, { - "lifted": "やくわりをえん", - "unlifted": "役割を演じています" - } - ] - }, - { - "english": "Did you catch the train?!", - "kanji": "列車に間に合ったのか?!", - "kana": "れっしゃにまにあったのか?!", - "pieces": [ + "lifted": null, + "unlifted": "ために" + }, { "lifted": "れっしゃ", "unlifted": "列車" }, { "lifted": null, - "unlifted": "に" + "unlifted": "は" }, { - "lifted": "まにあ", - "unlifted": "間に合った" + "lifted": "だっせん", + "unlifted": "脱線" }, { "lifted": null, - "unlifted": "の" - }, - { - "lifted": null, - "unlifted": "か" + "unlifted": "した" } ] }, { - "english": "If you have any opinions concerning traffic calming devices (humps, curb extensions, etc.) please write them.", - "kanji": "車の速度を落とす装置(ハンプや狭さく)について、意見があったら書いてください。", - "kana": "くるまのそくどをおとすそうち(ハンプやきょうさく)について、いけんがあったらかいてください。", + "english": "If you wash it, your car will shine in the sun.", + "kanji": "洗えば、車は太陽の光をあびて輝くだろう。", + "kana": "あらえば、くるまはたいようのひかりをあびてかがやくだろう。", "pieces": [ + { + "lifted": "あら", + "unlifted": "洗えば" + }, { "lifted": "くるま", "unlifted": "車" }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "たいよう", + "unlifted": "太陽" + }, { "lifted": null, "unlifted": "の" }, { - "lifted": "そくど", - "unlifted": "速度" + "lifted": "ひかり", + "unlifted": "光" }, { "lifted": null, "unlifted": "を" }, { - "lifted": "お", - "unlifted": "落とす" + "lifted": null, + "unlifted": "あびて" }, { - "lifted": "そうち", - "unlifted": "装置" + "lifted": "かがや", + "unlifted": "輝く" }, { "lifted": null, - "unlifted": "ハンプ" + "unlifted": "だろう" + } + ] + }, + { + "english": "Tanks and planes may defeat the troops but they cannot conquer the people.", + "kanji": "戦車や飛行機は軍隊を打ち破ることはできようが、国民を征服することはできない。", + "kana": "せんしゃやひこうきはぐんたいをうちやぶることはできようが、こくみんをせいふくすることはできない。", + "pieces": [ + { + "lifted": "せんしゃ", + "unlifted": "戦車" }, { "lifted": null, "unlifted": "や" }, { - "lifted": "きょう", - "unlifted": "狭さく" - }, - { - "lifted": null, - "unlifted": "について" - }, - { - "lifted": "いけん", - "unlifted": "意見" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "あったら" - }, - { - "lifted": "か", - "unlifted": "書いて" - }, - { - "lifted": null, - "unlifted": "ください" - } - ] - }, - { - "english": "The Mexican government announced the banning of all imports of second-hand cars, except for 1998 models.", - "kanji": "メキシコ政府は1998年型の中古車以外の中古車の輸入を禁止すると発表した。", - "kana": "メキシコせいふは1998ねんがたのちゅうこしゃいがいのちゅうこしゃのゆにゅうをきんしするとはっぴょうした。", - "pieces": [ - { - "lifted": null, - "unlifted": "メキシコ" - }, - { - "lifted": "せいふ", - "unlifted": "政府" + "lifted": "ひこうき", + "unlifted": "飛行機" }, { "lifted": null, "unlifted": "は" }, { - "lifted": "ねんがた", - "unlifted": "年型" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ちゅうこしゃ", - "unlifted": "中古車" - }, - { - "lifted": "いがい", - "unlifted": "以外" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ちゅうこしゃ", - "unlifted": "中古車" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ゆにゅう", - "unlifted": "輸入" + "lifted": "ぐんたい", + "unlifted": "軍隊" }, { "lifted": null, "unlifted": "を" }, { - "lifted": "きんし", - "unlifted": "禁止" + "lifted": "うちやぶ", + "unlifted": "打ち破る" + }, + { + "lifted": null, + "unlifted": "こと" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "できよう" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": "こくみん", + "unlifted": "国民" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "せいふく", + "unlifted": "征服" }, { "lifted": null, @@ -438,396 +554,112 @@ }, { "lifted": null, - "unlifted": "と" - }, - { - "lifted": "はっぴょう", - "unlifted": "発表" - }, - { - "lifted": null, - "unlifted": "した" + "unlifted": "ことはできない" } ] }, { - "english": "The car dove into the field and, after bumping along for a time, came to a halt.", - "kanji": "車は草地に飛び込み、しばらくガクンガクンと走って止まったのです。", - "kana": "くるまはくさちにとびこみ、しばらくガクンガクンとはしってとまったのです。", + "english": "Our teacher likes his new car.", + "kanji": "先生は新しい車が気に入っている。", + "kana": "せんせいはあたらしいくるまがきにっている。", "pieces": [ { - "lifted": "くるま", - "unlifted": "車" + "lifted": "せんせい", + "unlifted": "先生" }, { "lifted": null, "unlifted": "は" }, { - "lifted": "くさち", - "unlifted": "草地" + "lifted": "あたら", + "unlifted": "新しい" }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "とびこ", - "unlifted": "飛び込み" - }, - { - "lifted": null, - "unlifted": "しばらく" - }, - { - "lifted": null, - "unlifted": "ガクンガクンと" - }, - { - "lifted": "はし", - "unlifted": "走って" - }, - { - "lifted": "と", - "unlifted": "止まった" - }, - { - "lifted": null, - "unlifted": "のです" - } - ] - }, - { - "english": "I'm living on welfare, without a car or anything.", - "kanji": "車も何もなく、生活保護で生きてます。", - "kana": "くるまもなにもなく、せいかつほごでいきてます。", - "pieces": [ { "lifted": "くるま", "unlifted": "車" }, { "lifted": null, - "unlifted": "も" + "unlifted": "が" }, { - "lifted": "なに", - "unlifted": "何も" + "lifted": "きに", + "unlifted": "気に入っている" + } + ] + }, + { + "english": "My teacher drove me home.", + "kanji": "先生は私の家まで車で送ってくれた。", + "kana": "せんせいはわたしのいえまでくるまでおくってくれた。", + "pieces": [ + { + "lifted": "せんせい", + "unlifted": "先生" }, { "lifted": null, - "unlifted": "なく" + "unlifted": "は" }, { - "lifted": "せいかつほご", - "unlifted": "生活保護" + "lifted": "わたし", + "unlifted": "私の" + }, + { + "lifted": "いえ", + "unlifted": "家" + }, + { + "lifted": null, + "unlifted": "まで" + }, + { + "lifted": "くるま", + "unlifted": "車" }, { "lifted": null, "unlifted": "で" }, + { + "lifted": "おく", + "unlifted": "送って" + }, + { + "lifted": null, + "unlifted": "くれた" + } + ] + }, + { + "english": "The train bound for Sendai has just left.", + "kanji": "仙台行きの列車は出たばかりです。", + "kana": "仙台いきのれっしゃはでたばかりです。", + "pieces": [ { "lifted": "い", - "unlifted": "生きてます" - } - ] - }, - { - "english": "Cars that, when new, cost 3,000,000 yen are apparently now worth 300,000, so I think I'll use mine a little longer.", - "kanji": "新車時300万円した車も今では30万円位だそうですから、もう少し乗ろうと思います。", - "kana": "しんしゃどき300まんえんしたくるまもいまでは30まんえん位だそうですから、もうすこしのろうとおもいます。", - "pieces": [ - { - "lifted": "しんしゃ", - "unlifted": "新車" - }, - { - "lifted": "どき", - "unlifted": "時" - }, - { - "lifted": "まん", - "unlifted": "万" - }, - { - "lifted": "えん", - "unlifted": "円" - }, - { - "lifted": null, - "unlifted": "した" - }, - { - "lifted": "くるま", - "unlifted": "車" - }, - { - "lifted": null, - "unlifted": "も" - }, - { - "lifted": "いま", - "unlifted": "今では" - }, - { - "lifted": "まん", - "unlifted": "万" - }, - { - "lifted": "えん", - "unlifted": "円" - }, - { - "lifted": null, - "unlifted": "位" - }, - { - "lifted": null, - "unlifted": "だ" - }, - { - "lifted": null, - "unlifted": "そうです" - }, - { - "lifted": null, - "unlifted": "から" - }, - { - "lifted": "もうすこ", - "unlifted": "もう少し" - }, - { - "lifted": "の", - "unlifted": "乗ろう" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "おも", - "unlifted": "思います" - } - ] - }, - { - "english": "At that time the snow plow was certainly our hero.", - "kanji": "このとき除雪車は確かに私たちの英雄でした。", - "kana": "このときじょせつしゃはたしかにわたしたちのえいゆうでした。", - "pieces": [ - { - "lifted": null, - "unlifted": "この" - }, - { - "lifted": null, - "unlifted": "とき" - }, - { - "lifted": "じょせつしゃ", - "unlifted": "除雪車" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "たし", - "unlifted": "確かに" - }, - { - "lifted": "わたし", - "unlifted": "私たち" + "unlifted": "行き" }, { "lifted": null, "unlifted": "の" }, { - "lifted": "えいゆう", - "unlifted": "英雄" - }, - { - "lifted": null, - "unlifted": "でした" - } - ] - }, - { - "english": "He didn't intend to let her drive but she pestered him so much that he finally gave in.", - "kanji": "彼は彼女に車を運転させるつもりはなかったのだが、彼女があまりにせがむものだから、彼の方がとうとう折れた。", - "kana": "かれはかのじょにくるまをうんてんさせるつもりはなかったのだが、かのじょがあまりにせがむものだから、かれのほうがとうとうおれた。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" + "lifted": "れっしゃ", + "unlifted": "列車" }, { "lifted": null, "unlifted": "は" }, { - "lifted": "かのじょ", - "unlifted": "彼女" + "lifted": "で", + "unlifted": "出た" }, { "lifted": null, - "unlifted": "に" - }, - { - "lifted": "くるま", - "unlifted": "車" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "うんてん", - "unlifted": "運転させる" - }, - { - "lifted": null, - "unlifted": "つもり" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "なかった" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": null, - "unlifted": "だ" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "かのじょ", - "unlifted": "彼女" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "あまり" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": null, - "unlifted": "せがむ" - }, - { - "lifted": null, - "unlifted": "ものだから" - }, - { - "lifted": "かれ", - "unlifted": "彼の" - }, - { - "lifted": "ほう", - "unlifted": "方" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "とうとう" - }, - { - "lifted": "お", - "unlifted": "折れた" - } - ] - }, - { - "english": "We are now going to move to the crematorium so if Mr. Ogawa and you would enter the car ...", - "kanji": "これから火葬場へ移動しますので、小川様と君は車へ。", - "kana": "これからかそうばへいどうしますので、小川さまときみはくるまへ。", - "pieces": [ - { - "lifted": null, - "unlifted": "これから" - }, - { - "lifted": "かそうば", - "unlifted": "火葬場" - }, - { - "lifted": null, - "unlifted": "へ" - }, - { - "lifted": "いどう", - "unlifted": "移動" - }, - { - "lifted": null, - "unlifted": "します" - }, - { - "lifted": null, - "unlifted": "ので" - }, - { - "lifted": "さま", - "unlifted": "様" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "きみ", - "unlifted": "君" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "くるま", - "unlifted": "車" - }, - { - "lifted": null, - "unlifted": "へ" - } - ] - }, - { - "english": "Japanese cars are right hand drive.", - "kanji": "日本車は右ハンドルです。", - "kana": "にほんしゃはみぎハンドルです。", - "pieces": [ - { - "lifted": "にほんしゃ", - "unlifted": "日本車" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "みぎ", - "unlifted": "右ハンドル" + "unlifted": "ばかり" }, { "lifted": null, @@ -836,233 +668,180 @@ ] }, { - "english": "The coalition force fired at her car at the checkpoint in Bagdad.", - "kanji": "同盟軍はバグダッドの検問所で彼女の車を襲撃した。", - "kana": "どうめいぐんはバグダッドのけんもんじょでかのじょのくるまをしゅうげきした。", + "english": "The snow prevented the train from running.", + "kanji": "雪のため列車は走れなかった。", + "kana": "ゆきのためれっしゃははしれなかった。", "pieces": [ { - "lifted": "どうめいぐん", - "unlifted": "同盟軍" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "バグダッド" + "lifted": "ゆき", + "unlifted": "雪" }, { "lifted": null, "unlifted": "の" }, { - "lifted": "けんもんじょ", - "unlifted": "検問所" + "lifted": null, + "unlifted": "ため" + }, + { + "lifted": "れっしゃ", + "unlifted": "列車" }, { "lifted": null, - "unlifted": "で" + "unlifted": "は" }, { - "lifted": "かのじょ", - "unlifted": "彼女の" - }, - { - "lifted": "くるま", - "unlifted": "車" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "しゅうげき", - "unlifted": "襲撃" - }, - { - "lifted": null, - "unlifted": "した" + "lifted": "はし", + "unlifted": "走れなかった" } ] }, { - "english": "When it sets off the bell rings, \"ding-ding\". Thus 'ding-ding-train'.", - "kanji": "動き出すとき、ベルが「ちんちん」と鳴る。だから、ちんちん電車。", - "kana": "うごきだすとき、ベルが「ちんちん」となる。だから、ちんちんでんしゃ。", + "english": "Owing to the snow, the train was delayed.", + "kanji": "雪のため、列車が遅れた。", + "kana": "ゆきのため、れっしゃがおくれた。", "pieces": [ { - "lifted": "うごきだ", - "unlifted": "動き出す" + "lifted": "ゆき", + "unlifted": "雪" }, { "lifted": null, - "unlifted": "とき" + "unlifted": "の" }, { "lifted": null, - "unlifted": "ベル" + "unlifted": "ため" + }, + { + "lifted": "れっしゃ", + "unlifted": "列車" }, { "lifted": null, "unlifted": "が" }, { - "lifted": null, - "unlifted": "ちんちん" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "な", - "unlifted": "鳴る" - }, - { - "lifted": null, - "unlifted": "だから" - }, - { - "lifted": null, - "unlifted": "ちんちん" - }, - { - "lifted": "でんしゃ", - "unlifted": "電車" + "lifted": "おく", + "unlifted": "遅れた" } ] }, { - "english": "The car was stuck in the mud.", - "kanji": "車がぬかるみに填まり込んだ。", - "kana": "くるまがぬかるみにはまりこんだ。", + "english": "The snow caused me to miss the train.", + "kanji": "雪のせいで私は電車に乗り遅れた。", + "kana": "ゆきのせいでわたしはでんしゃにのりおくれた。", "pieces": [ { - "lifted": "くるま", - "unlifted": "車" + "lifted": "ゆき", + "unlifted": "雪" }, { "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "ぬかるみ" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "はまりこ", - "unlifted": "填まり込んだ" - } - ] - }, - { - "english": "We reached our destination just as I thought the car was going to give up the ghost.", - "kanji": "車がいかれるかと思ったころ終点に着きました。", - "kana": "くるまがいかれるかとおもったころしゅうてんにつきました。", - "pieces": [ - { - "lifted": "くるま", - "unlifted": "車" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "いかれる" - }, - { - "lifted": null, - "unlifted": "か" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "おも", - "unlifted": "思った" - }, - { - "lifted": null, - "unlifted": "ころ" - }, - { - "lifted": "しゅうてん", - "unlifted": "終点" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "つ", - "unlifted": "着きました" - } - ] - }, - { - "english": "Car? Ah, if you mean that limousine, - I chartered it.", - "kanji": "車?ああ・・・あのリムジンでしたら、私がチャーターした物ですわ。", - "kana": "くるま?ああ・・・あのリムジンでしたら、わたしがチャーターしたものですわ。", - "pieces": [ - { - "lifted": "くるま", - "unlifted": "車" - }, - { - "lifted": null, - "unlifted": "ああ" - }, - { - "lifted": null, - "unlifted": "あの" - }, - { - "lifted": null, - "unlifted": "リムジン" - }, - { - "lifted": null, - "unlifted": "でしたら" + "unlifted": "のせいで" }, { "lifted": "わたし", "unlifted": "私" }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "でんしゃ", + "unlifted": "電車" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "のりおく", + "unlifted": "乗り遅れた" + } + ] + }, + { + "english": "You must not travel on the train without a ticket.", + "kanji": "切符なしで電車に乗ってはいけません。", + "kana": "きっぷなしででんしゃにのってはいけません。", + "pieces": [ + { + "lifted": "きっぷ", + "unlifted": "切符" + }, + { + "lifted": null, + "unlifted": "なしで" + }, + { + "lifted": "でんしゃ", + "unlifted": "電車" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "の", + "unlifted": "乗って" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "いけません" + } + ] + }, + { + "english": "The lorry had to stop because its load had fallen off.", + "kanji": "積み荷が落ちたので、トラックは停車しなければならなかった。", + "kana": "つみにがおちたので、トラックはていしゃしなければならなかった。", + "pieces": [ + { + "lifted": "つみに", + "unlifted": "積み荷" + }, { "lifted": null, "unlifted": "が" }, { - "lifted": null, - "unlifted": "チャーター" + "lifted": "お", + "unlifted": "落ちた" }, { "lifted": null, - "unlifted": "した" - }, - { - "lifted": "もの", - "unlifted": "物" + "unlifted": "ので" }, { "lifted": null, - "unlifted": "です" + "unlifted": "トラック" }, { "lifted": null, - "unlifted": "わ" + "unlifted": "は" + }, + { + "lifted": "ていしゃ", + "unlifted": "停車" + }, + { + "lifted": null, + "unlifted": "し" + }, + { + "lifted": null, + "unlifted": "なければならなかった" } ] } ], - "uri": "https://jisho.org/search/%E8%BB%8A%23sentences", - "phrase": "車" + "uri": "https://jisho.org/search/%E8%BB%8A%23sentences" } \ No newline at end of file diff --git a/test/example_test_cases/1.json b/test/example_test_cases/1.json index 6cef354..9100cff 100644 --- a/test/example_test_cases/1.json +++ b/test/example_test_cases/1.json @@ -2,6 +2,401 @@ "query": "日本人", "found": true, "results": [ + { + "english": "After the war, the diligence and the saving of the Japanese gave an impression which is strong in the American.", + "kanji": "戦後、日本人の勤勉さと節約はアメリカ人に強い印象を与えた。", + "kana": "せんご、にほんじんのきんべんさとせつやくはアメリカじんにつよいいんしょうをあたえた。", + "pieces": [ + { + "lifted": "せんご", + "unlifted": "戦後" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "きんべん", + "unlifted": "勤勉さ" + }, + { + "lifted": null, + "unlifted": "と" + }, + { + "lifted": "せつやく", + "unlifted": "節約" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "アメリカじん", + "unlifted": "アメリカ人" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "つよ", + "unlifted": "強い" + }, + { + "lifted": "いんしょうをあた", + "unlifted": "印象を与えた" + } + ] + }, + { + "english": "Cleanliness is proper to the Japanese.", + "kanji": "清潔は日本人の習性だ。", + "kana": "せいけつはにほんじんのしゅうせいだ。", + "pieces": [ + { + "lifted": "せいけつ", + "unlifted": "清潔" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "しゅうせい", + "unlifted": "習性" + }, + { + "lifted": null, + "unlifted": "だ" + } + ] + }, + { + "english": "The passengers on board were mostly Japanese.", + "kanji": "乗船客は主に日本人だった。", + "kana": "じょうせんきゃくはおもににほんじんだった。", + "pieces": [ + { + "lifted": "じょうせん", + "unlifted": "乗船" + }, + { + "lifted": "きゃく", + "unlifted": "客" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "おも", + "unlifted": "主に" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "だった" + } + ] + }, + { + "english": "Those who are present are all Japanese.", + "kanji": "出席をしている人々は全部日本人です。", + "kana": "しゅっせきをしているひとびと々はぜんぶにほんじんです。", + "pieces": [ + { + "lifted": "しゅっせき", + "unlifted": "出席" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": null, + "unlifted": "している" + }, + { + "lifted": "ひとびと", + "unlifted": "人々" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "ぜんぶ", + "unlifted": "全部" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "です" + } + ] + }, + { + "english": "Some young Japanese people prefer being single to being married.", + "kanji": "若い日本人の中には、結婚するより独身でいることを好む者もいる。", + "kana": "わかいにほんじんのなかには、けっこんするよりどくしんでいることをこのむものもいる。", + "pieces": [ + { + "lifted": "わか", + "unlifted": "若い" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "なか", + "unlifted": "中" + }, + { + "lifted": null, + "unlifted": "には" + }, + { + "lifted": "けっこん", + "unlifted": "結婚する" + }, + { + "lifted": null, + "unlifted": "より" + }, + { + "lifted": "どくしん", + "unlifted": "独身" + }, + { + "lifted": null, + "unlifted": "で" + }, + { + "lifted": null, + "unlifted": "いる" + }, + { + "lifted": null, + "unlifted": "こと" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "この", + "unlifted": "好む" + }, + { + "lifted": "もの", + "unlifted": "者" + }, + { + "lifted": null, + "unlifted": "も" + }, + { + "lifted": null, + "unlifted": "いる" + } + ] + }, + { + "english": "I didn't know that he was Japanese.", + "kanji": "私は彼が日本人だとは知らなかった。", + "kana": "わたしはかれがにほんじんだとはしらなかった。", + "pieces": [ + { + "lifted": "わたし", + "unlifted": "私" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "かれ", + "unlifted": "彼" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "だ" + }, + { + "lifted": null, + "unlifted": "と" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "し", + "unlifted": "知らなかった" + } + ] + }, + { + "english": "I speak of the Japanese in general.", + "kanji": "私は日本人一般について言っているのだ。", + "kana": "わたしはにほんじんいっぱんについていっているのだ。", + "pieces": [ + { + "lifted": "わたし", + "unlifted": "私" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": "いっぱん", + "unlifted": "一般" + }, + { + "lifted": null, + "unlifted": "について" + }, + { + "lifted": "い", + "unlifted": "言っている" + }, + { + "lifted": null, + "unlifted": "のだ" + } + ] + }, + { + "english": "I am Japanese, but you are an American.", + "kanji": "私は日本人ですが、あなたはアメリカ人です。", + "kana": "わたしはにほんじんですが、あなたはアメリカじんです。", + "pieces": [ + { + "lifted": "わたし", + "unlifted": "私" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "です" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": null, + "unlifted": "あなた" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "アメリカじん", + "unlifted": "アメリカ人" + }, + { + "lifted": null, + "unlifted": "です" + } + ] + }, + { + "english": "I thought only Japanese were workaholics.", + "kanji": "私は仕事中毒者は日本人だけかと思っていました。", + "kana": "わたしはしごとちゅうどくしゃはにほんじんだけかとおもっていました。", + "pieces": [ + { + "lifted": "わたし", + "unlifted": "私" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "しごと", + "unlifted": "仕事" + }, + { + "lifted": "ちゅうどく", + "unlifted": "中毒" + }, + { + "lifted": "しゃ", + "unlifted": "者" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "だけ" + }, + { + "lifted": null, + "unlifted": "か" + }, + { + "lifted": null, + "unlifted": "と" + }, + { + "lifted": "おも", + "unlifted": "思っていました" + } + ] + }, { "english": "A Japanese person would never do such a thing.", "kanji": "日本人ならそんなことはけっしてしないでしょう。", @@ -41,49 +436,6 @@ } ] }, - { - "english": "When did the Japanese start eating polished rice?", - "kanji": "いつから日本人は精白米を食べるようになったのですか?", - "kana": "いつからにほんじんはせいはくまいをたべるようになったのですか?", - "pieces": [ - { - "lifted": null, - "unlifted": "いつから" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "せいはくまい", - "unlifted": "精白米" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "た", - "unlifted": "食べる" - }, - { - "lifted": null, - "unlifted": "ようになった" - }, - { - "lifted": null, - "unlifted": "のです" - }, - { - "lifted": null, - "unlifted": "か" - } - ] - }, { "english": "I think there are probably few Japanese who know this side of the Emperor Meiji, the side that left a song like this.", "kanji": "こんな歌を残している明治天皇の一面を知っている日本人は少ないのではないだろうか。", @@ -281,6 +633,53 @@ } ] }, + { + "english": "Few Japanese can use English well.", + "kanji": "日本人で英語をうまく使える人はほとんどいません。", + "kana": "にほんじんでえいごをうまくつかえるひとはほとんどいません。", + "pieces": [ + { + "lifted": "にほんじん", + "unlifted": "日本人" + }, + { + "lifted": null, + "unlifted": "で" + }, + { + "lifted": "えいご", + "unlifted": "英語" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": null, + "unlifted": "うまく" + }, + { + "lifted": "つか", + "unlifted": "使える" + }, + { + "lifted": "ひと", + "unlifted": "人" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "ほとんど" + }, + { + "lifted": null, + "unlifted": "いません" + } + ] + }, { "english": "As you can also tell from these beautiful, far from Japanese, looks, Yuna is not pure-blood Japanese. She's a quarter-blood with a westerner as grandmother.", "kanji": "日本人離れしたこの美しい相貌からもわかるように、優奈は実は生粋の日本人じゃない。西洋人をおばあちゃんに持つ、クォーターだったりする。", @@ -590,299 +989,7 @@ "unlifted": "雇う" } ] - }, - { - "english": "Are they Japanese?", - "kanji": "彼らは日本人ですか。", - "kana": "かれらはにほんじんですか。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼ら" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "ですか" - } - ] - }, - { - "english": "Are they Japanese or Chinese?", - "kanji": "彼らは日本人ですか、それとも中国人ですか。", - "kana": "かれらはにほんじんですか、それともちゅうごくじんですか。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼ら" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "ですか" - }, - { - "lifted": null, - "unlifted": "それとも" - }, - { - "lifted": "ちゅうごくじん", - "unlifted": "中国人" - }, - { - "lifted": null, - "unlifted": "ですか" - } - ] - }, - { - "english": "He is not Japanese.", - "kanji": "彼は日本人ではありません。", - "kana": "かれはにほんじんではありません。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "ではありません" - } - ] - }, - { - "english": "He speaks Japanese as if he were Japanese.", - "kanji": "彼は日本語をまるで日本人であるかのように話す。", - "kana": "かれはにほんごをまるでにほんじんであるかのようにはなす。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "にほんご", - "unlifted": "日本語" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": null, - "unlifted": "まるで" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "である" - }, - { - "lifted": null, - "unlifted": "かのように" - }, - { - "lifted": "はな", - "unlifted": "話す" - } - ] - }, - { - "english": "He is a typical Japanese.", - "kanji": "彼は典型的な日本人だ。", - "kana": "かれはてんけいてきなにほんじんだ。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "てんけいてき", - "unlifted": "典型的な" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "だ" - } - ] - }, - { - "english": "He is Japanese by birth.", - "kanji": "彼は生まれは日本人です。", - "kana": "かれはうまれはにほんじんです。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "う", - "unlifted": "生まれ" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "です" - } - ] - }, - { - "english": "He is the first Japanese that traveled in space.", - "kanji": "彼は最初に宇宙旅行をした日本人です。", - "kana": "かれはさいしょにうちゅうりょこうをしたにほんじんです。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "さいしょ", - "unlifted": "最初" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "うちゅうりょこう", - "unlifted": "宇宙旅行" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": null, - "unlifted": "した" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "です" - } - ] - }, - { - "english": "He is Japanese to the bone.", - "kanji": "彼は骨の髄まで日本人だ。", - "kana": "かれはほねのずいまでにほんじんだ。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "ほねのずい", - "unlifted": "骨の髄まで" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "だ" - } - ] - }, - { - "english": "He speaks Japanese as if he were Japanese.", - "kanji": "彼は、日本語をまるで日本人かのように話す。", - "kana": "かれは、にほんごをまるでにほんじんかのようにはなす。", - "pieces": [ - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "にほんご", - "unlifted": "日本語" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": null, - "unlifted": "まるで" - }, - { - "lifted": "にほんじん", - "unlifted": "日本人" - }, - { - "lifted": null, - "unlifted": "かのように" - }, - { - "lifted": "はな", - "unlifted": "話す" - } - ] } ], - "uri": "https://jisho.org/search/%E6%97%A5%E6%9C%AC%E4%BA%BA%23sentences", - "phrase": "日本人" + "uri": "https://jisho.org/search/%E6%97%A5%E6%9C%AC%E4%BA%BA%23sentences" } \ No newline at end of file diff --git a/test/example_test_cases/2.json b/test/example_test_cases/2.json index 71d6556..bc5813c 100644 --- a/test/example_test_cases/2.json +++ b/test/example_test_cases/2.json @@ -2,6 +2,5 @@ "query": "彼*叩く", "found": false, "results": [], - "uri": "https://jisho.org/search/%E5%BD%BC%EF%BC%8A%E5%8F%A9%E3%81%8F%23sentences", - "phrase": "彼*叩く" + "uri": "https://jisho.org/search/%E5%BD%BC%EF%BC%8A%E5%8F%A9%E3%81%8F%23sentences" } \ No newline at end of file diff --git a/test/example_test_cases/3.json b/test/example_test_cases/3.json index 68b4b8a..2aeacd4 100644 --- a/test/example_test_cases/3.json +++ b/test/example_test_cases/3.json @@ -3,158 +3,37 @@ "found": true, "results": [ { - "english": "The total solar eclipse can be observed next year on June 22nd.", - "kanji": "来年6月22日に観測される皆既日食。", - "kana": "らいねん6月22にちにかんそくされるかいきにっしょく。", + "english": "All the villagers in turn saluted the priest.", + "kanji": "村人はみなかわるがわる僧にあいさつした。", + "kana": "むらびとはみなかわるがわるそうにあいさつした。", "pieces": [ { - "lifted": "らいねん", - "unlifted": "来年" - }, - { - "lifted": null, - "unlifted": "6月" - }, - { - "lifted": "にち", - "unlifted": "日" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "かんそく", - "unlifted": "観測" - }, - { - "lifted": null, - "unlifted": "される" - }, - { - "lifted": "かいきにっしょく", - "unlifted": "皆既日食" - } - ] - }, - { - "english": "Do you all place great importance on morals?", - "kanji": "皆さんは、モラルを大切にしていますか。", - "kana": "みなさんは、モラルをたいせつにしていますか。", - "pieces": [ - { - "lifted": "みな", - "unlifted": "皆さん" + "lifted": "むらびと", + "unlifted": "村人" }, { "lifted": null, "unlifted": "は" }, - { - "lifted": null, - "unlifted": "モラル" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "たいせつ", - "unlifted": "大切に" - }, - { - "lifted": null, - "unlifted": "しています" - }, - { - "lifted": null, - "unlifted": "か" - } - ] - }, - { - "english": "Will everyone please stick with it to the last moment.", - "kanji": "どうぞ、皆様も最後の一瞬まで粘り抜いてください。", - "kana": "どうぞ、みなさまもさいごのいっしゅんまでねばりぬいてください。", - "pieces": [ - { - "lifted": null, - "unlifted": "どうぞ" - }, - { - "lifted": "みなさま", - "unlifted": "皆様" - }, - { - "lifted": null, - "unlifted": "も" - }, - { - "lifted": "さいご", - "unlifted": "最後" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "いっしゅん", - "unlifted": "一瞬" - }, - { - "lifted": null, - "unlifted": "まで" - }, - { - "lifted": "ねばりぬ", - "unlifted": "粘り抜いて" - }, - { - "lifted": null, - "unlifted": "ください" - } - ] - }, - { - "english": "We were all pleased to be so cheaply quit of him.", - "kanji": "これだけで厄介払いできたら安いもので、みな大喜びした。", - "kana": "これだけでやっかいばらいできたらやすいもので、みなおおよろこびした。", - "pieces": [ - { - "lifted": null, - "unlifted": "これだけ" - }, - { - "lifted": null, - "unlifted": "で" - }, - { - "lifted": "やっかいばら", - "unlifted": "厄介払い" - }, - { - "lifted": null, - "unlifted": "できたら" - }, - { - "lifted": "やす", - "unlifted": "安い" - }, - { - "lifted": null, - "unlifted": "もの" - }, - { - "lifted": null, - "unlifted": "で" - }, { "lifted": null, "unlifted": "みな" }, { - "lifted": "おおよろこ", - "unlifted": "大喜び" + "lifted": null, + "unlifted": "かわるがわる" + }, + { + "lifted": "そう", + "unlifted": "僧" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": null, + "unlifted": "あいさつ" }, { "lifted": null, @@ -163,349 +42,147 @@ ] }, { - "english": "For my part, having you lot with me is more reassuring than the police or anything!", - "kanji": "僕には警察よりも何よりもみんながいてくれることの方が心強いのですよ。", - "kana": "ぼくにはけいさつよりもなによりもみんながいてくれることのほうがこころづよいのですよ。", + "english": "All the villagers went out into the hills to look for a missing cat.", + "kanji": "村人たちは皆、行方不明になった猫を探すために山の中へでかけた。", + "kana": "むらびとたちはみんな、ゆくえふめいになったねこをさがすためにやまのなかへでかけた。", "pieces": [ { - "lifted": "ぼく", - "unlifted": "僕" + "lifted": "むらびと", + "unlifted": "村人" }, { "lifted": null, - "unlifted": "には" - }, - { - "lifted": "けいさつ", - "unlifted": "警察" - }, - { - "lifted": null, - "unlifted": "よりも" - }, - { - "lifted": "なに", - "unlifted": "何" - }, - { - "lifted": null, - "unlifted": "よりも" - }, - { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "いて" - }, - { - "lifted": null, - "unlifted": "くれる" - }, - { - "lifted": null, - "unlifted": "こと" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ほう", - "unlifted": "方" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "こころづよ", - "unlifted": "心強い" - }, - { - "lifted": null, - "unlifted": "のです" - }, - { - "lifted": null, - "unlifted": "よ" - } - ] - }, - { - "english": "With your ability it should be a doddle, but please don't be prideful of that but first apply yourself dilligently with everyone in your class.", - "kanji": "君の実力なら楽勝だとは思うが、それに驕らず、まずはクラスのみんなと切磋琢磨していって欲しい。", - "kana": "きみのじつりょくなららくしょうだとはおもうが、それにおごらず、まずはクラスのみんなとせっさたくましていってほしい。", - "pieces": [ - { - "lifted": "きみ", - "unlifted": "君の" - }, - { - "lifted": "じつりょく", - "unlifted": "実力" - }, - { - "lifted": null, - "unlifted": "なら" - }, - { - "lifted": "らくしょう", - "unlifted": "楽勝" - }, - { - "lifted": null, - "unlifted": "だ" - }, - { - "lifted": null, - "unlifted": "と" + "unlifted": "たち" }, { "lifted": null, "unlifted": "は" }, - { - "lifted": "おも", - "unlifted": "思う" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "それ" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "おご", - "unlifted": "驕らず" - }, - { - "lifted": null, - "unlifted": "まず" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "クラス" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "せっさたくま", - "unlifted": "切磋琢磨" - }, - { - "lifted": null, - "unlifted": "して" - }, - { - "lifted": null, - "unlifted": "いって" - }, - { - "lifted": "ほ", - "unlifted": "欲しい" - } - ] - }, - { - "english": "What programming language does everybody like?", - "kanji": "皆さんはどんなプログラミング言語が好きですか?", - "kana": "みなさんはどんなプログラミングげんごがすきですか?", - "pieces": [ - { - "lifted": "みな", - "unlifted": "皆さん" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "どんな" - }, - { - "lifted": "プログラミングげんご", - "unlifted": "プログラミング言語" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "す", - "unlifted": "好き" - }, - { - "lifted": null, - "unlifted": "ですか" - } - ] - }, - { - "english": "I'm teaching basic participial constructions now, but, with regard to those below, what different ways of translating them would everybody use?", - "kanji": "今、基本的な分詞構文を教えているのですが、皆さんは以下の分詞構文の訳については、どのように異なる訳し方をされますか?", - "kana": "いま、きほんてきなぶんしこうぶんをおしええているのですが、みなさんはいかのぶんしこうぶんのやくについては、どのようにことなるやくしかたをされますか?", - "pieces": [ - { - "lifted": "いま", - "unlifted": "今" - }, - { - "lifted": "きほんてき", - "unlifted": "基本的な" - }, - { - "lifted": "ぶんしこうぶん", - "unlifted": "分詞構文" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "おしえ", - "unlifted": "教えている" - }, - { - "lifted": null, - "unlifted": "のです" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "みな", - "unlifted": "皆さん" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "いか", - "unlifted": "以下" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ぶんしこうぶん", - "unlifted": "分詞構文" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "やく", - "unlifted": "訳" - }, - { - "lifted": null, - "unlifted": "について" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "どのように" - }, - { - "lifted": "こと", - "unlifted": "異なる" - }, - { - "lifted": "やく", - "unlifted": "訳し" - }, - { - "lifted": "かた", - "unlifted": "方" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": null, - "unlifted": "されます" - }, - { - "lifted": null, - "unlifted": "か" - } - ] - }, - { - "english": "What's different from Japan is that the doctors of Singapore generally all know each other.", - "kanji": "シンガポールの医師は殆どの場合皆お互いを知っている、というのが日本と異なります。", - "kana": "シンガポールのいしはほとんどのばあいみんなおたがいをしっている、というのがにほんとことなります。", - "pieces": [ - { - "lifted": null, - "unlifted": "シンガポール" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "いし", - "unlifted": "医師" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "ほとん", - "unlifted": "殆ど" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ばあい", - "unlifted": "場合" - }, { "lifted": "みんな", "unlifted": "皆" }, { - "lifted": "おたが", - "unlifted": "お互い" + "lifted": "ゆくえふめい", + "unlifted": "行方不明" + }, + { + "lifted": null, + "unlifted": "になった" + }, + { + "lifted": "ねこ", + "unlifted": "猫" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "さが", + "unlifted": "探す" + }, + { + "lifted": null, + "unlifted": "ために" + }, + { + "lifted": "やま", + "unlifted": "山" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "なか", + "unlifted": "中" + }, + { + "lifted": null, + "unlifted": "へ" + }, + { + "lifted": null, + "unlifted": "でかけた" + } + ] + }, + { + "english": "The festival is looked forward to by the villagers.", + "kanji": "村人たちはみな祭りを楽しみにしている。", + "kana": "むらびとたちはみなまつりをたのしみにしている。", + "pieces": [ + { + "lifted": "むらびと", + "unlifted": "村人" + }, + { + "lifted": null, + "unlifted": "たち" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "みな" + }, + { + "lifted": "まつ", + "unlifted": "祭り" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "たの", + "unlifted": "楽しみにしている" + } + ] + }, + { + "english": "All the villagers know of the accident.", + "kanji": "村の人々は皆その事故のことを知っている。", + "kana": "むらのひとびと々はみんなそのじこのことをしっている。", + "pieces": [ + { + "lifted": "むら", + "unlifted": "村" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "ひとびと", + "unlifted": "人々" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "みんな", + "unlifted": "皆" + }, + { + "lifted": null, + "unlifted": "その" + }, + { + "lifted": "じこ", + "unlifted": "事故" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": null, + "unlifted": "こと" }, { "lifted": null, @@ -514,340 +191,25 @@ { "lifted": "し", "unlifted": "知っている" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": null, - "unlifted": "いう" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "にほん", - "unlifted": "日本" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "こと", - "unlifted": "異なります" } ] }, { - "english": "Everyone, please keep to netiquette.", - "kanji": "皆さんネチケットはしっかり。", - "kana": "みなさんネチケットはしっかり。", + "english": "Everybody in the village looks up to him.", + "kanji": "村の人はみな彼のことを尊敬している。", + "kana": "むらのひとはみなかれのことをそんけいしている。", "pieces": [ { - "lifted": "みな", - "unlifted": "皆さん" - }, - { - "lifted": null, - "unlifted": "ネチケット" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "しっかり" - } - ] - }, - { - "english": "The example is a past progressive tense sentence. How was everybody taught when they were learning about progressive tense?", - "kanji": "例文は過去進行形の文です。皆さんは進行形を学習するとき、どのように教わりましたか?", - "kana": "れいぶんはかこしんこうけいのぶんです。みなさんはしんこうけいをがくしゅうするとき、どのようにおそわりましたか?", - "pieces": [ - { - "lifted": "れいぶん", - "unlifted": "例文" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "かこしんこうけい", - "unlifted": "過去進行形" + "lifted": "むら", + "unlifted": "村" }, { "lifted": null, "unlifted": "の" }, { - "lifted": "ぶん", - "unlifted": "文" - }, - { - "lifted": null, - "unlifted": "です" - }, - { - "lifted": "みな", - "unlifted": "皆さん" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "しんこうけい", - "unlifted": "進行形" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "がくしゅう", - "unlifted": "学習" - }, - { - "lifted": null, - "unlifted": "する" - }, - { - "lifted": null, - "unlifted": "とき" - }, - { - "lifted": null, - "unlifted": "どのように" - }, - { - "lifted": "おそ", - "unlifted": "教わりました" - }, - { - "lifted": null, - "unlifted": "か" - } - ] - }, - { - "english": "Oh, that's a secret, OK? Because slipping out of the dorm in the night is severely punished.", - "kanji": "あ、みんなには内緒だよ?寮を夜中に抜け出すのは厳罰だからね?", - "kana": "あ、みんなにはないしょだよ?りょうをよなかにぬけだすのはげんばつだからね?", - "pieces": [ - { - "lifted": null, - "unlifted": "あ" - }, - { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": null, - "unlifted": "には" - }, - { - "lifted": "ないしょ", - "unlifted": "内緒" - }, - { - "lifted": null, - "unlifted": "だ" - }, - { - "lifted": null, - "unlifted": "よ" - }, - { - "lifted": "りょう", - "unlifted": "寮" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "よなか", - "unlifted": "夜中" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": "ぬけだ", - "unlifted": "抜け出す" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": "げんばつ", - "unlifted": "厳罰" - }, - { - "lifted": null, - "unlifted": "だ" - }, - { - "lifted": null, - "unlifted": "から" - }, - { - "lifted": null, - "unlifted": "ね" - } - ] - }, - { - "english": "\"I've heard about it, Koichi\" \"You don't need to say anything more, I know. It's the summer festival incident at the shrine, right?\"", - "kanji": "「聞いたよ、光一」「まあ皆までいうなって。分かってる。神社の夏祭りの一件でしょ?」", - "kana": "「きいたよ、光一」「まあ皆までいうなって。わかかってる。じんじゃの夏祭りのいっけんでしょ?」", - "pieces": [ - { - "lifted": "き", - "unlifted": "聞いた" - }, - { - "lifted": null, - "unlifted": "よ" - }, - { - "lifted": null, - "unlifted": "まあ" - }, - { - "lifted": null, - "unlifted": "皆までいうな" - }, - { - "lifted": null, - "unlifted": "って" - }, - { - "lifted": "わか", - "unlifted": "分かってる" - }, - { - "lifted": "じんじゃ", - "unlifted": "神社" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": null, - "unlifted": "夏祭り" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "いっけん", - "unlifted": "一件" - }, - { - "lifted": null, - "unlifted": "でしょ" - } - ] - }, - { - "english": "We plan to elicit opinions from the public.", - "kanji": "市民の皆様の御意見をちょうだいする予定です。", - "kana": "しみんのみなさまのごいけんをちょうだいするよていです。", - "pieces": [ - { - "lifted": "しみん", - "unlifted": "市民" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "みなさま", - "unlifted": "皆様" - }, - { - "lifted": null, - "unlifted": "の" - }, - { - "lifted": "ご", - "unlifted": "御" - }, - { - "lifted": "いけん", - "unlifted": "意見" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": null, - "unlifted": "ちょうだい" - }, - { - "lifted": null, - "unlifted": "する" - }, - { - "lifted": "よてい", - "unlifted": "予定" - }, - { - "lifted": null, - "unlifted": "です" - } - ] - }, - { - "english": "Having scattered the enemy before me and triumphantly returned, this is how they would herald me.", - "kanji": "敵を蹴散らし、凱旋した俺はみなにこう呼ばれるんだ!", - "kana": "てきをけちらし、がいせんしたおれはみなにこうよばれるんだ!", - "pieces": [ - { - "lifted": "てき", - "unlifted": "敵" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "けち", - "unlifted": "蹴散らし" - }, - { - "lifted": "がいせん", - "unlifted": "凱旋" - }, - { - "lifted": null, - "unlifted": "した" - }, - { - "lifted": "おれ", - "unlifted": "俺" + "lifted": "ひと", + "unlifted": "人" }, { "lifted": null, @@ -858,153 +220,47 @@ "unlifted": "みな" }, { - "lifted": null, - "unlifted": "に" + "lifted": "かれ", + "unlifted": "彼" }, { "lifted": null, - "unlifted": "こう" - }, - { - "lifted": "よ", - "unlifted": "呼ばれる" + "unlifted": "の" }, { "lifted": null, - "unlifted": "んだ" - } - ] - }, - { - "english": "Quiet! Everybody stay where they are, there will now be a possessions check.", - "kanji": "静かに!みんなその場を動かないで。これから持ち物検査をはじめます。", - "kana": "しずかに!みんなそのばをうごかないで。これからもちものけんさをはじめます。", - "pieces": [ - { - "lifted": "しず", - "unlifted": "静かに" - }, - { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": "そのば", - "unlifted": "その場" + "unlifted": "こと" }, { "lifted": null, "unlifted": "を" }, { - "lifted": "うご", - "unlifted": "動かないで" + "lifted": "そんけい", + "unlifted": "尊敬" }, { "lifted": null, - "unlifted": "これ" - }, - { - "lifted": null, - "unlifted": "から" - }, - { - "lifted": "もちものけんさ", - "unlifted": "持ち物検査" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": null, - "unlifted": "はじめます" + "unlifted": "している" } ] }, { - "english": "Even if that's alright with you nobody else will accept it. I'll get shouted at afterwards so...", - "kanji": "恵子さんが良くてもみんなが納得しないんです。後で俺がドヤされるんだから。", - "kana": "恵子さんがよくてもみんながなっとくしないんです。あとでおれがドヤされるんだから。", + "english": "The frost killed all the flowers.", + "kanji": "霜で花はみんな枯れた。", + "kana": "しもではなはみんなかれた。", "pieces": [ { - "lifted": null, - "unlifted": "さん" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "よ", - "unlifted": "良くて" - }, - { - "lifted": null, - "unlifted": "も" - }, - { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "なっとく", - "unlifted": "納得" - }, - { - "lifted": null, - "unlifted": "しない" - }, - { - "lifted": null, - "unlifted": "んです" - }, - { - "lifted": "あと", - "unlifted": "後" + "lifted": "しも", + "unlifted": "霜" }, { "lifted": null, "unlifted": "で" }, { - "lifted": "おれ", - "unlifted": "俺" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": null, - "unlifted": "ドヤされる" - }, - { - "lifted": null, - "unlifted": "ん" - }, - { - "lifted": null, - "unlifted": "だから" - } - ] - }, - { - "english": "At home, because of his reddish hair and freckles, his mother scornfully named him \"carrot\" and had everybody else call him that.", - "kanji": "家では赤味がかった髪とそばかすのせいで、母が侮蔑を込めて「にんじん」と名付け、皆にもそう呼ばせています。", - "kana": "いえでは赤味がかったかみとそばかすのせいで、ははがぶべつをこめて「にんじん」となづけ、みんなにもそうよばせています。", - "pieces": [ - { - "lifted": "いえ", - "unlifted": "家" - }, - { - "lifted": null, - "unlifted": "で" + "lifted": "はな", + "unlifted": "花" }, { "lifted": null, @@ -1012,86 +268,284 @@ }, { "lifted": null, - "unlifted": "赤味がかった" + "unlifted": "みんな" }, { - "lifted": "かみ", - "unlifted": "髪" + "lifted": "か", + "unlifted": "枯れた" + } + ] + }, + { + "english": "All the early flowers were bitten by the frost.", + "kanji": "早咲きの花はみんな霜にやられた。", + "kana": "はやざきのはなはみんなしもにやられた。", + "pieces": [ + { + "lifted": "はやざ", + "unlifted": "早咲き" }, { "lifted": null, - "unlifted": "と" + "unlifted": "の" + }, + { + "lifted": "はな", + "unlifted": "花" }, { "lifted": null, - "unlifted": "そばかす" + "unlifted": "は" }, { "lifted": null, - "unlifted": "のせいで" + "unlifted": "みんな" }, { - "lifted": "はは", - "unlifted": "母" + "lifted": "しも", + "unlifted": "霜" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": null, + "unlifted": "やられた" + } + ] + }, + { + "english": "All students have access to the library.", + "kanji": "全学生はみんな図書館に入ることができる。", + "kana": "ぜんがくせいはみんなとしょかんにはいることができる。", + "pieces": [ + { + "lifted": "ぜん", + "unlifted": "全" + }, + { + "lifted": "がくせい", + "unlifted": "学生" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "みんな" + }, + { + "lifted": "としょかん", + "unlifted": "図書館" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "はい", + "unlifted": "入る" + }, + { + "lifted": null, + "unlifted": "ことができる" + } + ] + }, + { + "english": "All the players were in position.", + "kanji": "選手達はみな位置についていた。", + "kana": "せんしゅたちはみないちについていた。", + "pieces": [ + { + "lifted": "せんしゅ", + "unlifted": "選手" + }, + { + "lifted": "たち", + "unlifted": "達" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "みな" + }, + { + "lifted": "いち", + "unlifted": "位置" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": null, + "unlifted": "ついていた" + } + ] + }, + { + "english": "All the players did their best.", + "kanji": "選手たちみんなが最善をつくした。", + "kana": "せんしゅたちみんながさいぜんをつをつくした。", + "pieces": [ + { + "lifted": "せんしゅ", + "unlifted": "選手" + }, + { + "lifted": null, + "unlifted": "たち" + }, + { + "lifted": null, + "unlifted": "みんな" }, { "lifted": null, "unlifted": "が" }, { - "lifted": "ぶべつ", - "unlifted": "侮蔑" + "lifted": "さいぜんをつ", + "unlifted": "最善をつくした" + } + ] + }, + { + "english": "Everyone was glued to the TV set as the election results came in.", + "kanji": "選挙の結果出てくるにつれ、皆テレビにかじりついた。", + "kana": "せんきょのけっかでてくるにつれ、みんなテレビにかじりついた。", + "pieces": [ + { + "lifted": "せんきょ", + "unlifted": "選挙" }, { "lifted": null, - "unlifted": "を" + "unlifted": "の" }, { - "lifted": "こ", - "unlifted": "込めて" + "lifted": "けっか", + "unlifted": "結果" + }, + { + "lifted": "で", + "unlifted": "出てくる" }, { "lifted": null, - "unlifted": "にんじん" - }, - { - "lifted": null, - "unlifted": "と" - }, - { - "lifted": "なづ", - "unlifted": "名付け" + "unlifted": "につれ" }, { "lifted": "みんな", "unlifted": "皆" }, + { + "lifted": null, + "unlifted": "テレビ" + }, { "lifted": null, "unlifted": "に" }, { "lifted": null, - "unlifted": "も" - }, - { - "lifted": null, - "unlifted": "そう" - }, - { - "lifted": "よ", - "unlifted": "呼ばせています" + "unlifted": "かじりついた" } ] }, { - "english": "All for one, and one for all. That's team play.", - "kanji": "一人はみんなの為に、みんなは一人の為に。それがチームプレイだ。", - "kana": "ひとりはみんなのために、みんなはひとりのために。それがチームプレイだ。", + "english": "I may not have much to offer in the way of learning or ability, but I want to do whatever I can for us all and humbly ask for your favor.", + "kanji": "浅学非才の私ではありますが、何とぞ皆様のお力を賜りたく、ここにお願い申し上げる次第です。", + "kana": "せんがくひさいのわたしではありますが、なにとぞみなさまのおちからをたまわりたく、ここにおねがいもうしあげるしだいです。", "pieces": [ { - "lifted": "ひとり", - "unlifted": "一人" + "lifted": "せんがくひさい", + "unlifted": "浅学非才" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "わたし", + "unlifted": "私" + }, + { + "lifted": null, + "unlifted": "ではあります" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": "なに", + "unlifted": "何とぞ" + }, + { + "lifted": "みなさま", + "unlifted": "皆様" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": null, + "unlifted": "お" + }, + { + "lifted": "ちから", + "unlifted": "力" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "たまわ", + "unlifted": "賜り" + }, + { + "lifted": null, + "unlifted": "たく" + }, + { + "lifted": null, + "unlifted": "ここ" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "おねがいもうしあ", + "unlifted": "お願い申し上げる" + }, + { + "lifted": "しだい", + "unlifted": "次第" + }, + { + "lifted": null, + "unlifted": "です" + } + ] + }, + { + "english": "War doesn't make anybody happy.", + "kanji": "戦争はみんなを不幸せにする。", + "kana": "せんそうはみんなをふしあわせにする。", + "pieces": [ + { + "lifted": "せんそう", + "unlifted": "戦争" }, { "lifted": null, @@ -1101,13 +555,248 @@ "lifted": null, "unlifted": "みんな" }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "ふしあわ", + "unlifted": "不幸せ" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": null, + "unlifted": "する" + } + ] + }, + { + "english": "The other day I attended a class reunion of my elementary school.", + "kanji": "先日小学校のクラス会に出席した。", + "kana": "せんじつしょうがっこうのクラスかいにしゅっせきした。", + "pieces": [ + { + "lifted": "せんじつ", + "unlifted": "先日" + }, + { + "lifted": "しょうがっこう", + "unlifted": "小学校" + }, { "lifted": null, "unlifted": "の" }, { - "lifted": "ため", - "unlifted": "為に" + "lifted": "クラスかい", + "unlifted": "クラス会" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "しゅっせき", + "unlifted": "出席した" + } + ] + }, + { + "english": "The teacher called each student by name.", + "kanji": "先生は生徒みんなを名前で呼んだ。", + "kana": "せんせいはせいとみんなをなまえでよんだ。", + "pieces": [ + { + "lifted": "せんせい", + "unlifted": "先生" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "せいと", + "unlifted": "生徒" + }, + { + "lifted": null, + "unlifted": "みんな" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "なまえ", + "unlifted": "名前" + }, + { + "lifted": null, + "unlifted": "で" + }, + { + "lifted": "よ", + "unlifted": "呼んだ" + } + ] + }, + { + "english": "The teacher asked me if I was ready, adding that everybody was waiting for me at the school gate.", + "kanji": "先生は私に、用意は出来たか、みな校門のところで君を待っているよと言った。", + "kana": "せんせいはわたしに、よういはできたか、みなこうもんのところできみをまっているよといった。", + "pieces": [ + { + "lifted": "せんせい", + "unlifted": "先生" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "わたし", + "unlifted": "私" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "ようい", + "unlifted": "用意" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": "でき", + "unlifted": "出来た" + }, + { + "lifted": null, + "unlifted": "か" + }, + { + "lifted": null, + "unlifted": "みな" + }, + { + "lifted": "こうもん", + "unlifted": "校門" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": null, + "unlifted": "ところ" + }, + { + "lifted": null, + "unlifted": "で" + }, + { + "lifted": "きみ", + "unlifted": "君" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "ま", + "unlifted": "待っている" + }, + { + "lifted": null, + "unlifted": "よ" + }, + { + "lifted": null, + "unlifted": "と" + }, + { + "lifted": "い", + "unlifted": "言った" + } + ] + }, + { + "english": "I will tell the teacher all about it.", + "kanji": "先生にみんな言いつけてやるぞ。", + "kana": "せんせいにみんないいつけてやるぞ。", + "pieces": [ + { + "lifted": "せんせい", + "unlifted": "先生" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": null, + "unlifted": "みんな" + }, + { + "lifted": "い", + "unlifted": "言いつけて" + }, + { + "lifted": null, + "unlifted": "やる" + }, + { + "lifted": null, + "unlifted": "ぞ" + } + ] + }, + { + "english": "Everyone was silent as the teacher was announcing the results of the examination.", + "kanji": "先生が試験の結果を発表しているとき、みんなは沈黙していた。", + "kana": "せんせいがしけんのけっかをはっぴょうしているとき、みんなはちんもくしていた。", + "pieces": [ + { + "lifted": "せんせい", + "unlifted": "先生" + }, + { + "lifted": null, + "unlifted": "が" + }, + { + "lifted": "しけん", + "unlifted": "試験" + }, + { + "lifted": null, + "unlifted": "の" + }, + { + "lifted": "けっか", + "unlifted": "結果" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "はっぴょう", + "unlifted": "発表" + }, + { + "lifted": null, + "unlifted": "している" + }, + { + "lifted": null, + "unlifted": "とき" }, { "lifted": null, @@ -1118,20 +807,23 @@ "unlifted": "は" }, { - "lifted": "ひとり", - "unlifted": "一人" + "lifted": "ちんもく", + "unlifted": "沈黙" }, { "lifted": null, - "unlifted": "の" - }, + "unlifted": "していた" + } + ] + }, + { + "english": "Not all teachers behave like that.", + "kanji": "先生がみんなそんなふうにふるまうわけではない。", + "kana": "せんせいがみんなそんなふうにふるまうわけではない。", + "pieces": [ { - "lifted": "ため", - "unlifted": "為に" - }, - { - "lifted": null, - "unlifted": "それ" + "lifted": "せんせい", + "unlifted": "先生" }, { "lifted": null, @@ -1139,34 +831,38 @@ }, { "lifted": null, - "unlifted": "チームプレイ" + "unlifted": "みんな" }, { "lifted": null, - "unlifted": "だ" + "unlifted": "そんなふうに" + }, + { + "lifted": null, + "unlifted": "ふるまう" + }, + { + "lifted": null, + "unlifted": "わけではない" } ] }, { - "english": "Guys, I'll do my utmost to back you up. We'll make this event a success no matter what!", - "kanji": "みんな、俺も全力でフォローする。このイベントかならず成功させるぞ。", - "kana": "みんな、おれもぜんりょくでフォローする。このイベントかならずせいこうさせるぞ。", + "english": "Rabbi, that man who was with you on the other side of the Jordan - the one you testified about - well, he is baptizing, and everyone is going to him.", + "kanji": "先生、ごらん下さい。ヨルダンの向こうであなたと一緒にいたことがあり、そして、あなたがあかしをしておられたあのかたが、バプテスマを授けており、皆の者が、そのかたのところへ出かけています。", + "kana": "せんせい、ごらん下さい。ヨルダンの向こうであなたといっしょにいたことがあり、そして、あなたがあかしをしておられたあのかたが、バプテスマを授けており、皆の者が、そのかたのところへ出かけています。", "pieces": [ { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": "おれ", - "unlifted": "俺" + "lifted": "せんせい", + "unlifted": "先生" }, { "lifted": null, - "unlifted": "も" + "unlifted": "ヨルダン" }, { - "lifted": "ぜんりょく", - "unlifted": "全力" + "lifted": null, + "unlifted": "の" }, { "lifted": null, @@ -1174,39 +870,18 @@ }, { "lifted": null, - "unlifted": "フォロー" + "unlifted": "あなた" }, { "lifted": null, - "unlifted": "する" + "unlifted": "と" }, { - "lifted": null, - "unlifted": "この" - }, - { - "lifted": null, - "unlifted": "イベント" - }, - { - "lifted": null, - "unlifted": "かならず" - }, - { - "lifted": "せいこう", - "unlifted": "成功" - }, - { - "lifted": null, - "unlifted": "させる" - }, - { - "lifted": null, - "unlifted": "ぞ" + "lifted": "いっしょ", + "unlifted": "一緒に" } ] } ], - "uri": "https://jisho.org/search/%E7%9A%86%23sentences", - "phrase": "皆" + "uri": "https://jisho.org/search/%E7%9A%86%23sentences" } \ No newline at end of file diff --git a/test/example_test_cases/4.json b/test/example_test_cases/4.json index 9a37b84..e051fa3 100644 --- a/test/example_test_cases/4.json +++ b/test/example_test_cases/4.json @@ -2,6 +2,5 @@ "query": "ネガティブ", "found": false, "results": [], - "uri": "https://jisho.org/search/%E3%83%8D%E3%82%AC%E3%83%86%E3%82%A3%E3%83%96%23sentences", - "phrase": "ネガティブ" + "uri": "https://jisho.org/search/%E3%83%8D%E3%82%AC%E3%83%86%E3%82%A3%E3%83%96%23sentences" } \ No newline at end of file diff --git a/test/example_test_cases/5.json b/test/example_test_cases/5.json index afc70ea..7cdb2e5 100644 --- a/test/example_test_cases/5.json +++ b/test/example_test_cases/5.json @@ -2,6 +2,5 @@ "query": "grlgmregmneriireg", "found": false, "results": [], - "uri": "https://jisho.org/search/grlgmregmneriireg%23sentences", - "phrase": "grlgmregmneriireg" + "uri": "https://jisho.org/search/grlgmregmneriireg%23sentences" } \ No newline at end of file diff --git a/test/kanji_test_cases/0.json b/test/kanji_test_cases/0.json index ebc1c6a..7db2fa3 100644 --- a/test/kanji_test_cases/0.json +++ b/test/kanji_test_cases/0.json @@ -1,66 +1,68 @@ { "query": "車", "found": true, - "taughtIn": "grade 1", - "jlptLevel": "N5", - "newspaperFrequencyRank": 333, - "strokeCount": 7, - "meaning": "car", - "kunyomi": [ - "くるま" - ], - "onyomi": [ - "シャ" - ], - "onyomiExamples": [ - { - "example": "車", - "reading": "シャ", - "meaning": "car, vehicle" + "data": { + "taughtIn": "grade 1", + "jlptLevel": "N5", + "newspaperFrequencyRank": 333, + "strokeCount": 7, + "meaning": "car", + "kunyomi": [ + "くるま" + ], + "onyomi": [ + "シャ" + ], + "onyomiExamples": [ + { + "example": "車", + "reading": "シャ", + "meaning": "car, vehicle" + }, + { + "example": "車検", + "reading": "シャケン", + "meaning": "vehicle inspection" + }, + { + "example": "見切り発車", + "reading": "ミキリハッシャ", + "meaning": "starting a train (or bus, etc.) before all the passengers are on board, making a snap decision, starting an action without considering objections to it any longer" + }, + { + "example": "軽自動車", + "reading": "ケイジドウシャ", + "meaning": "light motor vehicle (up to 660cc and 64bhp), k-car, kei car" + } + ], + "kunyomiExamples": [ + { + "example": "車", + "reading": "くるま", + "meaning": "car, automobile, vehicle, wheel" + }, + { + "example": "車椅子", + "reading": "くるまいす", + "meaning": "wheelchair, folding push-chair" + }, + { + "example": "火の車", + "reading": "ひのくるま", + "meaning": "fiery chariot (which carries the souls of sinners into hell), desperate financial situation, dire straits" + } + ], + "radical": { + "symbol": "車", + "forms": [], + "meaning": "cart, car" }, - { - "example": "車検", - "reading": "シャケン", - "meaning": "vehicle inspection" - }, - { - "example": "見切り発車", - "reading": "ミキリハッシャ", - "meaning": "starting a train (or bus, etc.) before all the passengers are on board, making a snap decision, starting an action without considering objections to it any longer" - }, - { - "example": "軽自動車", - "reading": "ケイジドウシャ", - "meaning": "light motor vehicle (up to 660cc and 64bhp), k-car, kei car" - } - ], - "kunyomiExamples": [ - { - "example": "車", - "reading": "くるま", - "meaning": "car, automobile, vehicle, wheel" - }, - { - "example": "車椅子", - "reading": "くるまいす", - "meaning": "wheelchair, folding push-chair" - }, - { - "example": "火の車", - "reading": "ひのくるま", - "meaning": "fiery chariot (which carries the souls of sinners into hell), desperate financial situation, dire straits" - } - ], - "radical": { - "symbol": "車", - "forms": null, - "meaning": "cart, car" - }, - "parts": [ - "車" - ], - "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/36554_frames.png", - "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/08eca.svg", - "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/8eca.gif", - "uri": "https://jisho.org/search/%E8%BB%8A%23kanji" + "parts": [ + "車" + ], + "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/36554_frames.png", + "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/08eca.svg", + "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/8eca.gif", + "uri": "https://jisho.org/search/%E8%BB%8A%23kanji" + } } \ No newline at end of file diff --git a/test/kanji_test_cases/1.json b/test/kanji_test_cases/1.json index b0a1c9e..0312571 100644 --- a/test/kanji_test_cases/1.json +++ b/test/kanji_test_cases/1.json @@ -1,125 +1,127 @@ { "query": "家", "found": true, - "taughtIn": "grade 2", - "jlptLevel": "N4", - "newspaperFrequencyRank": 133, - "strokeCount": 10, - "meaning": "house, home, family, professional, expert, performer", - "kunyomi": [ - "いえ", - "や", - "うち" - ], - "onyomi": [ - "カ", - "ケ" - ], - "onyomiExamples": [ - { - "example": "家", - "reading": "カ", - "meaning": "-ist, -er" + "data": { + "taughtIn": "grade 2", + "jlptLevel": "N4", + "newspaperFrequencyRank": 133, + "strokeCount": 10, + "meaning": "house, home, family, professional, expert, performer", + "kunyomi": [ + "いえ", + "や", + "うち" + ], + "onyomi": [ + "カ", + "ケ" + ], + "onyomiExamples": [ + { + "example": "家", + "reading": "カ", + "meaning": "-ist, -er" + }, + { + "example": "家屋", + "reading": "カオク", + "meaning": "house, building" + }, + { + "example": "研究家", + "reading": "ケンキュウカ", + "meaning": "researcher, student (of)" + }, + { + "example": "活動家", + "reading": "カツドウカ", + "meaning": "activist" + }, + { + "example": "家", + "reading": "ケ", + "meaning": "house (e.g. of Tokugawa), family" + }, + { + "example": "家来", + "reading": "ケライ", + "meaning": "retainer, retinue, servant" + }, + { + "example": "本家", + "reading": "ホンケ", + "meaning": "head house (family), birthplace, originator" + }, + { + "example": "公家", + "reading": "クゲ", + "meaning": "court noble, nobility, Imperial Court" + } + ], + "kunyomiExamples": [ + { + "example": "家", + "reading": "いえ", + "meaning": "house, residence, dwelling, family, household, lineage, family name" + }, + { + "example": "家主", + "reading": "やぬし", + "meaning": "landlord, landlady, house owner, home owner, head of the household" + }, + { + "example": "本家", + "reading": "ほんけ", + "meaning": "head house (family), birthplace, originator" + }, + { + "example": "小家", + "reading": "こいえ", + "meaning": "small and simple home" + }, + { + "example": "屋", + "reading": "や", + "meaning": "(something) shop, somebody who sells (something) or works as (something), somebody with a (certain) personality trait, house, roof" + }, + { + "example": "家内", + "reading": "かない", + "meaning": "(my) wife, inside the home, one's family" + }, + { + "example": "長屋", + "reading": "ながや", + "meaning": "tenement house, row house" + }, + { + "example": "本家", + "reading": "ほんけ", + "meaning": "head house (family), birthplace, originator" + }, + { + "example": "家", + "reading": "うち", + "meaning": "house, one's house, one's home, one's family, one's household" + }, + { + "example": "家中", + "reading": "うちじゅう", + "meaning": "whole family, entire family, all (members of) the family, all over the house, throughout the house, retainer of a daimyo, feudal domain, clan" + } + ], + "radical": { + "symbol": "宀", + "forms": [], + "meaning": "roof" }, - { - "example": "家屋", - "reading": "カオク", - "meaning": "house, building" - }, - { - "example": "研究家", - "reading": "ケンキュウカ", - "meaning": "researcher, student (of)" - }, - { - "example": "活動家", - "reading": "カツドウカ", - "meaning": "activist" - }, - { - "example": "家", - "reading": "ケ", - "meaning": "house (e.g. of Tokugawa), family" - }, - { - "example": "家来", - "reading": "ケライ", - "meaning": "retainer, retinue, servant" - }, - { - "example": "本家", - "reading": "ホンケ", - "meaning": "head house (family), birthplace, originator" - }, - { - "example": "公家", - "reading": "クゲ", - "meaning": "court noble, nobility, Imperial Court" - } - ], - "kunyomiExamples": [ - { - "example": "家", - "reading": "いえ", - "meaning": "house, residence, dwelling, family, household, lineage, family name" - }, - { - "example": "家主", - "reading": "やぬし", - "meaning": "landlord, landlady, house owner, home owner, head of the household" - }, - { - "example": "本家", - "reading": "ほんけ", - "meaning": "head house (family), birthplace, originator" - }, - { - "example": "小家", - "reading": "こいえ", - "meaning": "small and simple home" - }, - { - "example": "屋", - "reading": "や", - "meaning": "(something) shop, somebody who sells (something) or works as (something), somebody with a (certain) personality trait, house, roof" - }, - { - "example": "家内", - "reading": "かない", - "meaning": "(my) wife, inside the home, one's family" - }, - { - "example": "長屋", - "reading": "ながや", - "meaning": "tenement house, row house" - }, - { - "example": "本家", - "reading": "ほんけ", - "meaning": "head house (family), birthplace, originator" - }, - { - "example": "家", - "reading": "うち", - "meaning": "house, home (one's own), (one's) family, (one's) household" - }, - { - "example": "家中", - "reading": "うちじゅう", - "meaning": "whole family, all (members of) the family, all over the house, retainer of a daimyo, feudal domain, clan" - } - ], - "radical": { - "symbol": "宀", - "forms": null, - "meaning": "roof" - }, - "parts": [ - "宀", - "豕" - ], - "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/23478_frames.png", - "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/05bb6.svg", - "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/5bb6.gif", - "uri": "https://jisho.org/search/%E5%AE%B6%23kanji" + "parts": [ + "宀", + "豕" + ], + "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/23478_frames.png", + "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/05bb6.svg", + "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/5bb6.gif", + "uri": "https://jisho.org/search/%E5%AE%B6%23kanji" + } } \ No newline at end of file diff --git a/test/kanji_test_cases/2.json b/test/kanji_test_cases/2.json index 6c4e8e2..56f4907 100644 --- a/test/kanji_test_cases/2.json +++ b/test/kanji_test_cases/2.json @@ -1,97 +1,99 @@ { "query": "楽", "found": true, - "taughtIn": "grade 2", - "jlptLevel": "N4", - "newspaperFrequencyRank": 373, - "strokeCount": 13, - "meaning": "music, comfort, ease", - "kunyomi": [ - "たの.しい", - "たの.しむ", - "この.む" - ], - "onyomi": [ - "ガク", - "ラク", - "ゴウ" - ], - "onyomiExamples": [ - { - "example": "楽団", - "reading": "ガクダン", - "meaning": "orchestra, band" + "data": { + "taughtIn": "grade 2", + "jlptLevel": "N4", + "newspaperFrequencyRank": 373, + "strokeCount": 13, + "meaning": "music, comfort, ease", + "kunyomi": [ + "たの.しい", + "たの.しむ", + "この.む" + ], + "onyomi": [ + "ガク", + "ラク", + "ゴウ" + ], + "onyomiExamples": [ + { + "example": "楽", + "reading": "ガク", + "meaning": "music, old Japanese court music, gagaku" + }, + { + "example": "楽章", + "reading": "ガクショウ", + "meaning": "(musical) movement" + }, + { + "example": "邦楽", + "reading": "ホウガク", + "meaning": "Japanese music (esp. traditional Japanese music)" + }, + { + "example": "室内楽", + "reading": "シツナイガク", + "meaning": "chamber music" + }, + { + "example": "楽", + "reading": "ラク", + "meaning": "comfort, ease, relief, (at) peace, relaxation, easy, simple, without trouble, without hardships, (economically) comfortable, raku pottery, sukha (happiness)" + }, + { + "example": "楽園", + "reading": "ラクエン", + "meaning": "paradise, Eden, Elysium" + }, + { + "example": "千秋楽", + "reading": "センシュウラク", + "meaning": "concluding festivities, concluding program, concluding programme, final day of a tournament" + }, + { + "example": "行楽", + "reading": "コウラク", + "meaning": "outing, excursion, pleasure trip, going on a picnic" + }, + { + "example": "猿楽", + "reading": "サルガク", + "meaning": "sarugaku (form of theatre popular in Japan during the 11th to 14th centuries), noh, fooling around" + } + ], + "kunyomiExamples": [ + { + "example": "楽しい", + "reading": "たのしい", + "meaning": "enjoyable, fun, pleasant, happy, delightful" + }, + { + "example": "楽しい思い出", + "reading": "たのしいおもいで", + "meaning": "happy memory, sweet memory" + }, + { + "example": "楽しむ", + "reading": "たのしむ", + "meaning": "to enjoy (oneself)" + } + ], + "radical": { + "symbol": "木", + "forms": [], + "meaning": "tree" }, - { - "example": "楽章", - "reading": "ガクショウ", - "meaning": "(musical) movement" - }, - { - "example": "邦楽", - "reading": "ホウガク", - "meaning": "Japanese music (esp. traditional Japanese music)" - }, - { - "example": "室内楽", - "reading": "シツナイガク", - "meaning": "chamber music" - }, - { - "example": "楽", - "reading": "ラク", - "meaning": "comfort, ease, relief, (at) peace, relaxation, easy, simple, without trouble, without hardships, (economically) comfortable, raku pottery" - }, - { - "example": "楽園", - "reading": "ラクエン", - "meaning": "pleasure garden, paradise" - }, - { - "example": "千秋楽", - "reading": "センシュウラク", - "meaning": "concluding festivities, concluding program, concluding programme, final day of a tournament" - }, - { - "example": "行楽", - "reading": "コウラク", - "meaning": "outing, excursion, pleasure trip, going on a picnic" - }, - { - "example": "猿楽", - "reading": "サルガク", - "meaning": "sarugaku (form of theatre popular in Japan during the 11th to 14th centuries), noh, fooling around" - } - ], - "kunyomiExamples": [ - { - "example": "楽しい", - "reading": "たのしい", - "meaning": "enjoyable, fun, pleasant, happy, delightful" - }, - { - "example": "楽しい思い出", - "reading": "たのしいおもいで", - "meaning": "happy memory, sweet memory" - }, - { - "example": "楽しむ", - "reading": "たのしむ", - "meaning": "to enjoy (oneself)" - } - ], - "radical": { - "symbol": "木", - "forms": null, - "meaning": "tree" - }, - "parts": [ - "冫", - "木", - "白" - ], - "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/27005_frames.png", - "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/0697d.svg", - "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/697d.gif", - "uri": "https://jisho.org/search/%E6%A5%BD%23kanji" + "parts": [ + "冫", + "木", + "白" + ], + "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/27005_frames.png", + "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/0697d.svg", + "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/697d.gif", + "uri": "https://jisho.org/search/%E6%A5%BD%23kanji" + } } \ No newline at end of file diff --git a/test/kanji_test_cases/3.json b/test/kanji_test_cases/3.json index 4c37adb..db84370 100644 --- a/test/kanji_test_cases/3.json +++ b/test/kanji_test_cases/3.json @@ -1,19 +1,5 @@ { "query": "極上", "found": false, - "taughtIn": null, - "jlptLevel": null, - "newspaperFrequencyRank": null, - "strokeCount": null, - "meaning": null, - "kunyomi": null, - "onyomi": null, - "onyomiExamples": null, - "kunyomiExamples": null, - "radical": null, - "parts": null, - "strokeOrderDiagramUri": null, - "strokeOrderSvgUri": null, - "strokeOrderGifUri": null, - "uri": null + "data": null } \ No newline at end of file diff --git a/test/kanji_test_cases/4.json b/test/kanji_test_cases/4.json index d841c96..b7c4701 100644 --- a/test/kanji_test_cases/4.json +++ b/test/kanji_test_cases/4.json @@ -1,53 +1,55 @@ { "query": "贄", "found": true, - "taughtIn": null, - "jlptLevel": null, - "newspaperFrequencyRank": null, - "strokeCount": 18, - "meaning": "offering, sacrifice", - "kunyomi": [ - "にえ" - ], - "onyomi": [ - "シ" - ], - "onyomiExamples": [], - "kunyomiExamples": [ - { - "example": "贄", - "reading": "にえ", - "meaning": "offering (to the gods, emperor, etc.), gift, sacrifice" + "data": { + "taughtIn": null, + "jlptLevel": null, + "newspaperFrequencyRank": null, + "strokeCount": 18, + "meaning": "offering, sacrifice", + "kunyomi": [ + "にえ" + ], + "onyomi": [ + "シ" + ], + "onyomiExamples": [], + "kunyomiExamples": [ + { + "example": "贄", + "reading": "にえ", + "meaning": "offering (to the gods, emperor, etc.), gift, sacrifice" + }, + { + "example": "早贄", + "reading": "はやにえ", + "meaning": "butcher-bird prey impaled on twigs, thorns, etc. for later consumption, first offering of the season" + }, + { + "example": "百舌の早贄", + "reading": "もずのはやにえ", + "meaning": "butcher-bird prey impaled on twigs, thorns, etc. for later consumption" + } + ], + "radical": { + "symbol": "貝", + "forms": [], + "meaning": "shell" }, - { - "example": "早贄", - "reading": "はやにえ", - "meaning": "butcher-bird prey impaled on twigs, thorns, etc. for later consumption, first offering of the season" - }, - { - "example": "百舌の早贄", - "reading": "もずのはやにえ", - "meaning": "butcher-bird prey impaled on twigs, thorns, etc. for later consumption" - } - ], - "radical": { - "symbol": "貝", - "forms": null, - "meaning": "shell" - }, - "parts": [ - "ハ", - "丶", - "九", - "亠", - "十", - "目", - "立", - "貝", - "辛" - ], - "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/36100_frames.png", - "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/08d04.svg", - "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/8d04.gif", - "uri": "https://jisho.org/search/%E8%B4%84%23kanji" + "parts": [ + "ハ", + "丶", + "九", + "亠", + "十", + "目", + "立", + "貝", + "辛" + ], + "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/36100_frames.png", + "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/08d04.svg", + "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/8d04.gif", + "uri": "https://jisho.org/search/%E8%B4%84%23kanji" + } } \ No newline at end of file diff --git a/test/kanji_test_cases/5.json b/test/kanji_test_cases/5.json index 5d3c8c7..4d4efce 100644 --- a/test/kanji_test_cases/5.json +++ b/test/kanji_test_cases/5.json @@ -1,19 +1,5 @@ { "query": "ネガティブ", "found": false, - "taughtIn": null, - "jlptLevel": null, - "newspaperFrequencyRank": null, - "strokeCount": null, - "meaning": null, - "kunyomi": null, - "onyomi": null, - "onyomiExamples": null, - "kunyomiExamples": null, - "radical": null, - "parts": null, - "strokeOrderDiagramUri": null, - "strokeOrderSvgUri": null, - "strokeOrderGifUri": null, - "uri": null + "data": null } \ No newline at end of file diff --git a/test/kanji_test_cases/6.json b/test/kanji_test_cases/6.json index 29815f2..b350800 100644 --- a/test/kanji_test_cases/6.json +++ b/test/kanji_test_cases/6.json @@ -1,19 +1,5 @@ { "query": "wegmwrlgkrgmg", "found": false, - "taughtIn": null, - "jlptLevel": null, - "newspaperFrequencyRank": null, - "strokeCount": null, - "meaning": null, - "kunyomi": null, - "onyomi": null, - "onyomiExamples": null, - "kunyomiExamples": null, - "radical": null, - "parts": null, - "strokeOrderDiagramUri": null, - "strokeOrderSvgUri": null, - "strokeOrderGifUri": null, - "uri": null + "data": null } \ No newline at end of file diff --git a/test/kanji_test_cases/7.json b/test/kanji_test_cases/7.json index 736c73d..01996ef 100644 --- a/test/kanji_test_cases/7.json +++ b/test/kanji_test_cases/7.json @@ -1,75 +1,77 @@ { "query": "水", "found": true, - "taughtIn": "grade 1", - "jlptLevel": "N5", - "newspaperFrequencyRank": 223, - "strokeCount": 4, - "meaning": "water", - "kunyomi": [ - "みず", - "みず-" - ], - "onyomi": [ - "スイ" - ], - "onyomiExamples": [ - { - "example": "水", - "reading": "スイ", - "meaning": "Wednesday, shaved ice (served with flavored syrup), water (fifth of the five elements)" - }, - { - "example": "水位", - "reading": "スイイ", - "meaning": "water level" - }, - { - "example": "用水", - "reading": "ヨウスイ", - "meaning": "irrigation water, water for fire, city water, cistern water" - }, - { - "example": "浄水", - "reading": "ジョウスイ", - "meaning": "clean water" - } - ], - "kunyomiExamples": [ - { - "example": "水", - "reading": "みず", - "meaning": "water (esp. cool, fresh water, e.g. drinking water), fluid (esp. in an animal tissue), liquid, flood, floodwaters, water offered to wrestlers just prior to a bout, break granted to wrestlers engaged in a prolonged bout" - }, - { - "example": "水揚げ", - "reading": "みずあげ", - "meaning": "landing, unloading (e.g. a ship), catch (of fish), takings, sales (of a shop), defloration (e.g. of a geisha), preservation (of cut flowers, in ikebana)" - }, - { - "example": "飲み水", - "reading": "のみみず", - "meaning": "drinking water, potable water" - }, - { - "example": "呼び水", - "reading": "よびみず", - "meaning": "pump-priming, rousing, stimulation" - } - ], - "radical": { - "symbol": "水", - "forms": [ - "氵", - "氺" + "data": { + "taughtIn": "grade 1", + "jlptLevel": "N5", + "newspaperFrequencyRank": 223, + "strokeCount": 4, + "meaning": "water", + "kunyomi": [ + "みず", + "みず-" ], - "meaning": "water" - }, - "parts": [ - "水" - ], - "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/27700_frames.png", - "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/06c34.svg", - "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/6c34.gif", - "uri": "https://jisho.org/search/%E6%B0%B4%23kanji" + "onyomi": [ + "スイ" + ], + "onyomiExamples": [ + { + "example": "水", + "reading": "スイ", + "meaning": "Wednesday, shaved ice (served with flavored syrup), water (fifth of the five elements)" + }, + { + "example": "水位", + "reading": "スイイ", + "meaning": "water level" + }, + { + "example": "用水", + "reading": "ヨウスイ", + "meaning": "irrigation water, water for fire, city water, cistern water" + }, + { + "example": "浄水", + "reading": "ジョウスイ", + "meaning": "clean water" + } + ], + "kunyomiExamples": [ + { + "example": "水", + "reading": "みず", + "meaning": "water (esp. cool, fresh water, e.g. drinking water), fluid (esp. in an animal tissue), liquid, flood, floodwaters, water offered to wrestlers just prior to a bout, break granted to wrestlers engaged in a prolonged bout" + }, + { + "example": "水揚げ", + "reading": "みずあげ", + "meaning": "landing, unloading (e.g. a ship), catch (of fish), takings, sales (of a shop), defloration (e.g. of a geisha), preservation (of cut flowers, in ikebana)" + }, + { + "example": "飲み水", + "reading": "のみみず", + "meaning": "drinking water, potable water" + }, + { + "example": "呼び水", + "reading": "よびみず", + "meaning": "pump-priming, rousing, stimulation" + } + ], + "radical": { + "symbol": "水", + "forms": [ + "氵", + "氺" + ], + "meaning": "water" + }, + "parts": [ + "水" + ], + "strokeOrderDiagramUri": "https://classic.jisho.org/static/images/stroke_diagrams/27700_frames.png", + "strokeOrderSvgUri": "https://d1w6u4xc3l95km.cloudfront.net/kanji-2015-03/06c34.svg", + "strokeOrderGifUri": "https://raw.githubusercontent.com/mistval/kanji_images/master/gifs/6c34.gif", + "uri": "https://jisho.org/search/%E6%B0%B4%23kanji" + } } \ No newline at end of file diff --git a/test/phrase_scrape_test_cases/0.json b/test/phrase_scrape_test_cases/0.json index 0fa1e1d..65ba377 100644 --- a/test/phrase_scrape_test_cases/0.json +++ b/test/phrase_scrape_test_cases/0.json @@ -1,97 +1,105 @@ { "found": true, "query": "車", - "uri": "https://jisho.org/word/%E8%BB%8A", - "tags": [ - "Common word", - "JLPT N5", - "Wanikani level 4" - ], - "meanings": [ - { - "seeAlsoTerms": [], - "sentences": [ - { - "english": "You cannot be too careful when you drive a car.", - "japanese": "車を運転する時はいくら注意してもしすぎることはない。", - "pieces": [ - { - "lifted": "くるま", - "unlifted": "車" - }, - { - "lifted": null, - "unlifted": "を" - }, - { - "lifted": "うんてん", - "unlifted": "運転" - }, - { - "lifted": null, - "unlifted": "する" - }, - { - "lifted": "とき", - "unlifted": "時" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "いくら" - }, - { - "lifted": "ちゅうい", - "unlifted": "注意" - }, - { - "lifted": null, - "unlifted": "して" - }, - { - "lifted": null, - "unlifted": "も" - }, - { - "lifted": null, - "unlifted": "しすぎる" - }, - { - "lifted": null, - "unlifted": "こと" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "ない" - } - ] - } - ], - "definition": "car; automobile; vehicle", - "supplemental": [], - "definitionAbstract": null, - "tags": [ - "noun" - ] - }, - { - "seeAlsoTerms": [], - "sentences": [], - "definition": "wheel", - "supplemental": [], - "definitionAbstract": null, - "tags": [ - "noun" - ] - } - ], - "otherForms": [], - "notes": [] + "data": { + "uri": "https://jisho.org/word/%E8%BB%8A", + "tags": [ + "Common word", + "JLPT N5", + "Wanikani level 4" + ], + "meanings": [ + { + "seeAlsoTerms": [], + "sentences": [ + { + "english": "You cannot be too careful when you drive a car.", + "japanese": "車を運転する時はいくら注意してもしすぎることはない。", + "pieces": [ + { + "lifted": "くるま", + "unlifted": "車" + }, + { + "lifted": null, + "unlifted": "を" + }, + { + "lifted": "うんてん", + "unlifted": "運転" + }, + { + "lifted": null, + "unlifted": "する" + }, + { + "lifted": "とき", + "unlifted": "時" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "いくら" + }, + { + "lifted": "ちゅうい", + "unlifted": "注意" + }, + { + "lifted": null, + "unlifted": "して" + }, + { + "lifted": null, + "unlifted": "も" + }, + { + "lifted": null, + "unlifted": "しすぎる" + }, + { + "lifted": null, + "unlifted": "こと" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "ない" + } + ] + } + ], + "definition": "car; automobile; vehicle", + "supplemental": [], + "definitionAbstract": null, + "tags": [] + }, + { + "seeAlsoTerms": [], + "sentences": [], + "definition": "wheel", + "supplemental": [], + "definitionAbstract": null, + "tags": [] + } + ], + "otherForms": [], + "audio": [ + { + "uri": "https://d1vjc5dkcd3yh2.cloudfront.net/audio/7f47c2a8e633ca3a79ac199f55a212dd.mp3", + "mimetype": "audio/mpeg" + }, + { + "uri": "https://d1vjc5dkcd3yh2.cloudfront.net/audio_ogg/7f47c2a8e633ca3a79ac199f55a212dd.ogg", + "mimetype": "audio/ogg" + } + ], + "notes": [] + } } \ No newline at end of file diff --git a/test/phrase_scrape_test_cases/1.json b/test/phrase_scrape_test_cases/1.json index 2ab07b4..dc84fb9 100644 --- a/test/phrase_scrape_test_cases/1.json +++ b/test/phrase_scrape_test_cases/1.json @@ -1,37 +1,36 @@ { "found": true, "query": "日本人", - "uri": "https://jisho.org/word/%E6%97%A5%E6%9C%AC%E4%BA%BA", - "tags": [ - "Common word" - ], - "meanings": [ - { - "seeAlsoTerms": [], - "sentences": [], - "definition": "Japanese person; Japanese people", - "supplemental": [], - "definitionAbstract": null, - "tags": [ - "noun" - ] - }, - { - "seeAlsoTerms": [], - "sentences": [], - "definition": "Japanese people", - "supplemental": [], - "definitionAbstract": "The Japanese people are a nationality originating in the Japanese archipelago and are the predominant ethnic group of Japan. Worldwide, approximately 130 million people are of Japanese descent; of these, approximately 127 million are residents of Japan. People of Japanese ancestry who live in other countries are referred to as nikkeijin . The term ethnic Japanese may also be used in some contexts to refer to a locus of ethnic groups including the Yamato, Ainu and Ryukyuan people.", - "tags": [ - "wikipedia definition" - ] - } - ], - "otherForms": [ - { - "kanji": "日本人", - "kana": "にっぽんじん" - } - ], - "notes": [] + "data": { + "uri": "https://jisho.org/word/%E6%97%A5%E6%9C%AC%E4%BA%BA", + "tags": [ + "Common word" + ], + "meanings": [ + { + "seeAlsoTerms": [], + "sentences": [], + "definition": "Japanese person; Japanese people", + "supplemental": [], + "definitionAbstract": null, + "tags": [] + }, + { + "seeAlsoTerms": [], + "sentences": [], + "definition": "Japanese people", + "supplemental": [], + "definitionAbstract": "The Japanese people are a nationality originating in the Japanese archipelago and are the predominant ethnic group of Japan. Worldwide, approximately 130 million people are of Japanese descent; of these, approximately 127 million are residents of Japan. People of Japanese ancestry who live in other countries are referred to as nikkeijin . The term ethnic Japanese may also be used in some contexts to refer to a locus of ethnic groups including the Yamato, Ainu and Ryukyuan people.", + "tags": [] + } + ], + "otherForms": [ + { + "kanji": "日本人", + "kana": "にっぽんじん" + } + ], + "audio": [], + "notes": [] + } } \ No newline at end of file diff --git a/test/phrase_scrape_test_cases/2.json b/test/phrase_scrape_test_cases/2.json index 3d2ed78..893d814 100644 --- a/test/phrase_scrape_test_cases/2.json +++ b/test/phrase_scrape_test_cases/2.json @@ -1,132 +1,101 @@ { "found": true, "query": "皆", - "uri": "https://jisho.org/word/%E7%9A%86", - "tags": [ - "Common word", - "JLPT N5" - ], - "meanings": [ - { - "seeAlsoTerms": [], - "sentences": [ - { - "english": "The people which were here have all gone.", - "japanese": "ここにいた人々はみんな行ってしまった。", - "pieces": [ - { - "lifted": null, - "unlifted": "ここ" - }, - { - "lifted": null, - "unlifted": "に" - }, - { - "lifted": null, - "unlifted": "いた" - }, - { - "lifted": "ひとびと", - "unlifted": "人々" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": "い", - "unlifted": "行って" - }, - { - "lifted": null, - "unlifted": "しまった" - } - ] - } - ], - "definition": "all; everyone; everybody", - "supplemental": [ - "Usually written using kana alone" - ], - "definitionAbstract": null, - "tags": [ - "adverb", - "noun" - ] - }, - { - "seeAlsoTerms": [], - "sentences": [ - { - "english": "All the dinner had been eaten before he came.", - "japanese": "ごちそうはみんな彼が来ないうちに食べられてしまった。", - "pieces": [ - { - "lifted": null, - "unlifted": "ごちそう" - }, - { - "lifted": null, - "unlifted": "は" - }, - { - "lifted": null, - "unlifted": "みんな" - }, - { - "lifted": "かれ", - "unlifted": "彼" - }, - { - "lifted": null, - "unlifted": "が" - }, - { - "lifted": "らい", - "unlifted": "来" - }, - { - "lifted": null, - "unlifted": "ないうちに" - }, - { - "lifted": "た", - "unlifted": "食べられて" - }, - { - "lifted": null, - "unlifted": "しまった" - } - ] - } - ], - "definition": "everything", - "supplemental": [ - "Usually written using kana alone" - ], - "definitionAbstract": null, - "tags": [ - "adverb", - "noun" - ] - } - ], - "otherForms": [ - { - "kanji": "皆んな", - "kana": "みんな" - }, - { - "kanji": "皆", - "kana": "みな" - } - ], - "notes": [ - "皆んな: Irregular okurigana usage." - ] + "data": { + "uri": "https://jisho.org/word/%E7%9A%86", + "tags": [ + "Common word", + "JLPT N5" + ], + "meanings": [ + { + "seeAlsoTerms": [], + "sentences": [ + { + "english": "She is loved by everybody.", + "japanese": "彼女はみんなに愛されている。", + "pieces": [ + { + "lifted": "かのじょ", + "unlifted": "彼女" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "みんな" + }, + { + "lifted": null, + "unlifted": "に" + }, + { + "lifted": "あい", + "unlifted": "愛されている" + } + ] + } + ], + "definition": "everyone; everybody; all", + "supplemental": [ + "Usually written using kana alone" + ], + "definitionAbstract": null, + "tags": [] + }, + { + "seeAlsoTerms": [], + "sentences": [ + { + "english": "The leaves have all fallen.", + "japanese": "木の葉はみんな落ちてしまった。", + "pieces": [ + { + "lifted": "このは", + "unlifted": "木の葉" + }, + { + "lifted": null, + "unlifted": "は" + }, + { + "lifted": null, + "unlifted": "みんな" + }, + { + "lifted": "お", + "unlifted": "落ちて" + }, + { + "lifted": null, + "unlifted": "しまった" + } + ] + } + ], + "definition": "everything; all", + "supplemental": [ + "Usually written using kana alone" + ], + "definitionAbstract": null, + "tags": [] + } + ], + "otherForms": [ + { + "kanji": "皆んな", + "kana": "みんな" + }, + { + "kanji": "皆", + "kana": "みな" + } + ], + "audio": [], + "notes": [ + "皆んな: Irregular okurigana usage." + ] + } } \ No newline at end of file diff --git a/test/phrase_scrape_test_cases/3.json b/test/phrase_scrape_test_cases/3.json index dcc45ae..c3016f4 100644 --- a/test/phrase_scrape_test_cases/3.json +++ b/test/phrase_scrape_test_cases/3.json @@ -1,69 +1,66 @@ { "found": true, "query": "ネガティブ", - "uri": "https://jisho.org/word/%E3%83%8D%E3%82%AC%E3%83%86%E3%82%A3%E3%83%96", - "tags": [ - "Common word" - ], - "meanings": [ - { - "seeAlsoTerms": [], - "sentences": [], - "definition": "negative (e.g. thinking)", - "supplemental": [ - "Antonym: ポジティブ" - ], - "definitionAbstract": null, - "tags": [ - "na-adjective" - ] - }, - { - "seeAlsoTerms": [], - "sentences": [], - "definition": "negative (photography)", - "supplemental": [], - "definitionAbstract": null, - "tags": [ - "noun" - ] - }, - { - "seeAlsoTerms": [ - "陰極" - ], - "sentences": [], - "definition": "negative (electrical polarity)", - "supplemental": [], - "definitionAbstract": null, - "tags": [ - "noun" - ] - }, - { - "seeAlsoTerms": [], - "sentences": [], - "definition": "Negative (Finnish band)", - "supplemental": [], - "definitionAbstract": "Negative is a Finnish glam rock band founded at the end of 1997. Members of Negative cite musical influence such as Guns N' Roses, Queen, and Hanoi Rocks. The band itself labels the music as ”emotional rock’n roll”.", - "tags": [ - "wikipedia definition" - ] - } - ], - "otherForms": [ - { - "kanji": "ネガティヴ", - "kana": null - }, - { - "kanji": "ネガチブ", - "kana": null - }, - { - "kanji": "ネガチィブ", - "kana": null - } - ], - "notes": [] + "data": { + "uri": "https://jisho.org/word/%E3%83%8D%E3%82%AC%E3%83%86%E3%82%A3%E3%83%96", + "tags": [ + "Common word" + ], + "meanings": [ + { + "seeAlsoTerms": [], + "sentences": [], + "definition": "negative (e.g. thinking)", + "supplemental": [ + "Antonym: ポジティブ" + ], + "definitionAbstract": null, + "tags": [] + }, + { + "seeAlsoTerms": [], + "sentences": [], + "definition": "negative", + "supplemental": [ + "Photography" + ], + "definitionAbstract": null, + "tags": [] + }, + { + "seeAlsoTerms": [ + "陰極" + ], + "sentences": [], + "definition": "negative (electrical polarity)", + "supplemental": [], + "definitionAbstract": null, + "tags": [] + }, + { + "seeAlsoTerms": [], + "sentences": [], + "definition": "Negative (Finnish band)", + "supplemental": [], + "definitionAbstract": "Negative is a Finnish glam rock band founded at the end of 1997. Members of Negative cite musical influence such as Guns N' Roses, Queen, and Hanoi Rocks. The band itself labels the music as ”emotional rock’n roll”.", + "tags": [] + } + ], + "otherForms": [ + { + "kanji": "ネガティヴ", + "kana": null + }, + { + "kanji": "ネガチブ", + "kana": null + }, + { + "kanji": "ネガチィブ", + "kana": null + } + ], + "audio": [], + "notes": [] + } } \ No newline at end of file diff --git a/test/phrase_scrape_test_cases/4.json b/test/phrase_scrape_test_cases/4.json index 43b08bc..eb7c0cb 100644 --- a/test/phrase_scrape_test_cases/4.json +++ b/test/phrase_scrape_test_cases/4.json @@ -1,9 +1,5 @@ { "found": false, "query": "grlgmregmneriireg", - "uri": null, - "tags": null, - "meanings": null, - "otherForms": null, - "notes": null + "data": null } \ No newline at end of file diff --git a/test/unofficial_jisho_api_test.dart b/test/unofficial_jisho_api_test.dart index 6283e6b..c0b7fa7 100644 --- a/test/unofficial_jisho_api_test.dart +++ b/test/unofficial_jisho_api_test.dart @@ -1,15 +1,17 @@ import 'dart:convert'; import 'dart:io'; -import 'package:path/path.dart' as path; -import 'package:unofficial_jisho_api/api.dart'; +import 'package:path/path.dart' as path; import 'package:test/test.dart'; +import 'package:unofficial_jisho_api/api.dart'; List getFilePaths(String dirname) { final currentdir = Directory.current.path; final testDir = path.join(currentdir, 'test', dirname); final filenames = Directory(testDir).listSync(); - return filenames.map((filename) => path.join(testDir, filename.path)).toList(); + return filenames + .map((filename) => path.join(testDir, filename.path)) + .toList(); } List getTestCases(String directoryName) { @@ -53,4 +55,4 @@ void main() { }); } }); -} \ No newline at end of file +}