@sametalmdr/word-editor 0.2.0-alpha → 0.3.0-alpha
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 +108 -70
- package/LICENSE +21 -21
- package/README.md +286 -247
- package/dist/canvas/box-clipboard.js +238 -238
- package/dist/canvas/box-selection.js +80 -80
- package/dist/canvas/canvas-editor.js +502 -502
- package/dist/canvas/controller.js +717 -717
- package/dist/canvas/geometry.js +131 -131
- package/dist/canvas/gesture.d.ts +0 -1
- package/dist/canvas/gesture.js +289 -289
- package/dist/canvas/handles.js +212 -212
- package/dist/canvas/menu.js +82 -82
- package/dist/canvas/mode-controller.js +81 -81
- package/dist/canvas/nudge.js +108 -108
- package/dist/canvas/overlay.js +149 -149
- package/dist/canvas/snap.js +132 -132
- package/dist/canvas/viewport.js +112 -112
- package/dist/canvas/z-order.js +171 -171
- package/dist/commands/alignment.js +150 -150
- package/dist/commands/box.js +272 -272
- package/dist/commands/clipboard.js +93 -93
- package/dist/commands/graphemes.js +112 -112
- package/dist/commands/marks.js +153 -153
- package/dist/commands/paragraph-props.js +176 -176
- package/dist/commands/size.js +368 -368
- package/dist/commands/text.js +291 -291
- package/dist/docx.d.ts +1 -0
- package/dist/docx.js +15 -13
- package/dist/editor/editing-host.js +434 -434
- package/dist/element.js +41 -41
- package/dist/fonts/OFL-Carlito.txt +94 -0
- package/dist/fonts/calibri-metrics.d.ts +27 -0
- package/dist/fonts/calibri-metrics.js +88 -0
- package/dist/history/history.js +433 -433
- package/dist/index.js +63 -63
- package/dist/input/beforeinput.js +224 -224
- package/dist/input/clipboard.js +107 -107
- package/dist/input/composition.js +341 -341
- package/dist/input/keymap.js +54 -54
- package/dist/io/ooxml/custgeom.js +72 -72
- package/dist/io/ooxml/drawingml.js +232 -232
- package/dist/io/ooxml/edits.js +67 -67
- package/dist/io/ooxml/export-splice.js +880 -880
- package/dist/io/ooxml/export.js +365 -365
- package/dist/io/ooxml/fill.d.ts +93 -8
- package/dist/io/ooxml/fill.js +618 -562
- package/dist/io/ooxml/fit.d.ts +252 -0
- package/dist/io/ooxml/fit.js +598 -0
- package/dist/io/ooxml/import-gate.js +200 -200
- package/dist/io/ooxml/import.js +691 -691
- package/dist/io/ooxml/inflate.js +126 -126
- package/dist/io/ooxml/media.js +87 -87
- package/dist/io/ooxml/ns.d.ts +2 -0
- package/dist/io/ooxml/ns.js +26 -21
- package/dist/io/ooxml/numbering.js +290 -290
- package/dist/io/ooxml/opc-write.js +171 -171
- package/dist/io/ooxml/provenance.js +93 -93
- package/dist/io/ooxml/recipe.js +708 -708
- package/dist/io/ooxml/relationships.js +59 -59
- package/dist/io/ooxml/run-fonts.d.ts +89 -0
- package/dist/io/ooxml/run-fonts.js +378 -0
- package/dist/io/ooxml/slots.d.ts +4 -0
- package/dist/io/ooxml/slots.js +582 -581
- package/dist/io/ooxml/styles-resolve.js +257 -257
- package/dist/io/ooxml/units.js +43 -43
- package/dist/io/ooxml/value.js +120 -120
- package/dist/io/ooxml/xml-scan.js +616 -616
- package/dist/io/ooxml/zip-container.js +228 -228
- package/dist/io/ooxml/zip-reject.js +106 -106
- package/dist/measure/placement.js +83 -83
- package/dist/measure/report.js +75 -75
- package/dist/model/ids.js +70 -70
- package/dist/model/normalize.js +146 -146
- package/dist/model/position.js +283 -283
- package/dist/model/transaction.js +209 -209
- package/dist/platform/capabilities.js +25 -25
- package/dist/react/index.js +21 -21
- package/dist/selection/controller.js +315 -315
- package/dist/selection/dom-map.js +334 -334
- package/dist/state/editor-state.js +109 -109
- package/dist/styles.css +66 -66
- package/package.json +94 -93
package/README.md
CHANGED
|
@@ -1,247 +1,286 @@
|
|
|
1
|
-
# @sametalmdr/word-editor
|
|
2
|
-
|
|
3
|
-
Tarayıcıda çalışan bir **sayfa tuvali** editörü: sabit sayfa yüzeyleri
|
|
4
|
-
üzerinde mutlak konumlu metin kutularının içeriğini ve yerleşimini düzenler,
|
|
5
|
-
gerçek `.docx` dosyalarını açar ve orijinal paketi yamalayarak geri kaydeder.
|
|
6
|
-
Akan metin / sayfalama / tablo yok (ADR-0006). Sıfır runtime bağımlılık, saf
|
|
7
|
-
ESM, MIT lisanslı.
|
|
8
|
-
|
|
9
|
-
> ⚠️ **Durum (2026-10-26): 0.
|
|
10
|
-
> `.docx` aç, metin yaz, kutu taşı, kalın/italik/altı çizili, punto, hizalama,
|
|
11
|
-
> girinti, Kaydet. **Gerçek Word'de doğrulanan:** metin, kutu taşıma ve
|
|
12
|
-
> kalın — kaydedilen dosya onarımsız açılıyor ve değişiklik görünüyor.
|
|
13
|
-
> İtalik ve altı çizili aynı yazma yolundan geçiyor, ama Word'de ayrıca
|
|
14
|
-
> açılmadı. Punto, hizalama ve girinti dosyaya yazılıyor ama **Word'de henüz
|
|
15
|
-
> doğrulanmadı** (FIDELITY.md'de AÇIK). **Bugün yalnız örnek sayfalardan
|
|
16
|
-
> kullanılabiliyor** (aşağıda `app.html`): paketin public API'si `createEditor()`
|
|
17
|
-
> (bir `doc` alır, tuval editörünü dışa vermez). `.docx` import/export'u ve şablon doldurma
|
|
18
|
-
> **`/docx` alt yolunda** (aşağıda; `0.
|
|
19
|
-
> ([docs/MASTER-PLAN.md](./docs/MASTER-PLAN.md)). Kaydedilmeyen düzenlemeler ve bilinen
|
|
20
|
-
> iki hata (yapıştırılan kutu kaydı engelliyor, silinen kutu sessizce
|
|
21
|
-
> kayboluyor): [FIDELITY.md](./FIDELITY.md) "Kutu yerleşimi" bölümü. Yol
|
|
22
|
-
> haritası: [ARCHITECTURE.md](./ARCHITECTURE.md) §6.
|
|
23
|
-
|
|
24
|
-
Bu proje Microsoft Word'ün bir klonu değildir ve Microsoft ile hiçbir
|
|
25
|
-
bağlantısı yoktur.
|
|
26
|
-
|
|
27
|
-
## Kurulum
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npm install @sametalmdr/word-editor@0.
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
## Saf HTML ile kullanım
|
|
34
|
-
|
|
35
|
-
Build adımı gerekmez.
|
|
36
|
-
|
|
37
|
-
```html
|
|
38
|
-
<link rel="stylesheet" href="./node_modules/@sametalmdr/word-editor/dist/styles.css" />
|
|
39
|
-
<word-editor></word-editor>
|
|
40
|
-
<script type="module">
|
|
41
|
-
import "@sametalmdr/word-editor/element";
|
|
42
|
-
</script>
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## React ile kullanım
|
|
46
|
-
|
|
47
|
-
`react` bir optional peer dependency'dir — kendi React sürümünüzü kurmanız
|
|
48
|
-
gerekir.
|
|
49
|
-
|
|
50
|
-
```jsx
|
|
51
|
-
import { WordEditor } from "@sametalmdr/word-editor/react";
|
|
52
|
-
import "@sametalmdr/word-editor/styles.css";
|
|
53
|
-
|
|
54
|
-
function App() {
|
|
55
|
-
return <WordEditor />;
|
|
56
|
-
}
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## Framework-agnostic çekirdek API
|
|
60
|
-
|
|
61
|
-
```js
|
|
62
|
-
import { createEditor } from "@sametalmdr/word-editor";
|
|
63
|
-
|
|
64
|
-
const editor = createEditor({ container: document.getElementById("root") });
|
|
65
|
-
// ...
|
|
66
|
-
editor.destroy();
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## `/docx` — şablon doldurma (DOM'suz; Node, Deno ve tarayıcı için yazıldı)
|
|
70
|
-
|
|
71
|
-
`{etiket}`li bir `.docx` şablonunu veriyle doldurur. Orijinal paketi yamalar: yalnız
|
|
72
|
-
`word/document.xml` yeniden yazılır, başka her parça bayt bayt aynı kalır. Hiçbir ağ isteği
|
|
73
|
-
atmaz; sunucuda (ör. Supabase Edge Functions) ve tarayıcıda aynı fonksiyon. Kapılarla sınanan:
|
|
74
|
-
Node 24.13.1 ve Deno 2.1.4; tarayıcıda (Chrome 152) yalnız incelendi, kanıt sınıfıyla değil.
|
|
75
|
-
|
|
76
|
-
```js
|
|
77
|
-
import { fillTemplate, inspectTemplate, TemplateError } from "@sametalmdr/word-editor/docx";
|
|
78
|
-
|
|
79
|
-
// template: bir .docx dosyasının baytları (Uint8Array)
|
|
80
|
-
try {
|
|
81
|
-
const { bytes, documentXml, report } = await fillTemplate(template, {
|
|
82
|
-
firma_adi: "Alrosoft Ltd",
|
|
83
|
-
rapor_no: "RPR-2026-0001",
|
|
84
|
-
notlar: null, // boş: serbest, report.empty'de listelenir
|
|
85
|
-
});
|
|
86
|
-
// bytes: doldurulmuş .docx
|
|
87
|
-
// documentXml: doldurulmuş word/document.xml, sıkıştırılmamış — çalışma ortamları
|
|
88
|
-
// arasında karşılaştırmayı bunun özetiyle yapın (zip baytları ortama göre değişir)
|
|
89
|
-
// report: etiket -> [{docPrId, page}], empty, unused, warnings, counts, engine
|
|
90
|
-
} catch (err) {
|
|
91
|
-
if (!(err instanceof TemplateError)) throw err;
|
|
92
|
-
for (const p of err.problems) console.log(p.code, p.tag, p.page); // hepsi birlikte
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const info = await inspectTemplate(template); // doldurmadan: etiketler, sorunlar, uyarılar
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Kurallar ([ADR-0037](./docs/adr/0037-template-fill-engine.md),
|
|
99
|
-
[ADR-0038](./docs/adr/0038-generated-output-keeps-both-copies-equal.md)):
|
|
100
|
-
|
|
101
|
-
- Etiket bir `w:t`'nin metninin tamamıdır: `{firma_adi}`, ad `[a-z][a-z0-9_]*`. Bölünmüş
|
|
102
|
-
etiket, `{ ad }`, `{#döngü}`, `{%görsel}` ve "Tarih: {tarih}" gibi karışık metin reddedilir.
|
|
103
|
-
- Etiket yalnız metin kutusunda olabilir. Kutunun iki kopyası (`mc:Choice` ve `mc:Fallback`)
|
|
104
|
-
birlikte yazılır ve eşit kaldıkları denetlenir — Word yalnız Choice'u okur, yanlış bir
|
|
105
|
-
Fallback Word'de görünmez (FILL-E2).
|
|
106
|
-
- Eksik anahtar hata; eksiklerin hepsi tek `TemplateError`'da. `null`, `""` ve yalnız boşluk
|
|
107
|
-
boştur: serbest, raporlanır.
|
|
108
|
-
- Değer string olmalı; sekme ve denetim karakterleri reddedilir. Tarih ve sayı biçimlemek
|
|
109
|
-
çağıranın işi.
|
|
110
|
-
- Satır sonu yalnız `multiline` seçeneğinin adlandırdığı etikette ve yalnız LF olarak
|
|
111
|
-
([ADR-0039](./docs/adr/0039-multi-line-values.md)): her satır etiketin kendi run'ında, aralarında
|
|
112
|
-
`w:br`, run'ın biçimi her satırda. CR, CRLF, U+2028 ve U+2029 her etikette reddedilir — motor
|
|
113
|
-
değeri sessizce değiştirmez, normalleştirmek çağıranın işi. Şablonda olmayan bir ad
|
|
114
|
-
`UNKNOWN_MULTILINE_TAG`:
|
|
115
|
-
|
|
116
|
-
```js
|
|
117
|
-
await fillTemplate(template, { ...data, notlar: "Birinci satır\nİkinci satır" }, { multiline: ["notlar"] });
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Kutunun alabileceğinden fazla satır Word'de sessizce kırpılır (FR3-WORD-ML2);
|
|
121
|
-
|
|
122
|
-
- `validateTemplate(bytes, {expectedTags, multiline})` şablonun etiketlerini bir listeyle tam küme
|
|
123
|
-
olarak karşılaştırır. Bilinmeyen seçenek (`{linebreaks: true}` gibi) hata verir.
|
|
124
|
-
- Rapor, sorunlar ve hata mesajları hiçbir değeri taşımaz.
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
`
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
npm run
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
1
|
+
# @sametalmdr/word-editor
|
|
2
|
+
|
|
3
|
+
Tarayıcıda çalışan bir **sayfa tuvali** editörü: sabit sayfa yüzeyleri
|
|
4
|
+
üzerinde mutlak konumlu metin kutularının içeriğini ve yerleşimini düzenler,
|
|
5
|
+
gerçek `.docx` dosyalarını açar ve orijinal paketi yamalayarak geri kaydeder.
|
|
6
|
+
Akan metin / sayfalama / tablo yok (ADR-0006). Sıfır runtime bağımlılık, saf
|
|
7
|
+
ESM, MIT lisanslı.
|
|
8
|
+
|
|
9
|
+
> ⚠️ **Durum (2026-10-26): 0.3.0-alpha hazır (0.2.0-alpha'ya `checkFit` eklendi); npm'de yayını sahip yapar. 0.2.0-alpha npm'de.** Editör çalışıyor:
|
|
10
|
+
> `.docx` aç, metin yaz, kutu taşı, kalın/italik/altı çizili, punto, hizalama,
|
|
11
|
+
> girinti, Kaydet. **Gerçek Word'de doğrulanan:** metin, kutu taşıma ve
|
|
12
|
+
> kalın — kaydedilen dosya onarımsız açılıyor ve değişiklik görünüyor.
|
|
13
|
+
> İtalik ve altı çizili aynı yazma yolundan geçiyor, ama Word'de ayrıca
|
|
14
|
+
> açılmadı. Punto, hizalama ve girinti dosyaya yazılıyor ama **Word'de henüz
|
|
15
|
+
> doğrulanmadı** (FIDELITY.md'de AÇIK). **Bugün yalnız örnek sayfalardan
|
|
16
|
+
> kullanılabiliyor** (aşağıda `app.html`): paketin public API'si `createEditor()`
|
|
17
|
+
> (bir `doc` alır, tuval editörünü dışa vermez). `.docx` import/export'u ve şablon doldurma
|
|
18
|
+
> **`/docx` alt yolunda** (aşağıda; `0.3.0-alpha`), `/canvas` FR4b'de geliyor
|
|
19
|
+
> ([docs/MASTER-PLAN.md](./docs/MASTER-PLAN.md)). Kaydedilmeyen düzenlemeler ve bilinen
|
|
20
|
+
> iki hata (yapıştırılan kutu kaydı engelliyor, silinen kutu sessizce
|
|
21
|
+
> kayboluyor): [FIDELITY.md](./FIDELITY.md) "Kutu yerleşimi" bölümü. Yol
|
|
22
|
+
> haritası: [ARCHITECTURE.md](./ARCHITECTURE.md) §6.
|
|
23
|
+
|
|
24
|
+
Bu proje Microsoft Word'ün bir klonu değildir ve Microsoft ile hiçbir
|
|
25
|
+
bağlantısı yoktur.
|
|
26
|
+
|
|
27
|
+
## Kurulum
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @sametalmdr/word-editor@0.3.0-alpha
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Saf HTML ile kullanım
|
|
34
|
+
|
|
35
|
+
Build adımı gerekmez.
|
|
36
|
+
|
|
37
|
+
```html
|
|
38
|
+
<link rel="stylesheet" href="./node_modules/@sametalmdr/word-editor/dist/styles.css" />
|
|
39
|
+
<word-editor></word-editor>
|
|
40
|
+
<script type="module">
|
|
41
|
+
import "@sametalmdr/word-editor/element";
|
|
42
|
+
</script>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## React ile kullanım
|
|
46
|
+
|
|
47
|
+
`react` bir optional peer dependency'dir — kendi React sürümünüzü kurmanız
|
|
48
|
+
gerekir.
|
|
49
|
+
|
|
50
|
+
```jsx
|
|
51
|
+
import { WordEditor } from "@sametalmdr/word-editor/react";
|
|
52
|
+
import "@sametalmdr/word-editor/styles.css";
|
|
53
|
+
|
|
54
|
+
function App() {
|
|
55
|
+
return <WordEditor />;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Framework-agnostic çekirdek API
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { createEditor } from "@sametalmdr/word-editor";
|
|
63
|
+
|
|
64
|
+
const editor = createEditor({ container: document.getElementById("root") });
|
|
65
|
+
// ...
|
|
66
|
+
editor.destroy();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## `/docx` — şablon doldurma (DOM'suz; Node, Deno ve tarayıcı için yazıldı)
|
|
70
|
+
|
|
71
|
+
`{etiket}`li bir `.docx` şablonunu veriyle doldurur. Orijinal paketi yamalar: yalnız
|
|
72
|
+
`word/document.xml` yeniden yazılır, başka her parça bayt bayt aynı kalır. Hiçbir ağ isteği
|
|
73
|
+
atmaz; sunucuda (ör. Supabase Edge Functions) ve tarayıcıda aynı fonksiyon. Kapılarla sınanan:
|
|
74
|
+
Node 24.13.1 ve Deno 2.1.4; tarayıcıda (Chrome 152) yalnız incelendi, kanıt sınıfıyla değil.
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
import { fillTemplate, inspectTemplate, TemplateError } from "@sametalmdr/word-editor/docx";
|
|
78
|
+
|
|
79
|
+
// template: bir .docx dosyasının baytları (Uint8Array)
|
|
80
|
+
try {
|
|
81
|
+
const { bytes, documentXml, report } = await fillTemplate(template, {
|
|
82
|
+
firma_adi: "Alrosoft Ltd",
|
|
83
|
+
rapor_no: "RPR-2026-0001",
|
|
84
|
+
notlar: null, // boş: serbest, report.empty'de listelenir
|
|
85
|
+
});
|
|
86
|
+
// bytes: doldurulmuş .docx
|
|
87
|
+
// documentXml: doldurulmuş word/document.xml, sıkıştırılmamış — çalışma ortamları
|
|
88
|
+
// arasında karşılaştırmayı bunun özetiyle yapın (zip baytları ortama göre değişir)
|
|
89
|
+
// report: etiket -> [{docPrId, page}], empty, unused, warnings, counts, engine
|
|
90
|
+
} catch (err) {
|
|
91
|
+
if (!(err instanceof TemplateError)) throw err;
|
|
92
|
+
for (const p of err.problems) console.log(p.code, p.tag, p.page); // hepsi birlikte
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const info = await inspectTemplate(template); // doldurmadan: etiketler, sorunlar, uyarılar
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Kurallar ([ADR-0037](./docs/adr/0037-template-fill-engine.md),
|
|
99
|
+
[ADR-0038](./docs/adr/0038-generated-output-keeps-both-copies-equal.md)):
|
|
100
|
+
|
|
101
|
+
- Etiket bir `w:t`'nin metninin tamamıdır: `{firma_adi}`, ad `[a-z][a-z0-9_]*`. Bölünmüş
|
|
102
|
+
etiket, `{ ad }`, `{#döngü}`, `{%görsel}` ve "Tarih: {tarih}" gibi karışık metin reddedilir.
|
|
103
|
+
- Etiket yalnız metin kutusunda olabilir. Kutunun iki kopyası (`mc:Choice` ve `mc:Fallback`)
|
|
104
|
+
birlikte yazılır ve eşit kaldıkları denetlenir — Word yalnız Choice'u okur, yanlış bir
|
|
105
|
+
Fallback Word'de görünmez (FILL-E2).
|
|
106
|
+
- Eksik anahtar hata; eksiklerin hepsi tek `TemplateError`'da. `null`, `""` ve yalnız boşluk
|
|
107
|
+
boştur: serbest, raporlanır.
|
|
108
|
+
- Değer string olmalı; sekme ve denetim karakterleri reddedilir. Tarih ve sayı biçimlemek
|
|
109
|
+
çağıranın işi.
|
|
110
|
+
- Satır sonu yalnız `multiline` seçeneğinin adlandırdığı etikette ve yalnız LF olarak
|
|
111
|
+
([ADR-0039](./docs/adr/0039-multi-line-values.md)): her satır etiketin kendi run'ında, aralarında
|
|
112
|
+
`w:br`, run'ın biçimi her satırda. CR, CRLF, U+2028 ve U+2029 her etikette reddedilir — motor
|
|
113
|
+
değeri sessizce değiştirmez, normalleştirmek çağıranın işi. Şablonda olmayan bir ad
|
|
114
|
+
`UNKNOWN_MULTILINE_TAG`:
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
await fillTemplate(template, { ...data, notlar: "Birinci satır\nİkinci satır" }, { multiline: ["notlar"] });
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Kutunun alabileceğinden fazla satır Word'de sessizce kırpılır (FR3-WORD-ML2); `checkFit` bunu
|
|
121
|
+
doldurmadan önce söyler (aşağıda).
|
|
122
|
+
- `validateTemplate(bytes, {expectedTags, multiline})` şablonun etiketlerini bir listeyle tam küme
|
|
123
|
+
olarak karşılaştırır. Bilinmeyen seçenek (`{linebreaks: true}` gibi) hata verir.
|
|
124
|
+
- Rapor, sorunlar ve hata mesajları hiçbir değeri taşımaz.
|
|
125
|
+
|
|
126
|
+
### `checkFit` — değer kutusuna sığıyor mu? ([ADR-0042](./docs/adr/0042-dom-free-fit-check.md))
|
|
127
|
+
|
|
128
|
+
Word kutuya sığmayan değeri sessizce kırpar. `checkFit` doldurmadan önce her değerin satırını şablonun
|
|
129
|
+
kendi kutusuyla karşılaştırır. Tarayıcı gerekmez: Calibri'nin genişlikleri, onunla metrik-uyumlu
|
|
130
|
+
Carlito'dan (OFL-1.1) bir tablo olarak paketin içinde.
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
import { checkFit, fillTemplate } from "@sametalmdr/word-editor/docx";
|
|
134
|
+
|
|
135
|
+
const fit = await checkFit(template, data, { ...manifest.options, ...manifest.fit });
|
|
136
|
+
if (!fit.ok) {
|
|
137
|
+
for (const t of fit.tags) {
|
|
138
|
+
for (const o of t.occurrences) {
|
|
139
|
+
if (o.status === "overflows" || o.status === "unknown") console.log(t.name, o.status, o.reason, o.marginPt);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- **Durumlar:** her occurrence `fits`, `overflows`, `unknown` ya da `empty` döner.
|
|
146
|
+
- Ölçülen occurrence en dar satırının `widthPt`, `availablePt` ve `marginPt` değerlerini taşır.
|
|
147
|
+
- `unknown` (ve sekmesini durağından iten `overflows`) kapalı bir listeden bir `reason` taşır.
|
|
148
|
+
- Etiketin durumu, occurrence'larının en kötüsüdür.
|
|
149
|
+
- **Tolerans:** τ = 0,05 pt + glif başına 0,025 pt.
|
|
150
|
+
- `fits`: satır τ payıyla sığar.
|
|
151
|
+
- `overflows`: satır τ'nun ötesinde taşar.
|
|
152
|
+
- Aradaki `unknown(BORDERLINE)` için karar verilmez.
|
|
153
|
+
- **Sondaki boşluklar:** Word'ün onları kenarın ötesine asılı bırakıp bırakmadığı sınanmadı. `fits` onları
|
|
154
|
+
sayarak sığmayı, `overflows` onlarsız taşmayı ister; yalnız onlar karar veriyorsa `unknown(TRAILING_SPACE)`.
|
|
155
|
+
Değeri kırpmak bu durumu ortadan kaldırır.
|
|
156
|
+
- **Çok satırlı değer** `capacity` ister: `{etiket: satır}`, manifestin `fit` bloğunda. Taşan satır en az
|
|
157
|
+
bir satır daha alır. Satır sayısı ile taşan satır sayısının toplamı kapasiteyi geçerse `overflows`.
|
|
158
|
+
- **Kırma yok:** satır kırma noktası seçilmez. Ölçülemeyen biçim `unknown` döner (başka bir font,
|
|
159
|
+
döndürülmüş ya da gruplanmış kutu, `kern`, sola dayalı olmayan sekme durağı, iç boşluklu kutuda ya da
|
|
160
|
+
sola dayalı olmayan satırda sekme vb.).
|
|
161
|
+
- **Doğrulama:** `fillTemplate`'in reddettiğini aynı `TemplateError` ile reddeder. Hiçbir şey yazmaz;
|
|
162
|
+
rapor değer taşımaz.
|
|
163
|
+
- **Öneri:** onayı `overflows` **ve** `unknown` durumunda kapatın.
|
|
164
|
+
|
|
165
|
+
Bilinen sınırlar ve sınanan ortamlar: [CHANGELOG.md](./CHANGELOG.md).
|
|
166
|
+
|
|
167
|
+
## Ürün sayfası — `app.html` (DOCX aç → düzenle → kaydet)
|
|
168
|
+
|
|
169
|
+
Ribbon'lı tam editör. Paket henüz bu yüzeyi dışa vermediği için (yukarıdaki
|
|
170
|
+
durum notu) bugün yalnız repo içinden çalışır:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npm run serve
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
http://127.0.0.1:8080/examples/static/app.html
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Dosya** sekmesindeki **Dosya Seç** ile `test/corpus/` altındaki bir belgeyi
|
|
181
|
+
seç (dosya yalnız okunur, değiştirilmez). Çift tık bir kutunun içinde metin moduna geçer,
|
|
182
|
+
tek tık kutuyu seçer (ADR-0024). **Kaydet (.docx)** orijinal paketi yamalayarak
|
|
183
|
+
indirir. "PDF indir" henüz bağlı değil — bugün PDF için görüntüleyicinin
|
|
184
|
+
Ctrl+P'si var (aşağıda).
|
|
185
|
+
|
|
186
|
+
## Corpus görüntüleyici (demo)
|
|
187
|
+
|
|
188
|
+
46 corpus belgesini gerçek renderer ile tarayıcıda gösterir.
|
|
189
|
+
**Görüntüleyici — düzenleme yok.** İki komut:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
npm run corpus:canvas
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npm run serve
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Sonra tarayıcıda aç:
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
http://127.0.0.1:8080/examples/static/viewer.html
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Solda 46 belge, seçince sayfaları çizilir; başlıkta kutu/dekorasyon/sayfa
|
|
206
|
+
sayısı ve render süresi görünür.
|
|
207
|
+
|
|
208
|
+
**Çift tıklayarak açılmaz, ve bu ölçülmüş bir kısıt.** Chrome 151 /
|
|
209
|
+
Windows 10 22H2'de `file://` üzerinde statik ES modül import'u, dinamik
|
|
210
|
+
`import()` ve `fetch()` **üçü de bloklanıyor**; yalnızca inline klasik
|
|
211
|
+
`<script>` koşuyor. Gerçek renderer'ı import etmenin başka yolu yok. Dört
|
|
212
|
+
ölçümün tamamı [docs/viewer-measurement.md](./docs/viewer-measurement.md)
|
|
213
|
+
§0'da; sunucu `node:http` ile yazıldı, **sıfır bağımlılık**, yalnızca
|
|
214
|
+
loopback. Aynı kısıt `examples/static/canvas.html` ve `index.html` için de
|
|
215
|
+
geçerli.
|
|
216
|
+
|
|
217
|
+
`npm run corpus:canvas` Python ister (`scripts/docx-to-canvas-json.py`
|
|
218
|
+
dönüştürücüsünü çağırır) ve bu yüzden `npm run ci`'nin parçası **değildir** —
|
|
219
|
+
`corpus:check` ve `corpus:names` ile aynı gerekçe. Çıktı
|
|
220
|
+
`examples/static/corpus-json/` altına yazılır, gitignore'ludur, her koşumda
|
|
221
|
+
baştan üretilir. `test/corpus/` **okunur, asla yazılmaz** (CLAUDE.md #16).
|
|
222
|
+
|
|
223
|
+
### PDF — Tier 0
|
|
224
|
+
|
|
225
|
+
Görüntüleyicide **Ctrl+P → "PDF olarak kaydet"**. Sayfa yüzeyleri belgenin
|
|
226
|
+
kendi boyutunda basılır (A4 dikey, A4 yatay ve A5 corpus'ta hepsi var), UI
|
|
227
|
+
kromu gizlenir.
|
|
228
|
+
|
|
229
|
+
**Bu bizim PDF writer'ımız değil, tarayıcınınki** — `ARCHITECTURE.md` §7'nin
|
|
230
|
+
Tier 0'ı. Sunucuda üretilen, gömülü fontlu PDF FR5'te geliyor (eski MP10, yol
|
|
231
|
+
haritasındaki P7); yolunu — kendi yazıcımız, pdf-lib ya da Cloudflare Browser Run — FR5
|
|
232
|
+
başında sahip seçiyor (ADR-0036 Karar 5).
|
|
233
|
+
|
|
234
|
+
**Gözle kontrol — henüz yapılmadı, yapılacaksa şöyle:** üç belgeyi seçip
|
|
235
|
+
Ctrl+P ile önizlemeye bak; kâğıt boyutu belgenin kendi boyutuna oturmalı,
|
|
236
|
+
kenar boşluğu olmamalı, sol liste ve üst başlık görünmemeli.
|
|
237
|
+
|
|
238
|
+
| Belge | Beklenen kâğıt | Neden bu üçü |
|
|
239
|
+
|---|---|---|
|
|
240
|
+
| `AA01` | A4 dikey (595.5×842 pt) | corpus'un çoğunluğu |
|
|
241
|
+
| `PK01` | **A4 YATAY** (842×595.5 pt) | sabit `A4` varsayımının kırılacağı yer |
|
|
242
|
+
| `R001` | **A5** (420×595.5 pt) | ikinci kırılma noktası; 71 sayfa |
|
|
243
|
+
|
|
244
|
+
Üçü de doğru basıyorsa sayfa boyutu belge başına yazılıyor demektir.
|
|
245
|
+
|
|
246
|
+
Ölçüm sonuçları: [docs/viewer-measurement.md](./docs/viewer-measurement.md).
|
|
247
|
+
|
|
248
|
+
## Tuval — kutu düzenleme (demo, P3b-a)
|
|
249
|
+
|
|
250
|
+
Görüntüleyiciden farklı olarak **burada düzenleme var** — metin değil, kutu
|
|
251
|
+
geometrisi: seç, tutamakla sürükle/boyutlandır, Ctrl+Z ile geri al,
|
|
252
|
+
kopyala/yapıştır, dekoratif bir şeklin kenarına yaklaştırıp snap'i gör.
|
|
253
|
+
`src/canvas/`'ın dokuz saf modülü + `CanvasController` + `Overlay`, gerçek
|
|
254
|
+
bir tarayıcıya bağlı (`docs/adr/0018-canvas-interaction-layer.md`).
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
npm run serve
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
http://127.0.0.1:8080/examples/static/canvas.html
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Dosya seçiciyle bir belge JSON'u yükle: `test/fixtures/canvas/fifty-boxes.json`
|
|
265
|
+
(50 kutu, 5 dekorasyon, 2 sayfa) hazır bir örnek; `npm run corpus:canvas`'ın
|
|
266
|
+
ürettiği `examples/static/corpus-json/*.json` de aynı formatta çalışır.
|
|
267
|
+
|
|
268
|
+
**Ölçülmemiş sabitler, sayfanın kendi geçici değerleri — kütüphaneye değil:**
|
|
269
|
+
tutamak boyutu, snap eşiği, kademe eşikleri hiçbiri ölçülmedi (Ö2/Ö4,
|
|
270
|
+
ADR-0018 §9.0). `canvas.html` kendi `EXAMPLE_METRICS` nesnesini enjekte
|
|
271
|
+
ediyor; `src/canvas/controller.js`'in `requireMetrics`'i eksik alanda hâlâ
|
|
272
|
+
gerçek `TypeError` atıyor, `src/` altına hiçbir varsayılan sızmadı.
|
|
273
|
+
|
|
274
|
+
Aynı `file://` kısıtı geçerli (yukarıdaki görüntüleyici bölümüne bakınız).
|
|
275
|
+
~~Metin düzenleme bu turun kapsamında değil~~ — 2026-08-29'dan beri
|
|
276
|
+
(ADR-0024) çift tık kutunun içinde metin moduna geçiyor, ve sayfa artık
|
|
277
|
+
`.docx` da açıp kaydedebiliyor. Ürün yüzeyi ise `app.html` (yukarıda).
|
|
278
|
+
|
|
279
|
+
## Mimari
|
|
280
|
+
|
|
281
|
+
Tasarım kararları için [ARCHITECTURE.md](./ARCHITECTURE.md),
|
|
282
|
+
uyumluluk sözleşmesi için [FIDELITY.md](./FIDELITY.md).
|
|
283
|
+
|
|
284
|
+
## Lisans
|
|
285
|
+
|
|
286
|
+
MIT — bkz. [LICENSE](./LICENSE).
|