89
89
TreeObject ,
90
90
read_object ,
91
91
)
92
- from .types import OutlinesType , PagemodeType
92
+ from .types import OutlineType , PagemodeType
93
93
from .xmp import XmpInformation
94
94
95
95
@@ -677,19 +677,30 @@ def getNamedDestinations(
677
677
return self ._get_named_destinations (tree , retval )
678
678
679
679
@property
680
- def outlines (self ) -> OutlinesType :
680
+ def outline (self ) -> OutlineType :
681
681
"""
682
- Read-only property for outlines present in the document.
682
+ Read-only property for the outline (i.e., a collection of 'outline items'
683
+ which are also known as 'bookmarks') present in the document.
683
684
684
685
:return: a nested list of :class:`Destinations<PyPDF2.generic.Destination>`.
685
686
"""
686
- return self ._get_outlines ()
687
+ return self ._get_outline ()
687
688
688
- def _get_outlines (
689
- self , node : Optional [DictionaryObject ] = None , outlines : Optional [Any ] = None
690
- ) -> OutlinesType :
691
- if outlines is None :
692
- outlines = []
689
+ @property
690
+ def outlines (self ) -> OutlineType :
691
+ """
692
+ .. deprecated:: 2.9.0
693
+
694
+ Use :py:attr:`outline` instead.
695
+ """
696
+ deprecate_with_replacement ("outlines" , "outline" )
697
+ return self .outline
698
+
699
+ def _get_outline (
700
+ self , node : Optional [DictionaryObject ] = None , outline : Optional [Any ] = None
701
+ ) -> OutlineType :
702
+ if outline is None :
703
+ outline = []
693
704
catalog = cast (DictionaryObject , self .trailer [TK .ROOT ])
694
705
695
706
# get the outline dictionary and named destinations
@@ -699,49 +710,49 @@ def _get_outlines(
699
710
except PdfReadError :
700
711
# this occurs if the /Outlines object reference is incorrect
701
712
# for an example of such a file, see https://unglueit-files.s3.amazonaws.com/ebf/7552c42e9280b4476e59e77acc0bc812.pdf
702
- # so continue to load the file without the Bookmarks
703
- return outlines
713
+ # so continue to load the file without the Outlines
714
+ return outline
704
715
705
716
if isinstance (lines , NullObject ):
706
- return outlines
717
+ return outline
707
718
708
719
# TABLE 8.3 Entries in the outline dictionary
709
720
if lines is not None and "/First" in lines :
710
721
node = cast (DictionaryObject , lines ["/First" ])
711
722
self ._namedDests = self ._get_named_destinations ()
712
723
713
724
if node is None :
714
- return outlines
725
+ return outline
715
726
716
- # see if there are any more outlines
727
+ # see if there are any more outline items
717
728
while True :
718
- outline = self ._build_outline (node )
719
- if outline :
720
- outlines .append (outline )
729
+ outline_obj = self ._build_outline_item (node )
730
+ if outline_obj :
731
+ outline .append (outline_obj )
721
732
722
- # check for sub-outlines
733
+ # check for sub-outline
723
734
if "/First" in node :
724
- sub_outlines : List [Any ] = []
725
- self ._get_outlines (cast (DictionaryObject , node ["/First" ]), sub_outlines )
726
- if sub_outlines :
727
- outlines .append (sub_outlines )
735
+ sub_outline : List [Any ] = []
736
+ self ._get_outline (cast (DictionaryObject , node ["/First" ]), sub_outline )
737
+ if sub_outline :
738
+ outline .append (sub_outline )
728
739
729
740
if "/Next" not in node :
730
741
break
731
742
node = cast (DictionaryObject , node ["/Next" ])
732
743
733
- return outlines
744
+ return outline
734
745
735
746
def getOutlines (
736
- self , node : Optional [DictionaryObject ] = None , outlines : Optional [Any ] = None
737
- ) -> OutlinesType : # pragma: no cover
747
+ self , node : Optional [DictionaryObject ] = None , outline : Optional [Any ] = None
748
+ ) -> OutlineType : # pragma: no cover
738
749
"""
739
750
.. deprecated:: 1.28.0
740
751
741
- Use :py:attr:`outlines ` instead.
752
+ Use :py:attr:`outline ` instead.
742
753
"""
743
- deprecate_with_replacement ("getOutlines" , "outlines " )
744
- return self ._get_outlines (node , outlines )
754
+ deprecate_with_replacement ("getOutlines" , "outline " )
755
+ return self ._get_outline (node , outline )
745
756
746
757
def _get_page_number_by_indirect (
747
758
self , indirect_ref : Union [None , int , NullObject , IndirectObject ]
@@ -809,7 +820,7 @@ def _build_destination(
809
820
array : List [Union [NumberObject , IndirectObject , NullObject , DictionaryObject ]],
810
821
) -> Destination :
811
822
page , typ = None , None
812
- # handle outlines with missing or invalid destination
823
+ # handle outline items with missing or invalid destination
813
824
if (
814
825
isinstance (array , (type (None ), NullObject ))
815
826
or (isinstance (array , ArrayObject ) and len (array ) == 0 )
@@ -835,8 +846,8 @@ def _build_destination(
835
846
title , indirect_ref , TextStringObject ("/Fit" ) # type: ignore
836
847
)
837
848
838
- def _build_outline (self , node : DictionaryObject ) -> Optional [Destination ]:
839
- dest , title , outline = None , None , None
849
+ def _build_outline_item (self , node : DictionaryObject ) -> Optional [Destination ]:
850
+ dest , title , outline_item = None , None , None
840
851
841
852
# title required for valid outline
842
853
# PDF Reference 1.7: TABLE 8.4 Entries in an outline item dictionary
@@ -861,40 +872,40 @@ def _build_outline(self, node: DictionaryObject) -> Optional[Destination]:
861
872
dest = dest ["/D" ]
862
873
863
874
if isinstance (dest , ArrayObject ):
864
- outline = self ._build_destination (title , dest ) # type: ignore
875
+ outline_item = self ._build_destination (title , dest ) # type: ignore
865
876
elif isinstance (dest , str ):
866
877
# named destination, addresses NameObject Issue #193
867
878
try :
868
- outline = self ._build_destination (
879
+ outline_item = self ._build_destination (
869
880
title , self ._namedDests [dest ].dest_array
870
881
)
871
882
except KeyError :
872
883
# named destination not found in Name Dict
873
- outline = self ._build_destination (title , None )
884
+ outline_item = self ._build_destination (title , None )
874
885
elif isinstance (dest , type (None )):
875
- # outline not required to have destination or action
886
+ # outline item not required to have destination or action
876
887
# PDFv1.7 Table 153
877
- outline = self ._build_destination (title , dest ) # type: ignore
888
+ outline_item = self ._build_destination (title , dest ) # type: ignore
878
889
else :
879
890
if self .strict :
880
891
raise PdfReadError (f"Unexpected destination { dest !r} " )
881
- outline = self ._build_destination (title , None ) # type: ignore
892
+ outline_item = self ._build_destination (title , None ) # type: ignore
882
893
883
- # if outline created, add color, format, and child count if present
884
- if outline :
894
+ # if outline item created, add color, format, and child count if present
895
+ if outline_item :
885
896
if "/C" in node :
886
- # Color of outline in (R, G, B) with values ranging 0.0-1.0
887
- outline [NameObject ("/C" )] = ArrayObject (FloatObject (c ) for c in node ["/C" ]) # type: ignore
897
+ # Color of outline item font in (R, G, B) with values ranging 0.0-1.0
898
+ outline_item [NameObject ("/C" )] = ArrayObject (FloatObject (c ) for c in node ["/C" ]) # type: ignore
888
899
if "/F" in node :
889
900
# specifies style characteristics bold and/or italic
890
901
# 1=italic, 2=bold, 3=both
891
- outline [NameObject ("/F" )] = node ["/F" ]
902
+ outline_item [NameObject ("/F" )] = node ["/F" ]
892
903
if "/Count" in node :
893
904
# absolute value = num. visible children
894
905
# positive = open/unfolded, negative = closed/folded
895
- outline [NameObject ("/Count" )] = node ["/Count" ]
906
+ outline_item [NameObject ("/Count" )] = node ["/Count" ]
896
907
897
- return outline
908
+ return outline_item
898
909
899
910
@property
900
911
def pages (self ) -> _VirtualList :
@@ -961,9 +972,9 @@ def page_mode(self) -> Optional[PagemodeType]:
961
972
:widths: 50 200
962
973
963
974
* - /UseNone
964
- - Do not show outlines or thumbnails panels
975
+ - Do not show outline or thumbnails panels
965
976
* - /UseOutlines
966
- - Show outlines (aka bookmarks) panel
977
+ - Show outline (aka bookmarks) panel
967
978
* - /UseThumbs
968
979
- Show page thumbnails panel
969
980
* - /FullScreen
0 commit comments