carve-hexapdf 0.1.4 → 0.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/README.md +3 -0
- data/lib/carve/hexapdf/renderer.rb +27 -5
- data/lib/carve/hexapdf/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 52d77d202d7f1390346e49475aa665563e045e3bcf0c411bfb10a0d99c800070
|
|
4
|
+
data.tar.gz: 74687ef32c19f1969dff555ace0311b406c65aecb2b7ea0fa6c5eeced9977b3c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 718e37565452624372860471353c73c80b26566e603d62b60912d2dba8ec5b99555c2671c7663ddc42dac18b88c620b091490908eb756f2c1277bf1a7f0ea731
|
|
7
|
+
data.tar.gz: 11b5129dd95d3f1ffd4260a136f6c842a381d4286fcaedac400ff53ca25b49b084e3d6f58c725b8a56d74dc29343149307c42ae586308b91701b546250302ef0
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.5] - 2026-10-24
|
|
11
|
+
|
|
12
|
+
Ruby interchange text now appears in rendered PDFs, and tables with span markers render without a PDF layout error.
|
|
13
|
+
|
|
14
|
+
### Fixes
|
|
15
|
+
|
|
16
|
+
- Ruby base text and annotations render together instead of losing the annotation (#58).
|
|
17
|
+
- Tables with ownerless span markers or a header rowspan crossing into body rows render without a PDF layout error (#60).
|
|
18
|
+
|
|
19
|
+
**Full Changelog**: https://github.com/markup-carve/carve-hexapdf/compare/v0.1.4...v0.1.5
|
|
20
|
+
|
|
21
|
+
|
|
10
22
|
## [0.1.4] - 2026-10-23
|
|
11
23
|
|
|
12
24
|
### Fixed
|
data/README.md
CHANGED
|
@@ -54,6 +54,9 @@ ast = Carve.parse("# From AST")
|
|
|
54
54
|
pdf_bytes = Carve::Hexapdf.render_ast(ast)
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
+
For interchange `ruby` nodes, PDF text shows each pair as
|
|
58
|
+
`base(annotation)`, including `()` when the annotation is empty.
|
|
59
|
+
|
|
57
60
|
### Includes
|
|
58
61
|
|
|
59
62
|
A Carve document can pull another file in with `{{ path }}`. A String has no
|
|
@@ -429,7 +429,9 @@ module Carve
|
|
|
429
429
|
resolved = resolve_spans(Array(node[:rows]))
|
|
430
430
|
return if resolved.empty?
|
|
431
431
|
|
|
432
|
-
|
|
432
|
+
# HexaPDF cannot repeat a header whose cell spans into the body.
|
|
433
|
+
header_count = resolved.first.any? { |o| o[:header] } &&
|
|
434
|
+
resolved.first.none? { |o| o[:row_span] > 1 } ? 1 : 0
|
|
433
435
|
table_style = style_for("table")
|
|
434
436
|
header_style = style_for("table.header")
|
|
435
437
|
|
|
@@ -478,8 +480,17 @@ module Carve
|
|
|
478
480
|
case cell[:span]
|
|
479
481
|
when "colspan"
|
|
480
482
|
owner = last || col_owner[col - 1]
|
|
481
|
-
|
|
482
|
-
|
|
483
|
+
if owner
|
|
484
|
+
owner[:col_span] += 1
|
|
485
|
+
col_owner[col] = owner
|
|
486
|
+
else
|
|
487
|
+
# A leading marker has no cell to extend. Keep its grid slot
|
|
488
|
+
# so the table has a drawable cell in this row.
|
|
489
|
+
o = { cell: cell, header: cell[:header], col_span: 1, row_span: 1 }
|
|
490
|
+
emitted << o
|
|
491
|
+
last = o
|
|
492
|
+
col_owner[col] = o
|
|
493
|
+
end
|
|
483
494
|
when "rowspan"
|
|
484
495
|
owner = col_owner[col]
|
|
485
496
|
# A multi-column cell has one `^` per covered column on the next
|
|
@@ -488,8 +499,12 @@ module Carve
|
|
|
488
499
|
owner[:row_span] += 1
|
|
489
500
|
bumped[owner.object_id] = true
|
|
490
501
|
end
|
|
491
|
-
|
|
492
|
-
|
|
502
|
+
if owner.nil?
|
|
503
|
+
o = { cell: cell, header: cell[:header], col_span: 1, row_span: 1 }
|
|
504
|
+
emitted << o
|
|
505
|
+
col_owner[col] = o
|
|
506
|
+
end
|
|
507
|
+
# A valid owner's slot remains available for further `^` rows.
|
|
493
508
|
else
|
|
494
509
|
o = { cell: cell, header: cell[:header], col_span: 1, row_span: 1 }
|
|
495
510
|
emitted << o
|
|
@@ -594,6 +609,13 @@ module Carve
|
|
|
594
609
|
when "substitution"
|
|
595
610
|
emit_half(node[:old], node[:oldText], ctx.merge(strike: true), out)
|
|
596
611
|
emit_half(node[:new], node[:newText], ctx.merge(underline: true), out)
|
|
612
|
+
when "ruby"
|
|
613
|
+
Array(node[:pairs]).each do |pair|
|
|
614
|
+
Array(pair[:base]).each { |part| emit_inline(part, ctx, out) }
|
|
615
|
+
out << run("(", ctx)
|
|
616
|
+
Array(pair[:annotation]).each { |part| emit_inline(part, ctx, out) }
|
|
617
|
+
out << run(")", ctx)
|
|
618
|
+
end
|
|
597
619
|
when "smart_punctuation" then out << run(smart_punctuation_text(node), ctx)
|
|
598
620
|
# A character the author escaped. The backslash is authoring syntax, so
|
|
599
621
|
# the page shows the character - but the node has no children, so
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: carve-hexapdf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- markup-carve
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: carve-lang
|