type level … const implicitLevel … // in returns if x is equal to any of the values in set. func (c Class) in(set ...Class) bool { … } type paragraph … // newParagraph 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 (p *paragraph) Len() int { … } // The 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() { … } // determineMatchingIsolates 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, end int) level { … } const maxDepth … type directionalStatusStack … func (s *directionalStatusStack) empty() { … } func (s *directionalStatusStack) pop() { … } func (s *directionalStatusStack) depth() int { … } func (s *directionalStatusStack) push(level level, overrideStatus Class, isolateStatus bool) { … } func (s *directionalStatusStack) lastEmbeddingLevel() level { … } func (s *directionalStatusStack) lastDirectionalOverrideStatus() Class { … } func (s *directionalStatusStack) lastDirectionalIsolateStatus() bool { … } // Determine explicit levels using rules X1 - X8 func (p *paragraph) determineExplicitEmbeddingLevels() { … } type isolatingRunSequence … func (i *isolatingRunSequence) Len() int { … } func maxLevel(a, b level) level { … } // Rule 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) *isolatingRunSequence { … } // Resolving weak types Rules W1-W7. // // Note that some weak types (EN, AN) remain after this processing is // complete. func (s *isolatingRunSequence) resolveWeakTypes() { … } // 6) resolving neutral types Rules N1-N2. func (s *isolatingRunSequence) resolveNeutralTypes() { … } func setLevels(levels []level, newLevel level) { … } func setTypes(types []Class, newType Class) { … } // 7) resolving implicit embedding levels Rules I1, I2. func (s *isolatingRunSequence) resolveImplicitLevels() { … } // Applies the levels and types resolved in rules W1-I2 to the // resultLevels array. func (s *isolatingRunSequence) applyLevelsAndTypes() { … } // 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) int { … } // Algorithm validation. Assert that all values in types are in the // provided set. func (s *isolatingRunSequence) assertOnly(codes ...Class) { … } // determineLevelRuns 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() [][]int { … } // Definition BD13. Determine isolating run sequences. func (p *paragraph) determineIsolatingRunSequences() []*isolatingRunSequence { … } // 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() { … } // getLevels 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) []level { … } // getReordering 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) []int { … } // Return multiline reordering array for a given level array. Reordering // does not occur across a line break. func computeMultilineReordering(levels []level, linebreaks []int) []int { … } // Return 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) []int { … } // isWhitespace reports whether the type is considered a whitespace type for the // line break rules. func isWhitespace(c Class) bool { … } // isRemovedByX9 reports whether the type is one of the types removed in X9. func isRemovedByX9(c Class) bool { … } // typeForLevel reports the strong type (L or R) corresponding to the level. func typeForLevel(level level) Class { … } func validateTypes(types []Class) error { … } func validateParagraphEmbeddingLevel(embeddingLevel level) error { … } func validateLineBreaks(linebreaks []int, textLength int) error { … } func validatePbTypes(pairTypes []bracketType) error { … } func validatePbValues(pairValues []rune, pairTypes []bracketType) error { … }