Imports #
"bytes"
"container/list"
"fmt"
"sort"
"fmt"
"log"
"unicode/utf8"
"bytes"
"container/list"
"fmt"
"sort"
"fmt"
"log"
"unicode/utf8"
const ALconst ANconst Bconst BNconst CSconst Controlconst ENconst ESconst ETconst FSIconst L Class = iotaconst LREconst LRIconst LROLeftToRight indicates the text contains no right-to-left characters and that either there are some left-to-right characters or the option DefaultDirection(LeftToRight) was passed.
const LeftToRight Direction = iotaMixed indicates text contains both left-to-right and right-to-left characters.
const Mixedconst NSMNeutral means that text contains no left-to-right and right-to-left characters and that no default direction has been set.
const Neutralconst ONconst PDFconst PDIconst Rconst RLEconst RLIconst RLORightToLeft indicates the text contains no left-to-right characters and that either there are some right-to-left characters or the option DefaultDirection(RightToLeft) was passed.
const RightToLeftconst SUnicodeVersion is the Unicode version from which the tables in this package are derived.
const UnicodeVersion = "12.0.0"UnicodeVersion is the Unicode version from which the tables in this package are derived.
const UnicodeVersion = "11.0.0"UnicodeVersion is the Unicode version from which the tables in this package are derived.
const UnicodeVersion = "15.0.0"UnicodeVersion is the Unicode version from which the tables in this package are derived.
const UnicodeVersion = "13.0.0"UnicodeVersion is the Unicode version from which the tables in this package are derived.
const UnicodeVersion = "10.0.0"UnicodeVersion is the Unicode version from which the tables in this package are derived.
const UnicodeVersion = "9.0.0"const WSbidiIndex: 24 blocks, 1536 entries, 1536 bytes Block 0 is the zero block.
var bidiIndex = [1536]uint8{...}bidiIndex: 24 blocks, 1536 entries, 1536 bytes Block 0 is the zero block.
var bidiIndex = [1536]uint8{...}bidiIndex: 24 blocks, 1536 entries, 1536 bytes Block 0 is the zero block.
var bidiIndex = [1536]uint8{...}bidiIndex: 24 blocks, 1536 entries, 1536 bytes Block 0 is the zero block.
var bidiIndex = [1536]uint8{...}bidiIndex: 26 blocks, 1664 entries, 3328 bytes Block 0 is the zero block.
var bidiIndex = [1664]uint16{...}bidiIndex: 24 blocks, 1536 entries, 1536 bytes Block 0 is the zero block.
var bidiIndex = [1536]uint8{...}bidiValues: 259 blocks, 16576 entries, 16576 bytes The third block is the zero block.
var bidiValues = [16576]uint8{...}bidiValues: 240 blocks, 15360 entries, 15360 bytes The third block is the zero block.
var bidiValues = [15360]uint8{...}bidiValues: 234 blocks, 14976 entries, 14976 bytes The third block is the zero block.
var bidiValues = [14976]uint8{...}bidiValues: 228 blocks, 14592 entries, 14592 bytes The third block is the zero block.
var bidiValues = [14592]uint8{...}bidiValues: 248 blocks, 15872 entries, 15872 bytes The third block is the zero block.
var bidiValues = [15872]uint8{...}bidiValues: 222 blocks, 14208 entries, 14208 bytes The third block is the zero block.
var bidiValues = [14208]uint8{...}const bpCloseconst bpNone bracketType = iotaconst bpOpenvar controlByteToClass = [16]Class{...}const implicitLevel level = *ast.UnaryExprconst maxDepth = 125const maxPairingDepth = 63const numClassconst openMask = 0x10var trie = *ast.CallExprconst unknownClass = *ast.UnaryExprconst xorMaskShift = 5xorMasks contains masks to be xor-ed with brackets to get the reverse version.
var xorMasks = []int32{...}xorMasks contains masks to be xor-ed with brackets to get the reverse version.
var xorMasks = []int32{...}xorMasks contains masks to be xor-ed with brackets to get the reverse version.
var xorMasks = []int32{...}xorMasks contains masks to be xor-ed with brackets to get the reverse version.
var xorMasks = []int32{...}xorMasks contains masks to be xor-ed with brackets to get the reverse version.
var xorMasks = []int32{...}xorMasks contains masks to be xor-ed with brackets to get the reverse version.
var xorMasks = []int32{...}Class is the Unicode BiDi class. Each rune has a single class.
type Class uintA Direction indicates the overall flow of text.
type Direction intAn Option is an option for Bidi processing.
type Option func(*options)bracketPairs is a slice of bracketPairs with a sort.Interface implementation.
type bracketPairs []bracketPairBidi_Paired_Bracket_Type BD14. An opening paired bracket is a character whose Bidi_Paired_Bracket_Type property value is Open. BD15. A closing paired bracket is a character whose Bidi_Paired_Bracket_Type property value is Close.
type bracketType bytelevel is the embedding level of a character. Even embedding levels indicate left-to-right order and odd levels indicate right-to-left order. The special level of -1 is reserved for undefined order.
type level int8An Ordering holds the computed visual order of runs of a Paragraph. Calling SetBytes or SetString on the originating Paragraph invalidates an Ordering. The methods of an Ordering should only be called by one goroutine at a time.
type Ordering struct {
runes [][]rune
directions []Direction
startpos []int
}A Paragraph holds a single Paragraph for Bidi processing.
type Paragraph struct {
p []byte
o Ordering
opts []Option
types []Class
pairTypes []bracketType
pairValues []rune
runes []rune
options options
}Properties provides access to BiDi properties of runes.
type Properties struct {
entry uint8
last uint8
}A Run is a continuous sequence of characters of a single direction.
type Run struct {
runes []rune
direction Direction
startpos int
}bidiTrie. Total size: 19904 bytes (19.44 KiB). Checksum: b1f201ed2debb6c8.
type bidiTrie struct {
}bidiTrie. Total size: 16128 bytes (15.75 KiB). Checksum: 8122d83e461996f.
type bidiTrie struct {
}bidiTrie. Total size: 16512 bytes (16.12 KiB). Checksum: 2a9cf1317f2ffaa.
type bidiTrie struct {
}bidiTrie. Total size: 17408 bytes (17.00 KiB). Checksum: df85fcbfe9b8377f.
type bidiTrie struct {
}bidiTrie. Total size: 16896 bytes (16.50 KiB). Checksum: 6f0927067913dc6d.
type bidiTrie struct {
}bidiTrie. Total size: 15744 bytes (15.38 KiB). Checksum: b4c3b70954803b86.
type bidiTrie struct {
}bracketPair holds a pair of index values for opening and closing bracket location of a bracket pair.
type bracketPair struct {
opener int
closer int
}type bracketPairer struct {
sos Class
openers *list.List
pairPositions bracketPairs
codesIsolatedRun []Class
indexes []int
}This stack will store the embedding levels and override and isolated statuses
type directionalStatusStack struct {
stackCounter int
embeddingLevelStack [*ast.BinaryExpr]level
overrideStatusStack [*ast.BinaryExpr]Class
isolateStatusStack [*ast.BinaryExpr]bool
}type isolatingRunSequence struct {
p *paragraph
indexes []int
types []Class
resolvedLevels []level
level level
sos Class
eos Class
}type options struct {
defaultDirection Direction
}A paragraph contains the state of a paragraph.
type paragraph struct {
initialTypes []Class
pairTypes []bracketType
pairValues []rune
embeddingLevel level
resultTypes []Class
resultLevels []level
matchingPDI []int
matchingIsolateInitiator []int
}AppendReverse reverses the order of characters of in, appends them to out, and returns the result. Modifiers will still follow the runes they modify. Brackets are replaced with their counterparts.
func AppendReverse(out []byte, in []byte) []byteBytes returns the text of the run in its original order.
func (r *Run) Bytes() []byteClass returns the Bidi class for p.
func (p Properties) Class() ClassDefaultDirection sets the default direction for a Paragraph. The direction is overridden if the text contains directional characters.
func DefaultDirection(d Direction) OptionDirection reports the direction of the run.
func (r *Run) Direction() DirectionDirection reports the directionality of the runs. The direction may be LeftToRight, RightToLeft, Mixed, or Neutral.
func (o *Ordering) Direction() DirectionDirection returns the direction of the text of this paragraph. The direction may be LeftToRight, RightToLeft, Mixed, or Neutral.
func (p *Paragraph) Direction() DirectionIsBracket reports whether the rune is a bracket.
func (p Properties) IsBracket() boolIsLeftToRight reports whether the principle direction of rendering for this paragraphs is left-to-right. If this returns false, the principle direction of rendering is right-to-left.
func (p *Paragraph) IsLeftToRight() boolIsOpeningBracket reports whether the rune is an opening bracket. IsBracket must return true.
func (p Properties) IsOpeningBracket() boolfunc (i *isolatingRunSequence) Len() intfunc (p *paragraph) Len() intfunc (b bracketPairs) Len() intfunc (b bracketPairs) Less(i int, j int) boolLine computes the visual ordering of runs for a single line starting and ending at the given positions in the original text.
func (p *Paragraph) Line(start int, end int) (Ordering, error)Lookup returns properties for the first rune in s and the width in bytes of its encoding. The size will be 0 if s does not hold enough bytes to complete the encoding.
func Lookup(s []byte) (p Properties, sz int)LookupRune returns properties for r.
func LookupRune(r rune) (p Properties, size int)LookupString returns properties for the first rune in s and the width in bytes of its encoding. The size will be 0 if s does not hold enough bytes to complete the encoding.
func LookupString(s string) (p Properties, sz int)NumRuns returns the number of runs.
func (o *Ordering) NumRuns() intOrder computes the visual ordering of all the runs in a Paragraph.
func (p *Paragraph) Order() (Ordering, error)Pos returns the position of the Run within the text passed to SetBytes or SetString of the originating Paragraph value.
func (r *Run) Pos() (start int, end int)ReverseString reverses the order of characters in s and returns a new string. Modifiers will still follow the runes they modify. Brackets are replaced with their counterparts.
func ReverseString(s string) stringRun returns the ith run within the ordering.
func (o *Ordering) Run(i int) RunRunAt reports the Run at the given position of the input text. This method can be used for computing line breaks on paragraphs.
func (p *Paragraph) RunAt(pos int) RunSetBytes configures p for the given paragraph text. It replaces text previously set by SetBytes or SetString. If b contains a paragraph separator it will only process the first paragraph and report the number of bytes consumed from b including this separator. Error may be non-nil if options are given.
func (p *Paragraph) SetBytes(b []byte, opts ...Option) (n int, err error)SetString configures s for the given paragraph text. It replaces text previously set by SetBytes or SetString. If s contains a paragraph separator it will only process the first paragraph and report the number of bytes consumed from s including this separator. Error may be non-nil if options are given.
func (p *Paragraph) SetString(s string, opts ...Option) (n int, err error)func (b *bracketPair) String() stringString returns the text of the run in its original order.
func (r *Run) String() stringfunc (b bracketPairs) Swap(i int, j int)Applies the levels and types resolved in rules W1-I2 to the resultLevels array.
func (s *isolatingRunSequence) applyLevelsAndTypes()Algorithm validation. Assert that all values in types are in the provided set.
func (s *isolatingRunSequence) assertOnly(codes ...Class)assignBracketType implements rule N0 for a single bracket pair.
func (p *bracketPairer) assignBracketType(loc bracketPair, dirEmbed Class, initialTypes []Class)Assign level information to characters removed by rule X9. This is for ease of relating the level information to the original input data. Note that the levels assigned to these codes are arbitrary, they're chosen so as to avoid breaking level runs.
func (p *paragraph) assignLevelsToCharactersRemovedByX9()func calculateOrdering(levels []level, runes []rune) OrderingclassBeforePair determines which strong types are present before a Bracket Pair. Return R or L if strong type found, otherwise ON.
func (p *bracketPairer) classBeforePair(loc bracketPair) ClassclassifyPairContent reports the strong types contained inside a Bracket Pair, assuming the given embedding direction. It returns ON if no strong type is found. If a single strong type is found, it returns this type. Otherwise it returns the embedding direction. TODO: use separate type for "strong" directionality.
func (p *bracketPairer) classifyPairContent(loc bracketPair, dirEmbed Class) ClassReturn multiline reordering array for a given level array. Reordering does not occur across a line break.
func computeMultilineReordering(levels []level, linebreaks []int) []intReturn reordering array for a given level array. This reorders a single line. The reordering is a visual to logical map. For example, the leftmost char is string.charAt(order[0]). Rule L2.
func computeReordering(levels []level) []intfunc (s *directionalStatusStack) depth() intDetermine explicit levels using rules X1 - X8
func (p *paragraph) determineExplicitEmbeddingLevels()Definition BD13. Determine isolating run sequences.
func (p *paragraph) determineIsolatingRunSequences() []*isolatingRunSequencedetermineLevelRuns returns an array of level runs. Each level run is described as an array of indexes into the input string. Determines the level runs. Rule X9 will be applied in determining the runs, in the way that makes sure the characters that are supposed to be removed are not included in the runs.
func (p *paragraph) determineLevelRuns() [][]intdetermineMatchingIsolates determines the matching PDI for each isolate initiator and vice versa. Definition BD9. At the end of this function: - The member variable matchingPDI is set to point to the index of the matching PDI character for each isolate initiator character. If there is no matching PDI, it is set to the length of the input text. For other characters, it is set to -1. - The member variable matchingIsolateInitiator is set to point to the index of the matching isolate initiator character for each PDI character. If there is no matching isolate initiator, or the character is not a PDI, it is set to -1.
func (p *paragraph) determineMatchingIsolates()determineParagraphEmbeddingLevel reports the resolved paragraph direction of the substring limited by the given range [start, end). Determines the paragraph level based on rules P2, P3. This is also used in rule X5c to find if an FSI should resolve to LRI or RLI.
func (p *paragraph) determineParagraphEmbeddingLevel(start int, end int) levelfunc (s *directionalStatusStack) empty()Return the limit of the run consisting only of the types in validSet starting at index. This checks the value at index, and will return index if that value is not in validSet.
func (s *isolatingRunSequence) findRunLimit(index int, validSet ...Class) intgetLevels computes levels array breaking lines at offsets in linebreaks. Rule L1. The linebreaks array must include at least one value. The values must be in strictly increasing order (no duplicates) between 1 and the length of the text, inclusive. The last value must be the length of the text.
func (p *paragraph) getLevels(linebreaks []int) []levelgetReordering returns the reordering of lines from a visual index to a logical index for line breaks at the given offsets. Lines are concatenated from left to right. So for example, the fifth character from the left on the third line is getReordering(linebreaks)[linebreaks[1] + 4] (linebreaks[1] is the position after the last character of the second line, which is also the index of the first character on the third line, and adding four gets the fifth character from the left). The linebreaks array must include at least one value. The values must be in strictly increasing order (no duplicates) between 1 and the length of the text, inclusive. The last value must be the length of the text.
func (p *paragraph) getReordering(linebreaks []int) []intgetStrongTypeN0 maps character's directional code to strong type as required by rule N0. TODO: have separate type for "strong" directionality.
func (p *bracketPairer) getStrongTypeN0(index int) Classin returns if x is equal to any of the values in set.
func (c Class) in(set ...Class) boolisRemovedByX9 reports whether the type is one of the types removed in X9.
func isRemovedByX9(c Class) boolisWhitespace reports whether the type is considered a whitespace type for the line break rules.
func isWhitespace(c Class) boolRule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types, either L or R, for each isolating run sequence.
func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequencefunc (s *directionalStatusStack) lastDirectionalIsolateStatus() boolfunc (s *directionalStatusStack) lastDirectionalOverrideStatus() Classfunc (s *directionalStatusStack) lastEmbeddingLevel() levellocateBrackets locates matching bracket pairs according to BD16. This implementation uses a linked list instead of a stack, because, while elements are added at the front (like a push) they are not generally removed in atomic 'pop' operations, reducing the benefit of the stack archetype.
func (p *bracketPairer) locateBrackets(pairTypes []bracketType, pairValues []rune)lookup returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookup(s []byte) (v uint8, sz int)lookup returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookup(s []byte) (v uint8, sz int)lookup returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookup(s []byte) (v uint8, sz int)lookup returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookup(s []byte) (v uint8, sz int)lookup returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookup(s []byte) (v uint8, sz int)lookup returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookup(s []byte) (v uint8, sz int)lookupString returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookupString(s string) (v uint8, sz int)lookupString returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookupString(s string) (v uint8, sz int)lookupString returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookupString(s string) (v uint8, sz int)lookupString returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookupString(s string) (v uint8, sz int)lookupString returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookupString(s string) (v uint8, sz int)lookupString returns the trie value for the first UTF-8 encoding in s and the width in bytes of this encoding. The size will be 0 if s does not hold enough bytes to complete the encoding. len(s) must be greater than 0.
func (t *bidiTrie) lookupString(s string) (v uint8, sz int)lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupStringUnsafe(s string) uint8lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupStringUnsafe(s string) uint8lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupStringUnsafe(s string) uint8lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupStringUnsafe(s string) uint8lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupStringUnsafe(s string) uint8lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupStringUnsafe(s string) uint8lookupUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupUnsafe(s []byte) uint8lookupUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupUnsafe(s []byte) uint8lookupUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupUnsafe(s []byte) uint8lookupUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupUnsafe(s []byte) uint8lookupUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupUnsafe(s []byte) uint8lookupUnsafe returns the trie value for the first UTF-8 encoding in s. s must start with a full and valid UTF-8 encoded rune.
func (t *bidiTrie) lookupUnsafe(s []byte) uint8lookupValue determines the type of block n and looks up the value for b.
func (t *bidiTrie) lookupValue(n uint32, b byte) uint8lookupValue determines the type of block n and looks up the value for b.
func (t *bidiTrie) lookupValue(n uint32, b byte) uint8lookupValue determines the type of block n and looks up the value for b.
func (t *bidiTrie) lookupValue(n uint32, b byte) uint8lookupValue determines the type of block n and looks up the value for b.
func (t *bidiTrie) lookupValue(n uint32, b byte) uint8lookupValue determines the type of block n and looks up the value for b.
func (t *bidiTrie) lookupValue(n uint32, b byte) uint8lookupValue determines the type of block n and looks up the value for b.
func (t *bidiTrie) lookupValue(n uint32, b byte) uint8matchOpener reports whether characters at given positions form a matching bracket pair.
func (p *bracketPairer) matchOpener(pairValues []rune, opener int, closer int) boolfunc maxLevel(a level, b level) levelfunc newBidiTrie(i int) *bidiTriefunc newBidiTrie(i int) *bidiTriefunc newBidiTrie(i int) *bidiTriefunc newBidiTrie(i int) *bidiTriefunc newBidiTrie(i int) *bidiTriefunc newBidiTrie(i int) *bidiTrienewParagraph initializes a paragraph. The user needs to supply a few arrays corresponding to the preprocessed text input. The types correspond to the Unicode BiDi classes for each rune. pairTypes indicates the bracket type for each rune. pairValues provides a unique bracket class identifier for each rune (suggested is the rune of the open bracket for opening and matching close brackets, after normalization). The embedding levels are optional, but may be supplied to encode embedding levels of styled text.
func newParagraph(types []Class, pairTypes []bracketType, pairValues []rune, levels level) (*paragraph, error)func (s *directionalStatusStack) pop()Initialize the p.pairTypes, p.pairValues and p.types from the input previously set by p.SetBytes() or p.SetString(). Also limit the input up to (and including) a paragraph separator (bidi class B). The function p.Order() needs these values to be set, so this preparation could be postponed. But since the SetBytes and SetStrings functions return the length of the input up to the paragraph separator, the whole input needs to be processed anyway and should not be done twice. The function has the same return values as SetBytes() / SetString()
func (p *Paragraph) prepareInput() (n int, err error)func (s *directionalStatusStack) push(level level, overrideStatus Class, isolateStatus bool)resolveBrackets implements rule N0 for a list of pairs.
func (p *bracketPairer) resolveBrackets(dirEmbed Class, initialTypes []Class)7) resolving implicit embedding levels Rules I1, I2.
func (s *isolatingRunSequence) resolveImplicitLevels()6) resolving neutral types Rules N1-N2.
func (s *isolatingRunSequence) resolveNeutralTypes()resolvePairedBrackets runs the paired bracket part of the UBA algorithm. For each rune, it takes the indexes into the original string, the class the bracket type (in pairTypes) and the bracket identifier (pairValues). It also takes the direction type for the start-of-sentence and the embedding level. The identifiers for bracket types are the rune of the canonicalized opening bracket for brackets (open or close) or 0 for runes that are not brackets.
func resolvePairedBrackets(s *isolatingRunSequence)Resolving weak types Rules W1-W7. Note that some weak types (EN, AN) remain after this processing is complete.
func (s *isolatingRunSequence) resolveWeakTypes()TODO: find a better API and expose.
func (p Properties) reverseBracket(r rune) runeThe algorithm. Does not include line-based processing (Rules L1, L2). These are applied later in the line-based phase of the algorithm.
func (p *paragraph) run()func (p *bracketPairer) setBracketsToType(loc bracketPair, dirPair Class, initialTypes []Class)func setLevels(levels []level, newLevel level)func setTypes(types []Class, newType Class)typeForLevel reports the strong type (L or R) corresponding to the level.
func typeForLevel(level level) Classfunc validateLineBreaks(linebreaks []int, textLength int) errorfunc validateParagraphEmbeddingLevel(embeddingLevel level) errorfunc validatePbTypes(pairTypes []bracketType) errorfunc validatePbValues(pairValues []rune, pairTypes []bracketType) errorfunc validateTypes(types []Class) errorGenerated with Arrow