Skip to content

Commit

Permalink
release v2.1.4
Browse files Browse the repository at this point in the history
  • Loading branch information
jorisschellekens committed Oct 1, 2022
1 parent 408ff01 commit 9f456ce
Show file tree
Hide file tree
Showing 455 changed files with 3,169 additions and 1,638 deletions.
3 changes: 2 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ include borb/io/write/document/resources/*.icm
include borb/pdf/canvas/font/composite_font/cmaps/*
include borb/pdf/canvas/font/simple_font/afm/*.afm
include borb/pdf/canvas/layout/emoji/resources/*.png
include borb/pdf/canvas/layout/hyphenation/resources/*.json
include borb/pdf/canvas/layout/hyphenation/resources/*.json
include borb/pdf/canvas/lipsum/resources/*.json
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
[![Corpus Coverage : 100.0%](https://img.shields.io/badge/corpus%20coverage-100.0%25-green)]()
[![Text Extraction : 93.1%](https://img.shields.io/badge/text%20extraction-93.1%25-green)]()
[![Public Method Documentation : 100%](https://img.shields.io/badge/public%20method%20documentation-100%25-green)]()
[![Number of Tests : 396](https://img.shields.io/badge/number%20of%20tests-396-green)]()


[![Downloads](https://pepy.tech/badge/borb)](https://pepy.tech/project/borb)
[![Downloads](https://pepy.tech/badge/borb/month)](https://pepy.tech/project/borb)
Expand Down
16 changes: 12 additions & 4 deletions borb/io/read/postfix/postfix_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,9 @@ def evaluate(s: str, args: typing.List[Decimal]) -> typing.List[Decimal]:
assert len(stk) >= 1, "Unable to apply operator exp, stack underflow"
# fmt: on
x = stk[-1]
assert isinstance(x, Decimal)
assert isinstance(
x, Decimal
), "Unable to apply operator exp, unexpected type"
stk.pop(len(stk) - 1)
stk.append(Decimal(exp(x)))
continue
Expand All @@ -251,7 +253,9 @@ def evaluate(s: str, args: typing.List[Decimal]) -> typing.List[Decimal]:
assert len(stk) >= 1, "Unable to apply operator floor, stack underflow"
# fmt: on
x = stk[-1]
assert isinstance(x, Decimal)
assert isinstance(
x, Decimal
), "Unable to apply operator floor, unexpected type"
stk.pop(len(stk) - 1)
stk.append(Decimal(floor(x)))
continue
Expand All @@ -260,8 +264,12 @@ def evaluate(s: str, args: typing.List[Decimal]) -> typing.List[Decimal]:
assert len(stk) >= 2, "Unable to apply operator ge, stack underflow"
x = stk[-1]
y = stk[-2]
assert isinstance(x, Decimal)
assert isinstance(y, Decimal)
assert isinstance(
x, Decimal
), "Unable to apply operator ge, unexpected type"
assert isinstance(
y, Decimal
), "Unable to apply operator ge, unexpected type"
stk.pop(len(stk) - 1)
stk.pop(len(stk) - 1)
stk.append(y >= x)
Expand Down
3 changes: 2 additions & 1 deletion borb/io/read/reference/xref_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ def transform(
"""

# update context
assert context is not None
assert context is not None, "context must be defined to read XREF objects"
assert isinstance(object_to_transform, io.BufferedIOBase) or isinstance(
object_to_transform, io.RawIOBase
)

context.root_object = Document()
context.source = object_to_transform
context.tokenizer = HighLevelTokenizer(context.source)
Expand Down
3 changes: 2 additions & 1 deletion borb/io/read/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,8 @@ def __setitem__(self, key, value):
super(Dictionary, self).__setitem__(key, value)

def __deepcopy__(self, memodict={}):
out = Dictionary()
out = type(self).__new__(type(self))
Dictionary.__init__(out)
for k, v in self.items():
out[copy.deepcopy(k, memodict)] = copy.deepcopy(v, memodict)
return out
Expand Down
2 changes: 1 addition & 1 deletion borb/io/write/ascii_art/ascii_logo.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
borb version 2.1.2
borb version 2.1.4
Joris Schellekens
6 changes: 5 additions & 1 deletion borb/io/write/document/catalog_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
)
from borb.io.write.object.dictionary_transformer import DictionaryTransformer
from borb.io.write.transformer import WriteTransformerState
from borb.pdf import Document

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -90,7 +91,10 @@ def transform(

# /OutputIntents
# fmt: off
needs_outputintents: bool = (context is not None and context.conformance_level is not None)

needs_outputintents: bool = (context is not None
and isinstance(context.root_object, Document)
and context.root_object.get_document_info().get_write_conformance_level() is not None)
if needs_outputintents:
self._build_rgb_outputintent_dictionary(object_to_transform)
# fmt: on
Expand Down
7 changes: 5 additions & 2 deletions borb/io/write/document/information_dictionary_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,17 @@ def transform(
and "Trailer" in document["XRef"] \
and "Root" in document["XRef"]["Trailer"] \
and "Metadata" in document["XRef"]["Trailer"]["Root"]
needs_xmp_metadata = has_xmp_metadata or (context is not None and context.conformance_level is not None)
needs_xmp_metadata = has_xmp_metadata or (document.get_document_info().get_write_conformance_level() is not None)
# fmt: on

if needs_xmp_metadata:
conformance_level: ConformanceLevel = (
document.get_document_info().get_write_conformance_level()
)

# write XMP /Metadata
xmp_metadata_stream: Stream = self._write_xmp_metadata_stream(
new_info_dictionary, context.conformance_level
new_info_dictionary, conformance_level
)
assert context is not None
document["XRef"]["Trailer"]["Root"][Name("Metadata")] = self.get_reference(
Expand Down
38 changes: 19 additions & 19 deletions borb/io/write/reference/xref_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,41 +45,41 @@ def transform(
trailer_out = Dictionary()

# /Root
trailer_out[Name("Root")] = self.get_reference(
object_to_transform["Trailer"]["Root"], context
)
# fmt: off
trailer_out[Name("Root")] = self.get_reference(object_to_transform["Trailer"]["Root"], context)
# fmt: on

# /Info
# fmt: off
if "Info" in object_to_transform["Trailer"]:
trailer_out[Name("Info")] = self.get_reference(
object_to_transform["Trailer"]["Info"], context
)
trailer_out[Name("Info")] = self.get_reference(object_to_transform["Trailer"]["Info"], context)
# fmt: on

# /Size
if (
"Trailer" in object_to_transform
and "Size" in object_to_transform["Trailer"]
):
# fmt: off
if ("Trailer" in object_to_transform and "Size" in object_to_transform["Trailer"]):
trailer_out[Name("Size")] = object_to_transform["Trailer"]["Size"]
else:
trailer_out[Name("Size")] = Decimal(
0
) # we'll recalculate this later anyway
trailer_out[Name("Size")] = Decimal(0) # we'll recalculate this later anyway
# fmt: on

# /ID
if "ID" in object_to_transform["Trailer"]:
trailer_out[Name("ID")] = object_to_transform["Trailer"]["ID"]

# write /Info object
# fmt: off
if "Info" in object_to_transform["Trailer"]:
self.get_root_transformer().transform(
object_to_transform["Trailer"]["Info"], context
)
self.get_root_transformer().transform(object_to_transform["Trailer"]["Info"], context)
# fmt: on

# write /Root /StructTreeRoot
# TODO

# write /Root object
self.get_root_transformer().transform(
object_to_transform["Trailer"]["Root"], context
)
# fmt: off
self.get_root_transformer().transform(object_to_transform["Trailer"]["Root"], context)
# fmt: on

# write /XREF
start_of_xref = context.destination.tell()
Expand Down
2 changes: 0 additions & 2 deletions borb/io/write/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ def __init__(
self,
destination: Optional[typing.Union[io.BufferedIOBase, io.RawIOBase]] = None,
root_object: Optional[AnyPDFType] = None,
conformance_level: typing.Optional[ConformanceLevel] = None,
):
# fmt: off
self.destination = destination # this is the destination to write to (file, byte-buffer, etc)
Expand All @@ -36,7 +35,6 @@ def __init__(
self.indirect_objects_by_hash: typing.Dict[int, typing.List[AnyPDFType]] = {} # these are the indirect objects (by hash)
self.resolved_references: typing.List[Reference] = [] # these references have already been written
self.compression_level: int = 9 # default compression level
self.conformance_level: typing.Optional[ConformanceLevel] = conformance_level # default conformance level
self.apply_font_subsetting: bool = False # whether to apply Font subsetting or not
# fmt: on

Expand Down
2 changes: 2 additions & 0 deletions borb/pdf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
# Shape
from .canvas.layout.shape.connected_shape import ConnectedShape
from .canvas.layout.shape.disconnected_shape import DisconnectedShape
from .canvas.layout.smart_art.smart_art import SmartArt

# Table
from .canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable
Expand All @@ -105,6 +106,7 @@
from .canvas.layout.text.heterogeneous_paragraph import HeterogeneousParagraph
from .canvas.layout.text.heading import Heading
from .canvas.layout.text.chunk_of_text import ChunkOfText
from .canvas.lipsum.lipsum import Lipsum

# Document, Page, PDF
from .document.document import Document
Expand Down
2 changes: 1 addition & 1 deletion borb/pdf/canvas/layout/horizontal_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ def _paint_content_box(self, page: Page, available_space: Rectangle) -> None:
)

# modify content stream
page._append_to_content_stream(content)
page.append_to_content_stream(content)
2 changes: 1 addition & 1 deletion borb/pdf/canvas/layout/image/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@ def _paint_content_box(self, page: Page, bounding_box: Rectangle):
)

# write content
page._append_to_content_stream(content)
page.append_to_content_stream(content)
25 changes: 22 additions & 3 deletions borb/pdf/canvas/layout/layout_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,22 @@ def __init__(
# linkage (for lists, tables, etc)
self._parent = parent

def _needs_to_be_tagged(self, p: "Page") -> bool:
"""
This function returns whether this LayoutElement needs to be tagged
:param p: the Page on which this LayoutElement is to be painted
:return: true if this LayoutElement needs to be tagged, False otherwise
"""
document: typing.Optional["Document"] = p.get_document()
if document is None:
return False
conformance_level: typing.Optional[
"ConformanceLevel"
] = document.get_document_info().get_write_conformance_level()
if conformance_level is None:
return False
return conformance_level.get_conformance_level() in ["A", "U"]

def get_font_size(self) -> Decimal:
"""
This function returns the font size of this LayoutElement
Expand Down Expand Up @@ -267,12 +283,15 @@ def paint(self, page: "Page", available_space: Rectangle) -> None: # type: igno
:param available_space: the available space (as a Rectangle) on which to paint this LayoutElement
:return: None
"""

# calculate horizontal_border_width
horizontal_border_width: Decimal = Decimal(0)
if self._border_left:
horizontal_border_width += self._border_width
if self._border_right:
horizontal_border_width += self._border_width

# calculate vertical_border_width
vertical_border_width: Decimal = Decimal(0)
if self._border_top:
vertical_border_width += self._border_width
Expand Down Expand Up @@ -523,7 +542,7 @@ def _paint_background(
background_box.get_y() + background_box.get_height(), # ul_y
)
# fmt: on
page._append_to_content_stream(content)
page.append_to_content_stream(content)
return

# remember border state
Expand Down Expand Up @@ -564,7 +583,7 @@ def _paint_background(
assert p is not None
content += " %f %f l" % (float(p[0]), float(p[1]))
content += " f Q"
page._append_to_content_stream(content)
page.append_to_content_stream(content)

def _paint_borders(self, page: "Page", border_box: Rectangle): # type: ignore[name-defined]
# border is not wanted on any side
Expand Down Expand Up @@ -604,4 +623,4 @@ def _paint_borders(self, page: "Page", border_box: Rectangle): # type: ignore[n
float(p1[1]),
)
content += " Q"
page._append_to_content_stream(content)
page.append_to_content_stream(content)
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import typing
from decimal import Decimal

from borb.pdf import ChunkOfText
from borb.pdf.canvas.geometry.rectangle import Rectangle
from borb.pdf.canvas.layout.page_layout.multi_column_layout import MultiColumnLayout
from borb.pdf.page.page import Page
Expand All @@ -24,20 +25,18 @@ class HeaderFooterMultiColumnLayout(MultiColumnLayout):
"""

def __init__(
# fmt: off
self,
page: Page,
number_of_columns: int = 2,
horizontal_margin: typing.Optional[Decimal] = None,
vertical_margin: typing.Optional[Decimal] = None,
header_callable: typing.Optional[
typing.Callable[[Page, Rectangle], None]
] = None,
header_callable: typing.Optional[typing.Callable[[Page, Rectangle], None]] = None,
header_height: Decimal = Decimal(12 * 3 * 1.2),
footer_height: Decimal = Decimal(12 * 3 * 1.2),
footer_callable: typing.Optional[
typing.Callable[[Page, Rectangle], None]
] = None,
footer_callable: typing.Optional[typing.Callable[[Page, Rectangle], None]] = None,
inter_column_margin: typing.Optional[Decimal] = None,
# fmt: on
):
super(HeaderFooterMultiColumnLayout, self).__init__(
page,
Expand All @@ -58,12 +57,6 @@ def __init__(
if self._footer_callable is None:
self._footer_height = Decimal(0)

# size of Page is updated to ensure the layout algorithm does not attempt
# to fill the Page entirely
assert self._page_height is not None
self._page_height -= self._header_height
self._page_height -= self._footer_height

# modify margins
self._vertical_margin_bottom += self._footer_height
self._vertical_margin_top += self._header_height
Expand All @@ -81,7 +74,7 @@ def _add_header_footer_to_current_page(self) -> None:
self.get_page(),
Rectangle(
self._horizontal_margin,
self._page_height - self._vertical_margin_top,
self._page_height - self._vertical_margin_top - self._header_height,
self._page_width - self._horizontal_margin * Decimal(2),
self._header_height,
),
Expand All @@ -100,6 +93,18 @@ def _add_header_footer_to_current_page(self) -> None:
),
)

# previous LayoutElement
self._previous_element = ChunkOfText("")
self._previous_element._previous_paint_box = Rectangle(
self._horizontal_margin,
self._page_height - self._vertical_margin_top - self._header_height,
self._page_width - self._horizontal_margin * Decimal(2),
self._header_height,
)
self._previous_element._previous_layout_box = (
self._previous_element._previous_paint_box
)

def switch_to_next_page(self) -> "PageLayout": # type: ignore[name-defined]
"""
This function forces this PageLayout to switch to the nex Page
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import typing
from decimal import Decimal

from borb.pdf import SingleColumnLayout, Page
from borb.pdf import SingleColumnLayout
from borb.pdf.canvas.geometry.rectangle import Rectangle
from borb.pdf.canvas.layout.layout_element import LayoutElement

Expand All @@ -24,7 +24,7 @@ class SingleColumnLayoutWithOverflow(SingleColumnLayout):

def __init__(
self,
page: Page,
page: "Page",
horizontal_margin: typing.Optional[Decimal] = None,
vertical_margin: typing.Optional[Decimal] = None,
):
Expand Down
2 changes: 1 addition & 1 deletion borb/pdf/canvas/layout/shape/connected_shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,4 +215,4 @@ def _paint_content_box(self, page: Page, available_space: Rectangle) -> None:
content += " Q"

# append to page
page._append_to_content_stream(content)
page.append_to_content_stream(content)
2 changes: 1 addition & 1 deletion borb/pdf/canvas/layout/shape/disconnected_shape.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,4 @@ def _paint_content_box(self, page: Page, available_space: Rectangle) -> None:
content += " S Q"

# append to page
page._append_to_content_stream(content)
page.append_to_content_stream(content)
Loading

0 comments on commit 9f456ce

Please sign in to comment.