jekyll-dictionaries 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c0764c62ab68f291ad64d37b37ea0af0e7e562e3d3a3ad3d275ba49957f20ca3
4
+ data.tar.gz: c551767a61e5bca0134f6e1e4f474dee01d834a24cb46af50d73f8922262215c
5
+ SHA512:
6
+ metadata.gz: 7f6d651e768b5701498d4e5cedd539d211eedce85140b1044a021f646933e19b993e8426c94f5fd95f5768da5050fbfaec984663ca41c4f682f7a1a3a0d92bdc
7
+ data.tar.gz: 11c1c8461223bb29e3d8ecd293ef277c8ff752d188bacc357117a69679bae9732e388a0ce7920dfa6e51deb5d4a776f94c5b04b356d5c7aafd3a9ab87c306d72
data/.DS_Store ADDED
Binary file
@@ -0,0 +1,11 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module version="4">
3
+ <component name="ModuleRunConfigurationManager">
4
+ <shared />
5
+ </component>
6
+ <component name="RakeTasksCache">
7
+ <option name="myRootTask">
8
+ <RakeTaskImpl id="rake" />
9
+ </option>
10
+ </component>
11
+ </module>
data/.idea/misc.xml ADDED
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="ProjectRootManager" version="2" project-jdk-name="RVM: ruby-2.6.2 [market_analytics]" project-jdk-type="RUBY_SDK" />
4
+ </project>
data/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,75 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="a0de0db4-04ba-4a6e-9544-85d905789a03" name="Changes" comment="">
8
+ <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
9
+ </list>
10
+ <option name="SHOW_DIALOG" value="false" />
11
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
12
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
13
+ <option name="LAST_RESOLUTION" value="IGNORE" />
14
+ </component>
15
+ <component name="Git.Settings">
16
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
17
+ </component>
18
+ <component name="MarkdownSettingsMigration">
19
+ <option name="stateVersion" value="1" />
20
+ </component>
21
+ <component name="ProjectId" id="2WEcjgC80wlCjXuxXvYFq2ebd1H" />
22
+ <component name="ProjectViewState">
23
+ <option name="hideEmptyMiddlePackages" value="true" />
24
+ <option name="showLibraryContents" value="true" />
25
+ </component>
26
+ <component name="PropertiesComponent">{
27
+ &quot;keyToString&quot;: {
28
+ &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
29
+ &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
30
+ &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
31
+ &quot;last_opened_file_path&quot;: &quot;/Users/s.ginkov/Work/Hinkou Labs/jekyll-dictionaries/spec/fixtures/jekyll&quot;,
32
+ &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
33
+ &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
34
+ &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
35
+ &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
36
+ &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
37
+ &quot;ruby.rails.projectView.checked&quot;: &quot;true&quot;,
38
+ &quot;ruby.structure.view.model.defaults.configured&quot;: &quot;true&quot;,
39
+ &quot;settings.editor.selected.configurable&quot;: &quot;org.jetbrains.plugins.ruby.settings.RubyActiveModuleSdkConfigurable&quot;,
40
+ &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
41
+ }
42
+ }</component>
43
+ <component name="RecentsManager">
44
+ <key name="CopyFile.RECENT_KEYS">
45
+ <recent name="$PROJECT_DIR$/spec/fixtures/jekyll" />
46
+ <recent name="$PROJECT_DIR$" />
47
+ <recent name="$PROJECT_DIR$/.idea" />
48
+ </key>
49
+ <key name="MoveFile.RECENT_KEYS">
50
+ <recent name="$PROJECT_DIR$/" />
51
+ <recent name="$PROJECT_DIR$/spec/fixtures/snapshots/pages" />
52
+ <recent name="$PROJECT_DIR$/spec/fixtures/jekyll" />
53
+ <recent name="$PROJECT_DIR$" />
54
+ <recent name="$PROJECT_DIR$/spec/fixtures/snapshots/api" />
55
+ </key>
56
+ </component>
57
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
58
+ <component name="SpringUtil" SPRING_PRE_LOADER_OPTION="true" RAKE_SPRING_PRE_LOADER_OPTION="true" RAILS_SPRING_PRE_LOADER_OPTION="true" />
59
+ <component name="TaskManager">
60
+ <task active="true" id="Default" summary="Default task">
61
+ <changelist id="a0de0db4-04ba-4a6e-9544-85d905789a03" name="Changes" comment="" />
62
+ <created>1696301317963</created>
63
+ <option name="number" value="Default" />
64
+ <option name="presentableId" value="Default" />
65
+ <updated>1696301317963</updated>
66
+ <workItem from="1696301319406" duration="9538000" />
67
+ <workItem from="1696310885150" duration="15107000" />
68
+ <workItem from="1696338033417" duration="6149000" />
69
+ </task>
70
+ <servers />
71
+ </component>
72
+ <component name="TypeScriptGeneratedFilesManager">
73
+ <option name="version" value="3" />
74
+ </component>
75
+ </project>
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/History.markdown ADDED
@@ -0,0 +1,3 @@
1
+ ## 0.1.0 / 2023-10-03
2
+
3
+ * Created a gem with basic dictionary support
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 hinkoulabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,483 @@
1
+ # Jekyll Dictionaries Plugin
2
+
3
+ Welcome to the Jekyll Dictionaries Plugin project! This open-source project allows you to create and share JSON dictionaries that can be accessed via a public API for language learning in mobile applications.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [Dictionaries Structure](#dictionaries-structure)
10
+ - [Dictionary Types](#dictionary-types)
11
+ - [1. Single Translation Dictionary](#1-single-translation-dictionary)
12
+ - [2. Multiple Translations Dictionary](#2-multiple-translations-dictionary)
13
+ - [Object Properties](#object-properties)
14
+ - [1. Dictionary Object](#1-dictionary-object)
15
+ - [2. Collection Object](#2-collection-object)
16
+ - [3. Folder Object](#3-folder-object)
17
+ - [Dictionary Types Examples](#dictionary-types-examples)
18
+ - [1. Single Translation Dictionary Example](#1-single-translation-dictionary-example)
19
+ - [2. Multiple Translations Dictionary Example](#2-multiple-translations-dictionary-example)
20
+ - [License](#license)
21
+
22
+ ## Installation
23
+
24
+ Add this line to your site's Gemfile:
25
+
26
+ ```ruby
27
+ gem 'jekyll-dictionaries'
28
+ ```
29
+
30
+ Generate 2 layouts for dictionary documentation and api:
31
+
32
+ **_layouts/dictionary_api.json:**
33
+
34
+ ```liquid
35
+ ---
36
+ ---
37
+ {% assign content = page.content | jsonify %}{% assign docPage = page.related_page %}{% if docPage %}{"docPath":"{{ docPage.url | absolute_url }}",{{ content | remove_first: '{' }}{% else %}{{ content }}{% endif %}
38
+ ```
39
+
40
+ **_layouts/dictionary.html:**
41
+
42
+ ```liquid
43
+ ---
44
+ layout: page
45
+ ---
46
+
47
+ <h1>Info</h1>
48
+ <table>
49
+ <tbody>
50
+ <tr>
51
+ <th>Name</th>
52
+ <td>{{ page.content.name }}</td>
53
+ </tr>
54
+ <tr>
55
+ <th>Version</th>
56
+ <td>{{ page.content.version }}</td>
57
+ </tr>
58
+ <tr>
59
+ <th>Learning</th>
60
+ <td>{{ page.content.learning }}</td>
61
+ </tr>
62
+
63
+ <tr>
64
+ <th>Translation Type</th>
65
+ <td>{{ page.content.translationType }}</td>
66
+ </tr>
67
+
68
+ {% if page.content.translationType == 'multiple' %}
69
+
70
+ <tr>
71
+ <th>Translations</th>
72
+ <td>{{ page.content.translations | join: ', ' }}</td>
73
+ </tr>
74
+ {% endif %}
75
+
76
+ {% assign apiPage = page.related_page %}
77
+
78
+ {% if apiPage %}
79
+
80
+ <tr>
81
+ <th> <a href="{{ apiPage.url | relative_url }}" target="_blank">API LINK</a> </th>
82
+ <td>
83
+ <button onclick="copyToClipboard('{{ apiPage.url | absolute_url }}')">Copy to Clipboard</button>
84
+ </td>
85
+ </tr>
86
+ {% endif %}
87
+
88
+
89
+ </tbody>
90
+ </table>
91
+
92
+ <script>
93
+ function copyToClipboard(text) {
94
+ // Copy the text inside the text field
95
+ navigator.clipboard.writeText(text);
96
+ }
97
+ </script>
98
+ ```
99
+
100
+ And then add this lines to your site's `_config.yml`:
101
+
102
+ ```yml
103
+ plugins:
104
+ - jekyll-dictionaries
105
+
106
+ dictionaries:
107
+ dictionary:
108
+ layout: dictionary
109
+ permalink: dictionaries/:name
110
+ dictionary_api:
111
+ layout: dictionary_api
112
+ permalink: api/dictionaries/:name.json
113
+ ```
114
+
115
+ ## Usage
116
+
117
+ The plugin will automatically generate dictionary and dictionary api pages for all dictionaries located into folder `_data/dictionaries` of jekyll project.
118
+
119
+ ## Dictionaries Structure
120
+
121
+ The dictionaries in this project have a specific structure that consists of the following components:
122
+
123
+ ### Root Directory
124
+
125
+ The root directory for dictionaries is `_data/dictionaries`. It contains JSON files that start with an underscore `_` as well as folders that have names similar to the files but without the underscore. These folders act as containers for dictionary collections and can be nested.
126
+
127
+ ### Collection Files
128
+
129
+ 1. **Any JSON File**: Any JSON file within a folder is detected as a collection file. A collection file is a JSON object that can be used to set translations.
130
+
131
+ 2. **"_metadata.json" (Optional)**: This file can be added inside nested folders to set folder details for the API. If this file is missing, the folder name will be used as the container name for the dictionaries in the API response. For example, if there is a folder named "greetings," and a developer wants to use a specific name for the folder in the API, they can add the file "_metadata.json" into the folder with data `{"name": "Greetings"}`. As a result, the plugin will generate an API where the folder name will be "Greetings."
132
+
133
+ ## Dictionary Types
134
+
135
+ This project supports two types of dictionaries:
136
+
137
+ ### 1. Single Translation Dictionary
138
+
139
+ A "single translation" dictionary is used to generate a dictionary for a selected learning language, with translations available in any other languages. The JSON structure for a "single translation" dictionary and its collections is as follows:
140
+
141
+ **_data/dictionaries/_single_dictionary.json:**
142
+
143
+ ```json
144
+ {
145
+ "version": "1.0.0",
146
+ "name": "Simple",
147
+ "translationType": "single",
148
+ "learning": "es"
149
+ }
150
+ ```
151
+
152
+ In this example, the learning language is set on the dictionary data with the "learning" field (using ISO 639-1 language codes).
153
+
154
+ **_data/dictionaries/single_dictionary/greetings.json:**
155
+
156
+ ```json
157
+ {
158
+ "name": "Greetings",
159
+ "type": "collection",
160
+ "data": [
161
+ {"learning":"¡Hola!", "primary":"Hello!"},
162
+ {"learning":"¡Buenos días!", "primary":"Good morning!", "notes": {"learning": "por la mañana", "primary": "at morning"}}
163
+ ]
164
+ }
165
+ ```
166
+
167
+ The collection contains an array property "data" with word translations. In this case, the learning language is specified for each translation entry, while the "primary" field represents the translation in the target language. Additionally, you can include "notes" related to learning and translations.
168
+
169
+ ### 2. Multiple Translations Dictionary
170
+
171
+ A "multiple translation" dictionary is used to generate a dictionary with multiple translations available simultaneously. The JSON structure for a "multiple translation" dictionary and its collections is as follows:
172
+
173
+ **_data/dictionaries/_multiple_dictionary.json:**
174
+
175
+ ```json
176
+ {
177
+ "version": "1.0.0",
178
+ "name": "Simple",
179
+ "translationType": "multiple",
180
+ "learning": "es",
181
+ "translations": ["en", "ru"]
182
+ }
183
+
184
+ ```
185
+
186
+ In this example, the learning language is set on the dictionary data with the "learning" field (using ISO 639-1 language codes). Multiple translation types are specified in the "translations" property (using ISO 639-1 language codes).
187
+
188
+ **_data/dictionaries/multiple_dictionary/greetings.json:**
189
+
190
+ ```json
191
+ {
192
+ "name": "Greetings",
193
+ "type": "collection",
194
+ "data": [
195
+ {"learning":"¡Hola!", "en":"Hello!", "ru": "Привет!"},
196
+ {"learning":"¡Buenos días!", "en":"Good morning!", "ru":"Доброе утро!", "notes": {"learning": "por la mañana", "en": "at morning", "ru": "говорят по утрам"}}
197
+ ]
198
+ }
199
+ ```
200
+
201
+ The collection contains an array property "data" with word translations. Each translation entry includes the learning language and multiple translations specified in the "translations" property. Additionally, you can include "notes" related to learning and translations for each entry.
202
+
203
+ ## Object Properties
204
+
205
+ ### 1. Dictionary Object
206
+
207
+ The dictionary object is a JSON object with the following properties:
208
+
209
+ | Property | Type | Description |
210
+ |------------------|----------|------------------------------------------|
211
+ | `name` | string | The name of the dictionary. (Required) |
212
+ | `translationType`| string | The type of translation ("single" or "multiple"). (Required) |
213
+ | `learning` | string | The learning language code, related to ISO 639-1 language codes. (Required) [ISO 639-1 Language Codes](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) |
214
+ | `version` | string | The version of the dictionary. (Optional) |
215
+ | `translations` | array | An array of ISO 639-1 language codes (required if `translationType` is "multiple"). |
216
+
217
+ ### 2. Collection Object
218
+
219
+ The collection object is a JSON object with the following properties based on the `translationType` of the dictionary:
220
+
221
+ #### If `translationType` is "single":
222
+
223
+ | Property | Type | Description |
224
+ |-------------|----------|------------------------------------------|
225
+ | `type` | string | The type of the collection ("folder"). (Required) |
226
+ | `learning` | string | The learning word or phrase. (Required) |
227
+ | `primary` | string | The primary translation. (Required) |
228
+ | `notes` | object | Additional notes related to learning and translation (Optional). - `learning`: Additional notes related to the learning word/phrase (string). - `primary`: Additional notes related to the primary translation (string). |
229
+
230
+ #### If `translationType` is "multiple":
231
+
232
+ | Property | Type | Description |
233
+ |-------------|----------|------------------------------------------|
234
+ | `type` | string | The type of the collection ("folder"). (Required) |
235
+ | `learning` | string | The learning word or phrase. (Required) |
236
+ | Properties for each translations of related dictionary | string | Properties for each translations of related dictionary, all of which are required. |
237
+ | `notes` | object | Additional notes related to learning and translations (Optional). - `learning`: Additional notes related to the learning word/phrase (string). - Properties for each translation type: Additional notes related to each translation type (string). |
238
+
239
+ ### 3. Folder Object
240
+
241
+ The `_metadata.json` file is used to set the folder name on the API response and contains the following property:
242
+
243
+ | Property | Type | Description |
244
+ |-------------|----------|------------------------------------------|
245
+ | `name` | string | The name to be used as the folder name in the API response. (Optional, if missing, the folder name will be used.) |
246
+
247
+ ## Dictionary Types Examples
248
+
249
+ ### 1. Single Translation Dictionary Example
250
+
251
+ #### Folder Structure
252
+
253
+ ```bash
254
+ _data/dictionaries/_single.json
255
+ _data/dictionaries/single/greetings.json
256
+ _data/dictionaries/single/unit1/numbers.json
257
+ ```
258
+
259
+ **_data/dictionaries/_single.json:**
260
+
261
+ ```json
262
+ {
263
+ "version": "1.0.0",
264
+ "name": "Basic (One Language)",
265
+ "translationType": "single",
266
+ "learning": "es"
267
+ }
268
+ ```
269
+
270
+ **_data/dictionaries/single/greetings.json:**
271
+
272
+ ```json
273
+ {
274
+ "name": "Greetings",
275
+ "type": "collection",
276
+ "data": [
277
+ {"learning":"¡Hola!", "primary":"Hello!"}
278
+ ]
279
+ }
280
+ ```
281
+
282
+ **_data/dictionaries/single/unit1/numbers.json:**
283
+
284
+ ```json
285
+ {
286
+ "type": "collection",
287
+ "data": [
288
+ {
289
+ "primary": "one",
290
+ "learning": "uno"
291
+ },
292
+ {
293
+ "primary": "two",
294
+ "learning": "dos"
295
+ },
296
+ {
297
+ "primary": "three",
298
+ "learning": "tres"
299
+ },
300
+ {
301
+ "primary": "four",
302
+ "learning": "cuatro"
303
+ },
304
+ {
305
+ "primary": "five",
306
+ "learning": "cinco"
307
+ },
308
+ {
309
+ "primary": "six",
310
+ "elearnings": "seis"
311
+ },
312
+ {
313
+ "primary": "seven",
314
+ "learning": "siete"
315
+ },
316
+ {
317
+ "primary": "eight",
318
+ "learning": "ocho"
319
+ },
320
+ {
321
+ "primary": "nine",
322
+ "learning": "nueve"
323
+ },
324
+ {
325
+ "primary": "ten",
326
+ "learning": "diez"
327
+ }
328
+ ]
329
+ }
330
+ ```
331
+
332
+ The plugin will generate JSON API **/api/dictionaries/single.json**
333
+
334
+ ```json
335
+ {"docPath":"http://example.org/dictionaries/single","version":"1.0.0","name":"Basic (One Language)","translationType":"single","learning":"es","data":[{"name":"Greetings","type":"collection","data":[{"learning":"¡Hola!","primary":"Hello!"}]},{"type":"folder","name":"unit1","data":[{"name":"numbers","type":"collection","data":[{"primary":"one","learning":"uno"},{"primary":"two","learning":"dos"},{"primary":"three","learning":"tres"},{"primary":"four","learning":"cuatro"},{"primary":"five","learning":"cinco"},{"primary":"six","elearnings":"seis"},{"primary":"seven","learning":"siete"},{"primary":"eight","learning":"ocho"},{"primary":"nine","learning":"nueve"},{"primary":"ten","learning":"diez"}]}]}]}
336
+ ```
337
+
338
+ ### 2. Multiple Translations Dictionary Example
339
+
340
+ #### Folder Structure
341
+
342
+ ```bash
343
+ _data/dictionaries/_multiple.json
344
+ _data/dictionaries/multiple/greetings.json
345
+ _data/dictionaries/multiple/unit1/_metadata.json
346
+ _data/dictionaries/multiple/unit1/numbers.json
347
+ ```
348
+
349
+ **_data/dictionaries/_multiple.json:**
350
+
351
+ ```json
352
+ {
353
+ "version": "1.0.0",
354
+ "name": "Basic (Multiple Languages)",
355
+ "translationType": "multiple",
356
+ "learning": "es",
357
+ "translations": [
358
+ "en", "ru", "de", "fr", "pt"
359
+ ]
360
+ }
361
+ ```
362
+
363
+ **_data/dictionaries/multiple/greetings.json:**
364
+
365
+ ```json
366
+ {
367
+ "name": "Greetings",
368
+ "type": "collection",
369
+ "data": [
370
+ {"learning":"¡Hola!", "en":"Hello!", "ru":"Привет!", "de":"Hallo!", "fr":"Bonjour!", "pt":"Olá!"}
371
+ ]
372
+ }
373
+ ```
374
+
375
+ **_data/dictionaries/multiple/un1/_metadata.json:**
376
+
377
+ ```json
378
+ {
379
+ "name": "Unit 1"
380
+ }
381
+ ```
382
+
383
+ **_data/dictionaries/multiple/un1/numbers.json:**
384
+
385
+ ```json
386
+ {
387
+ "type": "collection",
388
+ "data": [
389
+ {
390
+ "learning": "uno",
391
+ "en": "one",
392
+ "ru": "один",
393
+ "de": "eins",
394
+ "fr": "un",
395
+ "pt": "um"
396
+ },
397
+ {
398
+ "learning": "dos",
399
+ "en": "two",
400
+ "ru": "два",
401
+ "de": "zwei",
402
+ "fr": "deux",
403
+ "pt": "dois"
404
+ },
405
+ {
406
+ "learning": "tres",
407
+ "en": "three",
408
+ "ru": "три",
409
+ "de": "drei",
410
+ "fr": "trois",
411
+ "pt": "três"
412
+ },
413
+ {
414
+ "learning": "cuatro",
415
+ "en": "four",
416
+ "ru": "четыре",
417
+ "de": "vier",
418
+ "fr": "quatre",
419
+ "pt": "quatro"
420
+ },
421
+ {
422
+ "learning": "cinco",
423
+ "en": "five",
424
+ "ru": "пять",
425
+ "de": "fünf",
426
+ "fr": "cinq",
427
+ "pt": "cinco"
428
+ },
429
+ {
430
+ "learning": "seis",
431
+ "en": "six",
432
+ "ru": "шесть",
433
+ "de": "sechs",
434
+ "fr": "six",
435
+ "pt": "seis"
436
+ },
437
+ {
438
+ "learning": "siete",
439
+ "en": "seven",
440
+ "ru": "семь",
441
+ "de": "sieben",
442
+ "fr": "sept",
443
+ "pt": "sete"
444
+ },
445
+ {
446
+ "learning": "ocho",
447
+ "en": "eight",
448
+ "ru": "восемь",
449
+ "de": "acht",
450
+ "fr": "huit",
451
+ "pt": "oito"
452
+ },
453
+ {
454
+ "learning": "nueve",
455
+ "en": "nine",
456
+ "ru": "девять",
457
+ "de": "neun",
458
+ "fr": "neuf",
459
+ "pt": "nove"
460
+ },
461
+ {
462
+ "learning": "diez",
463
+ "en": "ten",
464
+ "ru": "десять",
465
+ "de": "zehn",
466
+ "fr": "dix",
467
+ "pt": "dez"
468
+ }
469
+ ]
470
+ }
471
+ ```
472
+
473
+ The plugin will generate JSON API **/api/dictionaries/multiple.json**
474
+
475
+ ```json
476
+ {"docPath":"http://example.org/dictionaries/multiple","version":"1.0.0","name":"Basic (Multiple Languages)","translationType":"multiple","learning":"es","translations":["en","ru","de","fr","pt"],"data":[{"name":"Greetings","type":"collection","data":[{"learning":"¡Hola!","en":"Hello!","ru":"Привет!","de":"Hallo!","fr":"Bonjour!","pt":"Olá!"}]},{"type":"folder","name":"Unit 1","data":[{"name":"numbers","type":"collection","data":[{"learning":"uno","en":"one","ru":"один","de":"eins","fr":"un","pt":"um"},{"learning":"dos","en":"two","ru":"два","de":"zwei","fr":"deux","pt":"dois"},{"learning":"tres","en":"three","ru":"три","de":"drei","fr":"trois","pt":"três"},{"learning":"cuatro","en":"four","ru":"четыре","de":"vier","fr":"quatre","pt":"quatro"},{"learning":"cinco","en":"five","ru":"пять","de":"fünf","fr":"cinq","pt":"cinco"},{"learning":"seis","en":"six","ru":"шесть","de":"sechs","fr":"six","pt":"seis"},{"learning":"siete","en":"seven","ru":"семь","de":"sieben","fr":"sept","pt":"sete"},{"learning":"ocho","en":"eight","ru":"восемь","de":"acht","fr":"huit","pt":"oito"},{"learning":"nueve","en":"nine","ru":"девять","de":"neun","fr":"neuf","pt":"nove"},{"learning":"diez","en":"ten","ru":"десять","de":"zehn","fr":"dix","pt":"dez"}]}]}]}
477
+ ```
478
+
479
+ As you can see collection `greetings` and folder `un1` have names that are defined by property `name`.
480
+
481
+ ## License
482
+
483
+ This project is licensed under the MIT License.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/jekyll-dictionaries/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "jekyll-dictionaries"
7
+ spec.version = JekyllDictionaries::VERSION
8
+ spec.authors = ["hinkoulabs"]
9
+ spec.email = ["siarhei.hinkou@hinkoulabs.com"]
10
+
11
+ spec.summary = "A Jekyll plugin to generate JSON dictionaries for language learning applications"
12
+ spec.homepage = "https://github.com/hinkoulabs/jekyll-dictionaries"
13
+ spec.license = "MIT"
14
+ spec.required_ruby_version = ">= 2.6.0"
15
+
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+
18
+ # Specify which files should be added to the gem when it is released.
19
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
20
+ spec.files = Dir.chdir(__dir__) do
21
+ `git ls-files -z`.split("\x0").reject do |f|
22
+ (File.expand_path(f) == __FILE__) ||
23
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
24
+ end
25
+ end
26
+ spec.extra_rdoc_files = Dir["README.md", "History.markdown", "LICENSE.txt"]
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_development_dependency 'rspec'
32
+ end
@@ -0,0 +1,10 @@
1
+ require_relative './dictionary_page'
2
+
3
+ module JekyllDictionaries
4
+ class DictionaryApiPage < DictionaryPage
5
+ def add_scope_data
6
+ @type = :dictionary_api
7
+ @ext = '.json'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,51 @@
1
+ module JekyllDictionaries
2
+ class DictionaryPage < Jekyll::Page
3
+ attr_accessor :type
4
+ attr_reader :related_page
5
+
6
+ def initialize(site, dic, default_opts)
7
+ @site = site # the current site instance.
8
+ @base = site.source # path to the source directory.
9
+ @dir = dic.filename # the directory the page will reside in.
10
+
11
+ add_scope_data
12
+
13
+ # All pages have the same filename, so define attributes straight away.
14
+ @basename = dic.filename # filename without the extension.
15
+ @name = dic.content['name'] || dic.filename # basically @basename + @ext.
16
+
17
+ # Initialize data hash with a key pointing to all posts under current category.
18
+ # This allows accessing the list in a template via `page.linked_docs`.
19
+ @data = {
20
+ 'content' => dic.content,
21
+ 'scope' => @type
22
+ }
23
+
24
+ # Look up front matter defaults scoped to type `dictionary`, if given key
25
+ # doesn't exist in the `data` hash.
26
+ data.default_proc = proc do |_, key|
27
+ (default_opts[@type.to_s] || {})[key]
28
+ end
29
+ end
30
+
31
+ def related_page=(page)
32
+ @related_page = page
33
+ @data['related_page'] = @related_page
34
+ end
35
+
36
+ def add_scope_data
37
+ @type = :dictionary
38
+ @ext = '.html'
39
+ end
40
+
41
+ # Placeholders that are used in constructing page URL.
42
+ def url_placeholders
43
+ {
44
+ :path => @dir,
45
+ :name => @dir,
46
+ :basename => basename,
47
+ :output_ext => output_ext,
48
+ }
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,73 @@
1
+ require_relative './dictionary_page'
2
+ require_relative './dictionary_api_page'
3
+
4
+ module JekyllDictionaries
5
+ class Generator < Jekyll::Generator
6
+ DICT_REGEX = /^_(.*)/
7
+
8
+ safe true
9
+
10
+ def generate(site)
11
+ @site = site
12
+ dicts = site.data['dictionaries'].inject([]) do |memo, (k, v)|
13
+ # dictionary start with _
14
+ m = k.match(DICT_REGEX)
15
+ if m
16
+ dict = v.merge(data: [])
17
+
18
+ name = m[1]
19
+
20
+ folder = site.data['dictionaries'][name]
21
+
22
+ if (folder)
23
+ dict[:data] = build_collections(folder)
24
+ end
25
+
26
+ memo << OpenStruct.new(filename: name, content: dict)
27
+ end
28
+ memo
29
+ end
30
+
31
+ dicts.each do |dict|
32
+ api_page = DictionaryApiPage.new(site, dict, config)
33
+ doc_page = DictionaryPage.new(site, dict, config)
34
+
35
+ api_page.related_page = doc_page
36
+ doc_page.related_page = api_page
37
+
38
+ site.pages << api_page
39
+ site.pages << doc_page
40
+ end
41
+ end
42
+
43
+ protected
44
+
45
+ def config
46
+ @config ||= @site.config["dictionaries"] || {}
47
+ end
48
+
49
+ def build_collections(folder_content)
50
+ folder_content.inject([]) do |memo, (k, v)|
51
+ if v.is_a?(Hash)
52
+ # collection is detected
53
+ if (v['type'] == 'collection')
54
+ # set k as title if title is missing
55
+ memo << { name: v['name'] || k }.merge(v)
56
+ else
57
+ metadata = v['_metadata']
58
+ # folder is detected
59
+ memo
60
+ folder = {
61
+ type: 'folder',
62
+ name: metadata ? metadata['name'] : k,
63
+ data: build_collections(v.select { |kk, _| kk != '_metadata' })
64
+ }
65
+ memo << folder
66
+ end
67
+ end
68
+
69
+ memo
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllDictionaries
4
+ VERSION = "1.0.1"
5
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jekyll"
4
+ require "jekyll-dictionaries/generator"
5
+
6
+ module JekyllDictionaries
7
+ autoload :DictionaryPage, "jekyll-dictionaries/dictionary_page.rb"
8
+ autoload :DictionaryApiPage, "jekyll-dictionaries/dictionary_api_page.rb"
9
+
10
+ def self.root
11
+ File.dirname __dir__
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-dictionaries
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - hinkoulabs
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-10-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description:
28
+ email:
29
+ - siarhei.hinkou@hinkoulabs.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files:
33
+ - README.md
34
+ - History.markdown
35
+ - LICENSE.txt
36
+ files:
37
+ - ".DS_Store"
38
+ - ".idea/jekyll-dictionaries.iml"
39
+ - ".idea/misc.xml"
40
+ - ".idea/vcs.xml"
41
+ - ".idea/workspace.xml"
42
+ - ".rspec"
43
+ - History.markdown
44
+ - LICENSE.txt
45
+ - README.md
46
+ - Rakefile
47
+ - jekyll-dictionaries.gemspec
48
+ - lib/jekyll-dictionaries.rb
49
+ - lib/jekyll-dictionaries/dictionary_api_page.rb
50
+ - lib/jekyll-dictionaries/dictionary_page.rb
51
+ - lib/jekyll-dictionaries/generator.rb
52
+ - lib/jekyll-dictionaries/version.rb
53
+ homepage: https://github.com/hinkoulabs/jekyll-dictionaries
54
+ licenses:
55
+ - MIT
56
+ metadata:
57
+ homepage_uri: https://github.com/hinkoulabs/jekyll-dictionaries
58
+ post_install_message:
59
+ rdoc_options: []
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 2.6.0
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubygems_version: 3.2.32
74
+ signing_key:
75
+ specification_version: 4
76
+ summary: A Jekyll plugin to generate JSON dictionaries for language learning applications
77
+ test_files: []