// // TableFormatter.swift // Metrika // // Author: Simon-Pierre Boucher // Contact: contact@spboucher.ai // Copyright © 2026 Simon-Pierre Boucher. All rights reserved. // import Foundation /// Console table rendering: monospaced, right-aligned numeric columns in /// the Stata output tradition. enum TableFormatter { /// Stata-flavored general format: up to `significant` significant /// digits, no trailing zeros, leading "0." collapsed to ".". static func general(_ value: Double, significant: Int = 7) -> String { if value.isNaN { return "." } if value == 0 { return "0" } var text = String(format: "%.\(significant)g", value) if text.contains("."), !text.contains("e"), !text.contains("E") { while text.hasSuffix("0") { text.removeLast() } if text.hasSuffix(".") { text.removeLast() } } if text.hasPrefix("0.") { text.removeFirst() } if text.hasPrefix("-0.") { text = "-" + text.dropFirst(2) } return text } static func fixed(_ value: Double, decimals: Int) -> String { value.isNaN ? "." : String(format: "%.\(decimals)f", value) } static func pad(_ text: String, _ width: Int, right: Bool = true) -> String { if text.count >= width { return text } let padding = String(repeating: " ", count: width - text.count) return right ? padding + text : text + padding } /// Renders rows of cells with per-column widths; the first column is /// left-padded to its width and separated by " | ". static func rule(_ widths: [Int]) -> String { let first = String(repeating: "-", count: widths[0] + 1) let rest = widths.dropFirst().reduce(0) { $0 + $1 } + (widths.count - 1) * 2 return first + "+" + String(repeating: "-", count: rest + 1) } }