SPB Git

spb/metrika Public

Stata-class statistics, GPU-accelerated by Apple Silicon. Native Swift — no Electron, no Python runtime, no compromises.

Swift 92.4% HTML 3.3% R 3% Shell 1.3%
1.8 KB · 49 lines swift
Raw Blame History
1//2//  TableFormatter.swift3//  Metrika4//5//  Author:  Simon-Pierre Boucher6//  Contact: contact@spboucher.ai7//  Copyright © 2026 Simon-Pierre Boucher. All rights reserved.8//910import Foundation1112/// Console table rendering: monospaced, right-aligned numeric columns in13/// the Stata output tradition.14enum TableFormatter {1516    /// Stata-flavored general format: up to `significant` significant17    /// digits, no trailing zeros, leading "0." collapsed to ".".18    static func general(_ value: Double, significant: Int = 7) -> String {19        if value.isNaN { return "." }20        if value == 0 { return "0" }21        var text = String(format: "%.\(significant)g", value)22        if text.contains("."), !text.contains("e"), !text.contains("E") {23            while text.hasSuffix("0") { text.removeLast() }24            if text.hasSuffix(".") { text.removeLast() }25        }26        if text.hasPrefix("0.") { text.removeFirst() }27        if text.hasPrefix("-0.") { text = "-" + text.dropFirst(2) }28        return text29    }3031    static func fixed(_ value: Double, decimals: Int) -> String {32        value.isNaN ? "." : String(format: "%.\(decimals)f", value)33    }3435    static func pad(_ text: String, _ width: Int, right: Bool = true) -> String {36        if text.count >= width { return text }37        let padding = String(repeating: " ", count: width - text.count)38        return right ? padding + text : text + padding39    }4041    /// Renders rows of cells with per-column widths; the first column is42    /// left-padded to its width and separated by " | ".43    static func rule(_ widths: [Int]) -> String {44        let first = String(repeating: "-", count: widths[0] + 1)45        let rest = widths.dropFirst().reduce(0) { $0 + $1 } + (widths.count - 1) * 246        return first + "+" + String(repeating: "-", count: rest + 1)47    }48}49