dsh-cait 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/README.ja.md +53 -13
- package/README.md +58 -16
- package/README.zh-CN.md +53 -15
- package/client/components.js +32 -1
- package/client/locales.js +27 -6
- package/client/rpc.js +1 -1
- package/client.js +60 -8
- package/lib/docx.js +12 -9
- package/lib/epub.js +355 -0
- package/lib/formats.js +88 -33
- package/lib/html.js +271 -0
- package/lib/import-export.js +136 -91
- package/lib/persistence.js +20 -0
- package/lib/preprocess.js +65 -0
- package/lib/store-utils.js +6 -3
- package/lib/store.js +12 -0
- package/package.json +2 -2
package/client/locales.js
CHANGED
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
'empty.demo': '加载演示文档',
|
|
58
58
|
'empty.demoHint': '没有素材?',
|
|
59
59
|
'empty.drop': '拖入文件,或点击选择',
|
|
60
|
-
'empty.formats': '支持 TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
60
|
+
'empty.formats': '支持 TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
61
61
|
'empty.features.tm': '翻译记忆',
|
|
62
62
|
'empty.features.tmDesc': '精确 + 模糊匹配',
|
|
63
63
|
'empty.features.glossary': '术语库',
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
'modal.new.targetLang': '目标语言',
|
|
72
72
|
'modal.new.create': '创建文档',
|
|
73
73
|
'modal.new.importing': '正在导入…',
|
|
74
|
-
'modal.new.dropHint': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
74
|
+
'modal.new.dropHint': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
75
75
|
'modal.new.csvSource': 'CSV 源文列',
|
|
76
76
|
'modal.new.csvTarget': 'CSV 译文列',
|
|
77
77
|
'modal.new.csvColumnPlaceholder': '列名或列号,例如 Source / 2',
|
|
@@ -156,6 +156,8 @@
|
|
|
156
156
|
'modal.export.targetMd': 'Markdown',
|
|
157
157
|
'modal.export.docx': 'Word DOCX',
|
|
158
158
|
'modal.export.docxGroup': '保留源格式',
|
|
159
|
+
'modal.export.epub': 'EPUB 电子书',
|
|
160
|
+
'modal.export.epubGroup': '保留源排版',
|
|
159
161
|
'modal.export.json': '文档 JSON',
|
|
160
162
|
'modal.export.subtitleGroup': '字幕',
|
|
161
163
|
'modal.export.localizationGroup': '本地化交换',
|
|
@@ -178,6 +180,11 @@
|
|
|
178
180
|
'modal.settings.uiAuto': '跟随 DSH 语言',
|
|
179
181
|
'modal.settings.uiHint': '只影响 CAIT 界面,不会改变文档的源语言和目标语言。',
|
|
180
182
|
'modal.settings.languages': '语言',
|
|
183
|
+
'modal.settings.preprocess': '预处理',
|
|
184
|
+
'modal.settings.preprocessHint': '在导入切句之前清理源文,占位符与标点不会被改写。',
|
|
185
|
+
'modal.settings.pre.normalizeWhitespace': '折叠多余空格与制表符',
|
|
186
|
+
'modal.settings.pre.stripInvisible': '移除零宽字符与控制字符',
|
|
187
|
+
'modal.settings.pre.collapseBlankLines': '合并连续空行',
|
|
181
188
|
'modal.settings.tm': '翻译记忆',
|
|
182
189
|
'modal.settings.fuzzy': '模糊匹配阈值',
|
|
183
190
|
'modal.settings.limit': '返回匹配数',
|
|
@@ -281,7 +288,7 @@
|
|
|
281
288
|
'empty.demo': 'Load demo document',
|
|
282
289
|
'empty.demoHint': 'No material?',
|
|
283
290
|
'empty.drop': 'Drop a file, or click to choose',
|
|
284
|
-
'empty.formats': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
291
|
+
'empty.formats': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
285
292
|
'empty.features.tm': 'Translation memory',
|
|
286
293
|
'empty.features.tmDesc': 'Exact + fuzzy matching',
|
|
287
294
|
'empty.features.glossary': 'Glossary',
|
|
@@ -295,7 +302,7 @@
|
|
|
295
302
|
'modal.new.targetLang': 'Target language',
|
|
296
303
|
'modal.new.create': 'Create document',
|
|
297
304
|
'modal.new.importing': 'Importing…',
|
|
298
|
-
'modal.new.dropHint': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
305
|
+
'modal.new.dropHint': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
299
306
|
'modal.new.csvSource': 'CSV source column',
|
|
300
307
|
'modal.new.csvTarget': 'CSV target column',
|
|
301
308
|
'modal.new.csvColumnPlaceholder': 'Column name or number, e.g. Source / 2',
|
|
@@ -380,6 +387,8 @@
|
|
|
380
387
|
'modal.export.targetMd': 'Markdown',
|
|
381
388
|
'modal.export.docx': 'Word DOCX',
|
|
382
389
|
'modal.export.docxGroup': 'Preserve source formatting',
|
|
390
|
+
'modal.export.epub': 'EPUB ebook',
|
|
391
|
+
'modal.export.epubGroup': 'Preserve source layout',
|
|
383
392
|
'modal.export.json': 'Document JSON',
|
|
384
393
|
'modal.export.subtitleGroup': 'Subtitles',
|
|
385
394
|
'modal.export.localizationGroup': 'Localization exchange',
|
|
@@ -402,6 +411,11 @@
|
|
|
402
411
|
'modal.settings.uiAuto': 'Follow DSH language',
|
|
403
412
|
'modal.settings.uiHint': 'Changes only the CAIT interface; document source and target languages are unaffected.',
|
|
404
413
|
'modal.settings.languages': 'Languages',
|
|
414
|
+
'modal.settings.preprocess': 'Preprocessing',
|
|
415
|
+
'modal.settings.preprocessHint': 'Cleans imported source text before segmentation. Placeholders and punctuation are left untouched.',
|
|
416
|
+
'modal.settings.pre.normalizeWhitespace': 'Collapse extra spaces and tabs',
|
|
417
|
+
'modal.settings.pre.stripInvisible': 'Remove zero-width and control characters',
|
|
418
|
+
'modal.settings.pre.collapseBlankLines': 'Merge consecutive blank lines',
|
|
405
419
|
'modal.settings.tm': 'Translation memory',
|
|
406
420
|
'modal.settings.fuzzy': 'Fuzzy-match threshold',
|
|
407
421
|
'modal.settings.limit': 'Matches returned',
|
|
@@ -505,7 +519,7 @@
|
|
|
505
519
|
'empty.demo': 'デモ文書を読み込む',
|
|
506
520
|
'empty.demoHint': '素材がありませんか?',
|
|
507
521
|
'empty.drop': 'ファイルをドロップ、またはクリックして選択',
|
|
508
|
-
'empty.formats': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX に対応',
|
|
522
|
+
'empty.formats': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX に対応',
|
|
509
523
|
'empty.features.tm': '翻訳メモリ',
|
|
510
524
|
'empty.features.tmDesc': '完全一致+あいまい一致',
|
|
511
525
|
'empty.features.glossary': '用語集',
|
|
@@ -519,7 +533,7 @@
|
|
|
519
533
|
'modal.new.targetLang': '訳文言語',
|
|
520
534
|
'modal.new.create': '文書を作成',
|
|
521
535
|
'modal.new.importing': 'インポート中…',
|
|
522
|
-
'modal.new.dropHint': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
536
|
+
'modal.new.dropHint': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
523
537
|
'modal.new.csvSource': 'CSV 原文列',
|
|
524
538
|
'modal.new.csvTarget': 'CSV 訳文列',
|
|
525
539
|
'modal.new.csvColumnPlaceholder': '列名または列番号(例:Source / 2)',
|
|
@@ -604,6 +618,8 @@
|
|
|
604
618
|
'modal.export.targetMd': 'Markdown',
|
|
605
619
|
'modal.export.docx': 'Word DOCX',
|
|
606
620
|
'modal.export.docxGroup': '元の書式を保持',
|
|
621
|
+
'modal.export.epub': 'EPUB 電子書',
|
|
622
|
+
'modal.export.epubGroup': '元のレイアウトを保持',
|
|
607
623
|
'modal.export.json': '文書 JSON',
|
|
608
624
|
'modal.export.subtitleGroup': '字幕',
|
|
609
625
|
'modal.export.localizationGroup': 'ローカライズ交換',
|
|
@@ -626,6 +642,11 @@
|
|
|
626
642
|
'modal.settings.uiAuto': 'DSH の言語に合わせる',
|
|
627
643
|
'modal.settings.uiHint': 'CAIT の表示だけを切り替えます。文書の原文言語・訳文言語には影響しません。',
|
|
628
644
|
'modal.settings.languages': '言語',
|
|
645
|
+
'modal.settings.preprocess': '前処理',
|
|
646
|
+
'modal.settings.preprocessHint': '取り込みと分割の前に原文を整えます。プレースホルダーと句読点は変更しません。',
|
|
647
|
+
'modal.settings.pre.normalizeWhitespace': '余分な空白とタブをまとめる',
|
|
648
|
+
'modal.settings.pre.stripInvisible': 'ゼロ幅文字と制御文字を除去',
|
|
649
|
+
'modal.settings.pre.collapseBlankLines': '連続する空行をまとめる',
|
|
629
650
|
'modal.settings.tm': '翻訳メモリ',
|
|
630
651
|
'modal.settings.fuzzy': 'あいまい一致のしきい値',
|
|
631
652
|
'modal.settings.limit': '返す一致件数',
|
package/client/rpc.js
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
function filePayload(file) {
|
|
53
53
|
const extension = (file.name.match(/\.([a-z0-9]+)$/i)?.[1] || '').toLowerCase()
|
|
54
|
-
if (extension === 'docx' || extension === 'xlsx' || extension === 'pptx') {
|
|
54
|
+
if (extension === 'docx' || extension === 'xlsx' || extension === 'pptx' || extension === 'epub') {
|
|
55
55
|
return file.arrayBuffer().then((buffer) => {
|
|
56
56
|
const bytes = new Uint8Array(buffer)
|
|
57
57
|
let binary = ''
|
package/client.js
CHANGED
|
@@ -421,7 +421,7 @@ window.__ModuleLoader__.load({
|
|
|
421
421
|
|
|
422
422
|
function filePayload(file) {
|
|
423
423
|
const extension = (file.name.match(/\.([a-z0-9]+)$/i)?.[1] || '').toLowerCase()
|
|
424
|
-
if (extension === 'docx' || extension === 'xlsx' || extension === 'pptx') {
|
|
424
|
+
if (extension === 'docx' || extension === 'xlsx' || extension === 'pptx' || extension === 'epub') {
|
|
425
425
|
return file.arrayBuffer().then((buffer) => {
|
|
426
426
|
const bytes = new Uint8Array(buffer)
|
|
427
427
|
let binary = ''
|
|
@@ -1528,7 +1528,7 @@ window.__ModuleLoader__.load({
|
|
|
1528
1528
|
h('input', {
|
|
1529
1529
|
ref: inputRef,
|
|
1530
1530
|
type: 'file',
|
|
1531
|
-
accept: '.txt,.md,.markdown,.tmx,.docx,.csv,.srt,.vtt,.po,.pot,.xliff,.xlf,.sdlxliff,.html,.htm,.json,.rtf,.xlsx,.pptx',
|
|
1531
|
+
accept: '.txt,.md,.markdown,.tmx,.docx,.epub,.csv,.srt,.vtt,.po,.pot,.xliff,.xlf,.sdlxliff,.html,.htm,.json,.rtf,.xlsx,.pptx',
|
|
1532
1532
|
hidden: true,
|
|
1533
1533
|
onChange: (event) => pickFile(event.target.files?.[0]),
|
|
1534
1534
|
}),
|
|
@@ -1572,6 +1572,7 @@ window.__ModuleLoader__.load({
|
|
|
1572
1572
|
['target-txt', t('modal.export.targetTxt'), t('modal.export.target'), 'download'],
|
|
1573
1573
|
['target-md', t('modal.export.targetMd'), t('modal.export.target'), 'download'],
|
|
1574
1574
|
['docx', t('modal.export.docx'), t('modal.export.docxGroup'), 'file'],
|
|
1575
|
+
['epub', t('modal.export.epub'), t('modal.export.epubGroup'), 'file'],
|
|
1575
1576
|
['srt', t('modal.export.srt'), t('modal.export.subtitleGroup'), 'file'],
|
|
1576
1577
|
['vtt', t('modal.export.vtt'), t('modal.export.subtitleGroup'), 'file'],
|
|
1577
1578
|
['po', t('modal.export.po'), t('modal.export.localizationGroup'), 'file'],
|
|
@@ -1611,6 +1612,11 @@ window.__ModuleLoader__.load({
|
|
|
1611
1612
|
fuzzyThreshold: settings.fuzzyThreshold,
|
|
1612
1613
|
tmLimit: settings.tmLimit,
|
|
1613
1614
|
uiLang: settings.uiLang || 'auto',
|
|
1615
|
+
preprocess: {
|
|
1616
|
+
normalizeWhitespace: settings.preprocess?.normalizeWhitespace !== false,
|
|
1617
|
+
stripInvisible: settings.preprocess?.stripInvisible !== false,
|
|
1618
|
+
collapseBlankLines: settings.preprocess?.collapseBlankLines !== false,
|
|
1619
|
+
},
|
|
1614
1620
|
mt: {
|
|
1615
1621
|
provider: settings.mt.provider,
|
|
1616
1622
|
model: settings.mt.model,
|
|
@@ -1623,6 +1629,8 @@ window.__ModuleLoader__.load({
|
|
|
1623
1629
|
const routeMissing = form.mt.provider !== 'mock' && !route
|
|
1624
1630
|
|
|
1625
1631
|
const setMt = (patch) => setForm((current) => ({ ...current, mt: { ...current.mt, ...patch } }))
|
|
1632
|
+
const setPre = (patch) =>
|
|
1633
|
+
setForm((current) => ({ ...current, preprocess: { ...current.preprocess, ...patch } }))
|
|
1626
1634
|
const selectProvider = (provider) => {
|
|
1627
1635
|
const nextRoute = routes.find((item) => item.id === provider)
|
|
1628
1636
|
setForm((current) => ({
|
|
@@ -1646,6 +1654,11 @@ window.__ModuleLoader__.load({
|
|
|
1646
1654
|
fuzzyThreshold: Number(form.fuzzyThreshold),
|
|
1647
1655
|
tmLimit: Number(form.tmLimit),
|
|
1648
1656
|
uiLang: form.uiLang,
|
|
1657
|
+
preprocess: {
|
|
1658
|
+
normalizeWhitespace: Boolean(form.preprocess.normalizeWhitespace),
|
|
1659
|
+
stripInvisible: Boolean(form.preprocess.stripInvisible),
|
|
1660
|
+
collapseBlankLines: Boolean(form.preprocess.collapseBlankLines),
|
|
1661
|
+
},
|
|
1649
1662
|
mt: {
|
|
1650
1663
|
provider: form.mt.provider,
|
|
1651
1664
|
model: form.mt.model,
|
|
@@ -1712,6 +1725,24 @@ window.__ModuleLoader__.load({
|
|
|
1712
1725
|
),
|
|
1713
1726
|
),
|
|
1714
1727
|
),
|
|
1728
|
+
h(
|
|
1729
|
+
'div',
|
|
1730
|
+
{ className: 'cait-settings-section' },
|
|
1731
|
+
h('h4', { className: 'cait-settings-title' }, t('modal.settings.preprocess')),
|
|
1732
|
+
h('p', { className: 'cait-mt-hint', style: { marginTop: 0 } }, t('modal.settings.preprocessHint')),
|
|
1733
|
+
['normalizeWhitespace', 'stripInvisible', 'collapseBlankLines'].map((key) =>
|
|
1734
|
+
h(
|
|
1735
|
+
'label',
|
|
1736
|
+
{ key, className: 'cait-checkline' },
|
|
1737
|
+
h('input', {
|
|
1738
|
+
type: 'checkbox',
|
|
1739
|
+
checked: Boolean(form.preprocess[key]),
|
|
1740
|
+
onChange: (event) => setPre({ [key]: event.target.checked }),
|
|
1741
|
+
}),
|
|
1742
|
+
t(`modal.settings.pre.${key}`),
|
|
1743
|
+
),
|
|
1744
|
+
),
|
|
1745
|
+
),
|
|
1715
1746
|
h(
|
|
1716
1747
|
'div',
|
|
1717
1748
|
{ className: 'cait-settings-section' },
|
|
@@ -2899,7 +2930,7 @@ window.__ModuleLoader__.load({
|
|
|
2899
2930
|
'empty.demo': '加载演示文档',
|
|
2900
2931
|
'empty.demoHint': '没有素材?',
|
|
2901
2932
|
'empty.drop': '拖入文件,或点击选择',
|
|
2902
|
-
'empty.formats': '支持 TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
2933
|
+
'empty.formats': '支持 TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
2903
2934
|
'empty.features.tm': '翻译记忆',
|
|
2904
2935
|
'empty.features.tmDesc': '精确 + 模糊匹配',
|
|
2905
2936
|
'empty.features.glossary': '术语库',
|
|
@@ -2913,7 +2944,7 @@ window.__ModuleLoader__.load({
|
|
|
2913
2944
|
'modal.new.targetLang': '目标语言',
|
|
2914
2945
|
'modal.new.create': '创建文档',
|
|
2915
2946
|
'modal.new.importing': '正在导入…',
|
|
2916
|
-
'modal.new.dropHint': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
2947
|
+
'modal.new.dropHint': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
2917
2948
|
'modal.new.csvSource': 'CSV 源文列',
|
|
2918
2949
|
'modal.new.csvTarget': 'CSV 译文列',
|
|
2919
2950
|
'modal.new.csvColumnPlaceholder': '列名或列号,例如 Source / 2',
|
|
@@ -2998,6 +3029,8 @@ window.__ModuleLoader__.load({
|
|
|
2998
3029
|
'modal.export.targetMd': 'Markdown',
|
|
2999
3030
|
'modal.export.docx': 'Word DOCX',
|
|
3000
3031
|
'modal.export.docxGroup': '保留源格式',
|
|
3032
|
+
'modal.export.epub': 'EPUB 电子书',
|
|
3033
|
+
'modal.export.epubGroup': '保留源排版',
|
|
3001
3034
|
'modal.export.json': '文档 JSON',
|
|
3002
3035
|
'modal.export.subtitleGroup': '字幕',
|
|
3003
3036
|
'modal.export.localizationGroup': '本地化交换',
|
|
@@ -3020,6 +3053,11 @@ window.__ModuleLoader__.load({
|
|
|
3020
3053
|
'modal.settings.uiAuto': '跟随 DSH 语言',
|
|
3021
3054
|
'modal.settings.uiHint': '只影响 CAIT 界面,不会改变文档的源语言和目标语言。',
|
|
3022
3055
|
'modal.settings.languages': '语言',
|
|
3056
|
+
'modal.settings.preprocess': '预处理',
|
|
3057
|
+
'modal.settings.preprocessHint': '在导入切句之前清理源文,占位符与标点不会被改写。',
|
|
3058
|
+
'modal.settings.pre.normalizeWhitespace': '折叠多余空格与制表符',
|
|
3059
|
+
'modal.settings.pre.stripInvisible': '移除零宽字符与控制字符',
|
|
3060
|
+
'modal.settings.pre.collapseBlankLines': '合并连续空行',
|
|
3023
3061
|
'modal.settings.tm': '翻译记忆',
|
|
3024
3062
|
'modal.settings.fuzzy': '模糊匹配阈值',
|
|
3025
3063
|
'modal.settings.limit': '返回匹配数',
|
|
@@ -3123,7 +3161,7 @@ window.__ModuleLoader__.load({
|
|
|
3123
3161
|
'empty.demo': 'Load demo document',
|
|
3124
3162
|
'empty.demoHint': 'No material?',
|
|
3125
3163
|
'empty.drop': 'Drop a file, or click to choose',
|
|
3126
|
-
'empty.formats': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
3164
|
+
'empty.formats': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
3127
3165
|
'empty.features.tm': 'Translation memory',
|
|
3128
3166
|
'empty.features.tmDesc': 'Exact + fuzzy matching',
|
|
3129
3167
|
'empty.features.glossary': 'Glossary',
|
|
@@ -3137,7 +3175,7 @@ window.__ModuleLoader__.load({
|
|
|
3137
3175
|
'modal.new.targetLang': 'Target language',
|
|
3138
3176
|
'modal.new.create': 'Create document',
|
|
3139
3177
|
'modal.new.importing': 'Importing…',
|
|
3140
|
-
'modal.new.dropHint': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
3178
|
+
'modal.new.dropHint': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
3141
3179
|
'modal.new.csvSource': 'CSV source column',
|
|
3142
3180
|
'modal.new.csvTarget': 'CSV target column',
|
|
3143
3181
|
'modal.new.csvColumnPlaceholder': 'Column name or number, e.g. Source / 2',
|
|
@@ -3222,6 +3260,8 @@ window.__ModuleLoader__.load({
|
|
|
3222
3260
|
'modal.export.targetMd': 'Markdown',
|
|
3223
3261
|
'modal.export.docx': 'Word DOCX',
|
|
3224
3262
|
'modal.export.docxGroup': 'Preserve source formatting',
|
|
3263
|
+
'modal.export.epub': 'EPUB ebook',
|
|
3264
|
+
'modal.export.epubGroup': 'Preserve source layout',
|
|
3225
3265
|
'modal.export.json': 'Document JSON',
|
|
3226
3266
|
'modal.export.subtitleGroup': 'Subtitles',
|
|
3227
3267
|
'modal.export.localizationGroup': 'Localization exchange',
|
|
@@ -3244,6 +3284,11 @@ window.__ModuleLoader__.load({
|
|
|
3244
3284
|
'modal.settings.uiAuto': 'Follow DSH language',
|
|
3245
3285
|
'modal.settings.uiHint': 'Changes only the CAIT interface; document source and target languages are unaffected.',
|
|
3246
3286
|
'modal.settings.languages': 'Languages',
|
|
3287
|
+
'modal.settings.preprocess': 'Preprocessing',
|
|
3288
|
+
'modal.settings.preprocessHint': 'Cleans imported source text before segmentation. Placeholders and punctuation are left untouched.',
|
|
3289
|
+
'modal.settings.pre.normalizeWhitespace': 'Collapse extra spaces and tabs',
|
|
3290
|
+
'modal.settings.pre.stripInvisible': 'Remove zero-width and control characters',
|
|
3291
|
+
'modal.settings.pre.collapseBlankLines': 'Merge consecutive blank lines',
|
|
3247
3292
|
'modal.settings.tm': 'Translation memory',
|
|
3248
3293
|
'modal.settings.fuzzy': 'Fuzzy-match threshold',
|
|
3249
3294
|
'modal.settings.limit': 'Matches returned',
|
|
@@ -3347,7 +3392,7 @@ window.__ModuleLoader__.load({
|
|
|
3347
3392
|
'empty.demo': 'デモ文書を読み込む',
|
|
3348
3393
|
'empty.demoHint': '素材がありませんか?',
|
|
3349
3394
|
'empty.drop': 'ファイルをドロップ、またはクリックして選択',
|
|
3350
|
-
'empty.formats': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX に対応',
|
|
3395
|
+
'empty.formats': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX に対応',
|
|
3351
3396
|
'empty.features.tm': '翻訳メモリ',
|
|
3352
3397
|
'empty.features.tmDesc': '完全一致+あいまい一致',
|
|
3353
3398
|
'empty.features.glossary': '用語集',
|
|
@@ -3361,7 +3406,7 @@ window.__ModuleLoader__.load({
|
|
|
3361
3406
|
'modal.new.targetLang': '訳文言語',
|
|
3362
3407
|
'modal.new.create': '文書を作成',
|
|
3363
3408
|
'modal.new.importing': 'インポート中…',
|
|
3364
|
-
'modal.new.dropHint': 'TXT · Markdown · DOCX · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
3409
|
+
'modal.new.dropHint': 'TXT · Markdown · DOCX · EPUB · TMX · CSV · SRT · VTT · PO · XLIFF · HTML · JSON · RTF · XLSX · PPTX',
|
|
3365
3410
|
'modal.new.csvSource': 'CSV 原文列',
|
|
3366
3411
|
'modal.new.csvTarget': 'CSV 訳文列',
|
|
3367
3412
|
'modal.new.csvColumnPlaceholder': '列名または列番号(例:Source / 2)',
|
|
@@ -3446,6 +3491,8 @@ window.__ModuleLoader__.load({
|
|
|
3446
3491
|
'modal.export.targetMd': 'Markdown',
|
|
3447
3492
|
'modal.export.docx': 'Word DOCX',
|
|
3448
3493
|
'modal.export.docxGroup': '元の書式を保持',
|
|
3494
|
+
'modal.export.epub': 'EPUB 電子書',
|
|
3495
|
+
'modal.export.epubGroup': '元のレイアウトを保持',
|
|
3449
3496
|
'modal.export.json': '文書 JSON',
|
|
3450
3497
|
'modal.export.subtitleGroup': '字幕',
|
|
3451
3498
|
'modal.export.localizationGroup': 'ローカライズ交換',
|
|
@@ -3468,6 +3515,11 @@ window.__ModuleLoader__.load({
|
|
|
3468
3515
|
'modal.settings.uiAuto': 'DSH の言語に合わせる',
|
|
3469
3516
|
'modal.settings.uiHint': 'CAIT の表示だけを切り替えます。文書の原文言語・訳文言語には影響しません。',
|
|
3470
3517
|
'modal.settings.languages': '言語',
|
|
3518
|
+
'modal.settings.preprocess': '前処理',
|
|
3519
|
+
'modal.settings.preprocessHint': '取り込みと分割の前に原文を整えます。プレースホルダーと句読点は変更しません。',
|
|
3520
|
+
'modal.settings.pre.normalizeWhitespace': '余分な空白とタブをまとめる',
|
|
3521
|
+
'modal.settings.pre.stripInvisible': 'ゼロ幅文字と制御文字を除去',
|
|
3522
|
+
'modal.settings.pre.collapseBlankLines': '連続する空行をまとめる',
|
|
3471
3523
|
'modal.settings.tm': '翻訳メモリ',
|
|
3472
3524
|
'modal.settings.fuzzy': 'あいまい一致のしきい値',
|
|
3473
3525
|
'modal.settings.limit': '返す一致件数',
|
package/lib/docx.js
CHANGED
|
@@ -59,16 +59,16 @@ function readZipEntry(buffer, wanted) {
|
|
|
59
59
|
return null
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
function readZipEntries(buffer) {
|
|
62
|
+
function readZipEntries(buffer, label = 'DOCX') {
|
|
63
63
|
const eocd = findEndOfCentralDirectory(buffer)
|
|
64
|
-
if (eocd < 0) throw new Error(
|
|
64
|
+
if (eocd < 0) throw new Error(`${label} 文件不是有效的 ZIP 容器`)
|
|
65
65
|
const count = buffer.readUInt16LE(eocd + 10)
|
|
66
66
|
let offset = buffer.readUInt32LE(eocd + 16)
|
|
67
67
|
const entries = []
|
|
68
68
|
|
|
69
69
|
for (let index = 0; index < count; index += 1) {
|
|
70
70
|
if (offset + 46 > buffer.length || buffer.readUInt32LE(offset) !== CENTRAL) {
|
|
71
|
-
throw new Error(
|
|
71
|
+
throw new Error(`${label} ZIP 中央目录损坏`)
|
|
72
72
|
}
|
|
73
73
|
const method = buffer.readUInt16LE(offset + 10)
|
|
74
74
|
const compressedSize = buffer.readUInt32LE(offset + 20)
|
|
@@ -78,7 +78,7 @@ function readZipEntries(buffer) {
|
|
|
78
78
|
const localOffset = buffer.readUInt32LE(offset + 42)
|
|
79
79
|
const name = buffer.subarray(offset + 46, offset + 46 + nameLength).toString('utf8')
|
|
80
80
|
|
|
81
|
-
if (buffer.readUInt32LE(localOffset) !== LOCAL) throw new Error(
|
|
81
|
+
if (buffer.readUInt32LE(localOffset) !== LOCAL) throw new Error(`${label} ZIP 本地头损坏`)
|
|
82
82
|
const localNameLength = buffer.readUInt16LE(localOffset + 26)
|
|
83
83
|
const localExtraLength = buffer.readUInt16LE(localOffset + 28)
|
|
84
84
|
const start = localOffset + 30 + localNameLength + localExtraLength
|
|
@@ -86,9 +86,9 @@ function readZipEntries(buffer) {
|
|
|
86
86
|
let data
|
|
87
87
|
if (method === 0) data = Buffer.from(compressed)
|
|
88
88
|
else if (method === 8) data = inflateRawSync(compressed)
|
|
89
|
-
else throw new Error(
|
|
89
|
+
else throw new Error(`${label} 使用了不支持的压缩方式 (${method})`)
|
|
90
90
|
|
|
91
|
-
entries.push({ name, data })
|
|
91
|
+
entries.push({ name, data, method })
|
|
92
92
|
offset += 46 + nameLength + extraLength + commentLength
|
|
93
93
|
}
|
|
94
94
|
|
|
@@ -134,14 +134,17 @@ function writeZip(entries) {
|
|
|
134
134
|
for (const entry of entries) {
|
|
135
135
|
const name = Buffer.from(entry.name, 'utf8')
|
|
136
136
|
const data = Buffer.isBuffer(entry.data) ? entry.data : Buffer.from(entry.data)
|
|
137
|
-
|
|
137
|
+
// EPUB requires the `mimetype` entry to be stored (method 0) and first.
|
|
138
|
+
const stored = entry.store === true
|
|
139
|
+
const method = stored ? 0 : 8
|
|
140
|
+
const compressed = stored ? data : deflateRawSync(data)
|
|
138
141
|
const crc = crc32(data)
|
|
139
142
|
|
|
140
143
|
const local = Buffer.alloc(30)
|
|
141
144
|
local.writeUInt32LE(LOCAL, 0)
|
|
142
145
|
local.writeUInt16LE(20, 4)
|
|
143
146
|
local.writeUInt16LE(0x0800, 6)
|
|
144
|
-
local.writeUInt16LE(
|
|
147
|
+
local.writeUInt16LE(method, 8)
|
|
145
148
|
local.writeUInt16LE(time, 10)
|
|
146
149
|
local.writeUInt16LE(date, 12)
|
|
147
150
|
local.writeUInt32LE(crc, 14)
|
|
@@ -156,7 +159,7 @@ function writeZip(entries) {
|
|
|
156
159
|
central.writeUInt16LE(20, 4)
|
|
157
160
|
central.writeUInt16LE(20, 6)
|
|
158
161
|
central.writeUInt16LE(0x0800, 8)
|
|
159
|
-
central.writeUInt16LE(
|
|
162
|
+
central.writeUInt16LE(method, 10)
|
|
160
163
|
central.writeUInt16LE(time, 12)
|
|
161
164
|
central.writeUInt16LE(date, 14)
|
|
162
165
|
central.writeUInt32LE(crc, 16)
|