Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #4
This PR is a hot mess ๐ฅโ๐ถ๐ฅ However it may also be "good enough" to use.
As per #4, the core problem is that, currently the
prawn-rtl-support
gem first Bidi-reorders RTL text, then Prawn computes line wrapping. This causes the lines to be effectively reversed, i.e. bottom-to-top ordering.This PR "fixes" this as follows:
Prawn::Text::Formatted::Box
now only performs Arabic connecting. This is a text "preprocessing" step; we can't do reordering here.Prawn::Text::Formatted::Arranger
is the class that handles "arranging" within each line. This is where this PR implements the reordering; the assumption is that splitting text into lines first, then reordering each line with Bidi, always yields the correct result. This has two sub-steps:Prawn::Rtl::Connector.reorder_fragments
. This is a magic method that "tags" each fragment with marker chars on either side, runs them through Bidi reorder, and then recomposes the text with an index number of style. For example, given fragments["foo ", "bar ", "baz"]
(supposing foo, etc. are RTL chars) this will yield[[2, "zab"], [1, " rab"], [0, " oof"]]
.Prawn::Text::Formatted::Fragment
is now (un-)patched to no longer do a naive character reverse ifdirection == :rtl
Alternative approaches:
Prawn::Text::Formatted::Box#form_fragments_from_like_font_glyph_pairs
, I'm not sure.fragments
, which would eliminate the need for the marker mess. That way we could apply the Bidi algorithm to the text within a style group before it is fragmented. Need to study more about how Bidi does line breaking.Limitations:
Prawn::Rtl::Connector.reorder_fragments
struggles with whitespace and punctuation, for example"foo: bar"
we might expect to become"rab :oof"
but it becomes"rab: oof"
instead. This could possibly be hacked.Prawn::Rtl::Connector.reorder_fragments
uses magic chars in the Unicode Private User Area. This will break FontAwesome and other icon fonts using chars in this area, if they are combined on the same line as RTL chars.ู ุฑุญุจูุง
becomesู ุฑุญุจููุง
.Misc changes (for performance):
#include_rtl?
now uses direct regex on strings rather than doingTwitterCldr::Shared::Bidi
object allocations.