import OrgSwift import SwiftUI /// A table, in a `Grid` that scrolls sideways when it is wider than the screen. /// /// Column alignment comes from org's `|---+:---:+---|` separator row. `Grid` takes it from /// one cell per column, so it is set on the first row and inherited down. struct OrgTableView: View { let table: OrgTableLayout @Environment(\.orgMath) private var math var body: some View { ScrollView(.horizontal, showsIndicators: false) { Grid(alignment: .topLeading, horizontalSpacing: 14, verticalSpacing: 7) { ForEach(Array(table.rows.enumerated()), id: \.element.id) { index, row in GridRow { ForEach(0 ..< table.columnCount, id: \.self) { column in cell(row, column: column, isHeader: index < table.headerRowCount) } } // The rule row separating the header band from the body. if index + 1 == table.headerRowCount { Divider().gridCellColumns(table.columnCount) } } } .padding(.vertical, 2) } } @ViewBuilder private func cell(_ row: OrgTableLayout.Row, column: Int, isHeader: Bool) -> some View { // Org tolerates ragged rows; a missing cell is empty, not a crash. let text = column < row.cells.count ? row.cells[column].text : AttributedString() orgText(text, math: math) .fontWeight(isHeader ? .semibold : .regular) .multilineTextAlignment(Self.textAlignment(table.alignment(column: column))) .fixedSize(horizontal: false, vertical: true) .gridColumnAlignment(Self.gridAlignment(table.alignment(column: column))) } private static func gridAlignment(_ alignment: OrgAlignment?) -> HorizontalAlignment { switch alignment { case .center: .center case .right: .trailing case .left, nil: .leading } } private static func textAlignment(_ alignment: OrgAlignment?) -> TextAlignment { switch alignment { case .center: .center case .right: .trailing case .left, nil: .leading } } }