Class: Rpdfium::Structure::Element
- Inherits:
-
Object
- Object
- Rpdfium::Structure::Element
- Defined in:
- lib/rpdfium/structure/element.rb
Overview
Element di un PDF tagged StructTree.
Un Element rappresenta un nodo della struttura logica del documento: ‘Document`, `P` (paragrafo), `H1`..`H6` (headings), `Table`, `TR`, `TH`, `TD`, `Figure`, `Span`, `Lbl`, `LI`, `Caption`, ecc. Vedi PDF spec §14.8 per la tassonomia completa.
Gli element non hanno una vita autonoma: appartengono al Tree che li ha generati. Quando il Tree viene chiuso, gli element diventano invalidi. Non chiamare metodi su un element dopo ‘tree.close`.
Tutti i metodi sono read-only: PDFium non espone API per modificare il StructTree (è una struttura “di sola lettura” anche nel suo C API pubblico).
Instance Attribute Summary collapse
-
#handle ⇒ Object
readonly
Returns the value of attribute handle.
-
#tree ⇒ Object
readonly
Returns the value of attribute tree.
Instance Method Summary collapse
-
#actual_text ⇒ Object
ActualText: override del testo “logico” per l’element.
-
#alt_text ⇒ Object
AltText: testo alternativo per Figure / Formula / immagini.
-
#attributes ⇒ Object
Attributi PDF strutturali.
-
#children ⇒ Object
Figli diretti dell’element.
-
#expansion ⇒ Object
Expansion text per abbreviazioni (es. element type “Span” con contenuto “Dr.” e expansion “Doctor”).
-
#id ⇒ Object
ID univoco dell’element (se dichiarato nel /ID dictionary del StructTreeRoot).
-
#initialize(tree, handle) ⇒ Element
constructor
A new instance of Element.
- #inspect ⇒ Object
-
#lang ⇒ Object
Lingua dichiarata sull’element (es. “it-IT”, “en-US”).
-
#leaves ⇒ Object
Foglie del sub-tree (element senza figli).
-
#marked_content_ids ⇒ Object
Marked Content IDs collegati a questo element.
-
#obj_type ⇒ Object
Tipo dell’oggetto PDF sottostante: di solito “StructElem”, ma può essere “MCR” (Marked Content Reference) o “OBJR” (Object Reference) per nodi specializzati.
-
#parent ⇒ Object
Parent.
-
#text ⇒ Object
Testo dell’element, ricostruito dalla pagina via MCID.
-
#title ⇒ Object
Title attribute (raro, usato in alcuni documenti per dare un nome parlante all’element, es. “Capitolo 1”).
- #to_s ⇒ Object
-
#type ⇒ Object
Tipo strutturale dell’element (es. “P”, “H1”, “Table”, “TR”, “TD”).
-
#walk {|_self| ... } ⇒ Object
Walk depth-first dell’intero sub-tree a partire da questo element.
Constructor Details
#initialize(tree, handle) ⇒ Element
Returns a new instance of Element.
22 23 24 25 |
# File 'lib/rpdfium/structure/element.rb', line 22 def initialize(tree, handle) @tree = tree @handle = handle end |
Instance Attribute Details
#handle ⇒ Object (readonly)
Returns the value of attribute handle.
20 21 22 |
# File 'lib/rpdfium/structure/element.rb', line 20 def handle @handle end |
#tree ⇒ Object (readonly)
Returns the value of attribute tree.
20 21 22 |
# File 'lib/rpdfium/structure/element.rb', line 20 def tree @tree end |
Instance Method Details
#actual_text ⇒ Object
ActualText: override del testo “logico” per l’element. Risolve legature (PDF mostra ‘fi` ma actual_text dice “fi”), simboli math (“∫” → “integral”), abbreviazioni. Se presente, ha priorità sul testo grafico per accessibility e ricerca.
63 64 65 |
# File 'lib/rpdfium/structure/element.rb', line 63 def actual_text read_utf16_string(:FPDF_StructElement_GetActualText) end |
#alt_text ⇒ Object
AltText: testo alternativo per Figure / Formula / immagini. PDF/UA richiede che ogni Figure abbia un alt_text non vuoto.
69 70 71 |
# File 'lib/rpdfium/structure/element.rb', line 69 def alt_text read_utf16_string(:FPDF_StructElement_GetAltText) end |
#attributes ⇒ Object
Attributi PDF strutturali. Ritorna un Hash { name => value } con tutti gli attributi dichiarati su questo element (RowSpan, ColSpan, Scope, Headers, BBox, ecc.). I valori sono Ruby-native: Integer, Float, String, true/false, o Array per attributi “Headers” che contengono liste di ID.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/rpdfium/structure/element.rb', line 169 def attributes result = {} attr_count = Raw.FPDF_StructElement_GetAttributeCount(@handle) return result if attr_count <= 0 (0...attr_count).each do |ai| attr = Raw.FPDF_StructElement_GetAttributeAtIndex(@handle, ai) next if attr.null? key_count = Raw.FPDF_StructElement_Attr_GetCount(attr) (0...key_count).each do |ki| name = read_attr_name(attr, ki) next if name.nil? || name.empty? value = read_attr_value(attr, name) result[name] = value unless value.nil? end end result end |
#children ⇒ Object
Figli diretti dell’element. Ordinati come dichiarati nel PDF (top-to-bottom, left-to-right per reading order).
108 109 110 111 112 113 114 115 116 |
# File 'lib/rpdfium/structure/element.rb', line 108 def children n = Raw.FPDF_StructElement_CountChildren(@handle) return [] if n <= 0 (0...n).filter_map do |i| child_handle = Raw.FPDF_StructElement_GetChildAtIndex(@handle, i) child_handle.null? ? nil : Element.new(@tree, child_handle) end end |
#expansion ⇒ Object
Expansion text per abbreviazioni (es. element type “Span” con contenuto “Dr.” e expansion “Doctor”). Usato per text-to-speech.
75 76 77 |
# File 'lib/rpdfium/structure/element.rb', line 75 def expansion read_utf16_string(:FPDF_StructElement_GetExpansion) end |
#id ⇒ Object
ID univoco dell’element (se dichiarato nel /ID dictionary del StructTreeRoot). Permette riferimenti cross-element (es. Headers attribute di una cella TD che punta a un TH per id).
49 50 51 |
# File 'lib/rpdfium/structure/element.rb', line 49 def id read_utf16_string(:FPDF_StructElement_GetID) end |
#inspect ⇒ Object
201 202 203 |
# File 'lib/rpdfium/structure/element.rb', line 201 def inspect "#<Rpdfium::Structure::Element #{self}>" end |
#lang ⇒ Object
Lingua dichiarata sull’element (es. “it-IT”, “en-US”). Ereditata dal parent se non sovrascritta. Utile per pipeline language-aware.
55 56 57 |
# File 'lib/rpdfium/structure/element.rb', line 55 def lang read_utf16_string(:FPDF_StructElement_GetLang) end |
#leaves ⇒ Object
Foglie del sub-tree (element senza figli). Sono i nodi che tipicamente hanno il MCID diretto.
138 139 140 141 142 |
# File 'lib/rpdfium/structure/element.rb', line 138 def leaves return [self] if children.empty? children.flat_map(&:leaves) end |
#marked_content_ids ⇒ Object
Marked Content IDs collegati a questo element. Un element ha tipicamente 1 MCID (es. una ‘<P>` ha tutto il testo del paragrafo dentro un BDC con mcid=N) oppure 0 (element strutturale puro: `<Document>`, `<Table>`, `<TR>` — i loro MCID stanno nei figli foglia).
Per collegare un MCID al testo della pagina: leggi i page object e raggruppa per ‘FPDFPageObj_GetMarkedContentID`. Vedi `Element#text`.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/rpdfium/structure/element.rb', line 86 def marked_content_ids first = Raw.FPDF_StructElement_GetMarkedContentID(@handle) count = Raw.FPDF_StructElement_GetMarkedContentIdCount(@handle) # Casi: GetMarkedContentIdCount ritorna -1 quando non ci sono MCID # diretti (element strutturale). GetMarkedContentID ritorna -1 # nello stesso caso. return [] if count <= 0 && first < 0 # Quando esiste un solo MCID, GetMarkedContentIdCount può ritornare # 0 o -1 mentre GetMarkedContentID dà il valore. Coalescenza: if count <= 0 first >= 0 ? [first] : [] else (0...count).filter_map do |i| mcid = Raw.FPDF_StructElement_GetMarkedContentIdAtIndex(@handle, i) mcid >= 0 ? mcid : nil end end end |
#obj_type ⇒ Object
Tipo dell’oggetto PDF sottostante: di solito “StructElem”, ma può essere “MCR” (Marked Content Reference) o “OBJR” (Object Reference) per nodi specializzati. La maggior parte degli utenti usa ‘type`.
36 37 38 |
# File 'lib/rpdfium/structure/element.rb', line 36 def obj_type read_utf16_string(:FPDF_StructElement_GetObjType) end |
#parent ⇒ Object
Parent. Nil per gli element root (figli diretti del StructTree).
119 120 121 122 123 124 |
# File 'lib/rpdfium/structure/element.rb', line 119 def parent h = Raw.FPDF_StructElement_GetParent(@handle) return nil if h.null? Element.new(@tree, h) end |
#text ⇒ Object
Testo dell’element, ricostruito dalla pagina via MCID. Risoluzione:
-
Se ‘actual_text` è presente, lo usa (gestisce legature/abbreviazioni).
-
Altrimenti raccoglie tutti gli MCID del sub-tree (questo element + ricorsivamente i figli) e concatena il testo dei page objects con quei MCID, in document order.
Per element strutturali puri (‘Table`, `TR`) il testo è la concatenazione di tutti i discendenti — utile come “summary”.
152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/rpdfium/structure/element.rb', line 152 def text return actual_text if actual_text && !actual_text.empty? # Raccoglie MCID di tutto il sub-tree depth-first all_mcids = [] walk { |el| all_mcids.concat(el.marked_content_ids) } return "" if all_mcids.empty? mcid_map = @tree.send(:mcid_text_map) all_mcids.filter_map { |id| mcid_map[id] }.join end |
#title ⇒ Object
Title attribute (raro, usato in alcuni documenti per dare un nome parlante all’element, es. “Capitolo 1”).
42 43 44 |
# File 'lib/rpdfium/structure/element.rb', line 42 def title read_utf16_string(:FPDF_StructElement_GetTitle) end |
#to_s ⇒ Object
190 191 192 193 194 195 196 197 198 199 |
# File 'lib/rpdfium/structure/element.rb', line 190 def to_s parts = ["<#{type || obj_type || '?'}>"] mcids = marked_content_ids parts << "mcid=#{mcids.first}" if mcids.size == 1 parts << "mcids=#{mcids.inspect}" if mcids.size > 1 parts << "lang=#{lang.inspect}" if lang parts << "actual_text=#{actual_text.inspect[0, 30]}" if actual_text parts << "alt_text=#{alt_text.inspect[0, 30]}" if alt_text parts.join(" ") end |
#type ⇒ Object
Tipo strutturale dell’element (es. “P”, “H1”, “Table”, “TR”, “TD”). Nil se PDFium non riesce a leggerlo (element placeholder).
29 30 31 |
# File 'lib/rpdfium/structure/element.rb', line 29 def type read_utf16_string(:FPDF_StructElement_GetType) end |
#walk {|_self| ... } ⇒ Object
Walk depth-first dell’intero sub-tree a partire da questo element. Visita prima self, poi ricorsivamente i figli. Senza block ritorna un Enumerator.
129 130 131 132 133 134 |
# File 'lib/rpdfium/structure/element.rb', line 129 def walk(&block) return enum_for(:walk) unless block yield self children.each { |c| c.walk(&block) } end |