// Copyright 2017-2022 The MathJax Consortium // SPDX-License-Identifier: Apache-2.0 // Sources: BaseMethods.HLine and BaseItems.ArrayItem.checkLines/createMml.
package tex import ( ) const arrayRulesProperty = "arrayRules" // Each real ArrayItem owns its rules. Reading the owner's completed-row count // also observes direct EndRow calls, such as ArrowBetweenLines, without // confusing them with an Entry or an ordinary no-item command. type arrayRules struct { rows func() int frame []string lines []string dashed bool } func newArrayRules( *mml.Node) *arrayRules { := &arrayRules{rows: func() int { return len(.Children) }} .SetProperty(arrayRulesProperty, ) return } func isHLine( string) bool { return == "hline" || == "hdashline" } func misplacedHLine( string) error { return texError("Misplaced", "Misplaced %s", "\\"+) } func ( *arrayRules) ( string) { := .rows() if == 0 { .frame = append(.frame, "top") return } for len(.lines) < { .lines = append(.lines, "none") } := "solid" if == "hdashline" { = "dashed" } .lines[-1] = } func tableArrayRules( *mml.Node) *arrayRules { if , := .Property(arrayRulesProperty); { if , := .(*arrayRules); { return } } return newArrayRules() } // Call after the owner has finished its entries/rows and applied its arraydef, // but before adding the owner's delimiters or delivering its final MML item. func finishArrayRules( *mml.Node) *mml.Node { , := .Property(arrayRulesProperty) if ! { return } := .(*arrayRules) .RemoveProperty(arrayRulesProperty) if len(.lines) != 0 { if len(.lines) == len(.Children) { .frame = append(.frame, "bottom") .lines = .lines[:len(.lines)-1] } else if len(.lines) < len(.Children)-1 { .lines = append(.lines, "none") } .Attributes.Set("rowlines", strings.Join(.lines, " ")) } if len(.frame) == 4 { := "solid" if .dashed { = "dashed" } .Attributes.Set("frame", ) return } if len(.frame) == 0 { return } // The original constructs mtable before trimming the arraydef's trailing // repeated none entries. The trimmed spelling controls partial-frame padding; // it does not rewrite the already-created table's rowlines attribute. := append([]string(nil), .lines...) for len() > 1 && [len()-1] == "none" && [len()-2] == "none" { = [:len()-1] } , := .Attributes.Get("columnlines") , := sourceValueString(), strings.Join(, " ") .Attributes.Set("frame", "") := setAttributes(node("menclose", ), map[string]any{"notation": strings.Join(.frame, " ")}) if ( != "" && != "none") || ( != "" && != "none") { .Attributes.Set("data-padding", 0) } return }