Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ on:
jobs:
build:

runs-on: macos-latest
runs-on: macos-15

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Show Swift version
run: swift --version
- name: Build
run: swift build -v
- name: Run tests
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
*.swiftpm/
.swiftpm/xcode/
Package.resolved
18 changes: 15 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
// swift-tools-version:5.1
// swift-tools-version:6.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "Table",
platforms: [
.macOS(.v11),
.iOS(.v14),
.tvOS(.v14),
.watchOS(.v7)
],
products: [
// Products define the executables and libraries produced by a package, and make them visible to other packages.
.library(
Expand All @@ -20,9 +26,15 @@ let package = Package(
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "Table",
dependencies: []),
dependencies: [],
swiftSettings: [
.swiftLanguageMode(.v6)
]),
.testTarget(
name: "TableTests",
dependencies: ["Table"]),
dependencies: ["Table"],
swiftSettings: [
.swiftLanguageMode(.v6)
]),
]
)
150 changes: 140 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
# Welcome to Table
The table is a helper function to print the table.
The table is a helper function to print the table.

You can print the table bypassing the Any data!
You can print the table bypassing the Any data!
[e.g., `1d array`,` 2d array`, and `dictionary`]

It inspired by `javascript` `console.table`.
It inspired by `javascript` `console.table`.

I'm sure if you practice coding interviews, it helps you a lot. You don't need to struggle for checking results using a build-in print function!

## Requirements

- **Swift 6.1+** (Xcode 16+ or Swift 6.1 toolchain on Linux)
- macOS 11+ / iOS 14+ / tvOS 14+ / watchOS 7+

## Usage

```swift
Expand Down Expand Up @@ -154,29 +159,154 @@ You can use it on your iPad Playground 😎



## Table Style

Choose between ASCII (default) or Unicode box-drawing characters:

### ASCII Style (Default)
```swift
print(table: [["1", "Hello"], ["2", "World"]], header: ["ID", "Word"])
```
```
+--+-----+
|ID|Word |
+--+-----+
|1 |Hello|
+--+-----+
|2 |World|
+--+-----+
```

### Unicode Style (MySQL-like)
```swift
print(table: [["1", "Hello"], ["2", "World"]], header: ["ID", "Word"], style: .unicode)
```
```
┌──┬─────┐
│ID│Word │
├──┼─────┤
│1 │Hello│
├──┼─────┤
│2 │World│
└──┴─────┘
```

## Multi-Language Support

Table correctly handles CJK characters, Korean Hangul, Japanese Kana, Arabic, and emoji with proper column alignment:

```swift
// Mixed language table with Unicode style
print(table: [
["Hello", "你好"],
["World", "世界"]
], header: ["EN", "CN"], style: .unicode)
```
```
┌─────┬────┐
│EN │CN │
├─────┼────┤
│Hello│你好│
├─────┼────┤
│World│世界│
└─────┴────┘
```

### Emoji Support

```swift
print(table: ["👋", "🎉", "🚀"], style: .unicode)
```
```
┌──┬──┬──┐
│👋│🎉│🚀│
└──┴──┴──┘
```

## Control Character Handling

Control characters are automatically escaped to prevent layout corruption:

```swift
print(table: ["Line1\nLine2", "Tab\there"])
// Displays as: |Line1\nLine2|Tab\there|
```

## Logger Integration

Table extends Apple's [os.Logger](https://developer.apple.com/documentation/os/logger) with a `table()` method for easy logging:

```swift
import os
import Table

let logger = Logger(subsystem: "com.myapp", category: "DataDisplay")

// 1D Array of String with Header
logger.table(["Good", "Very Good", "Happy", "Cool!"], header: ["Wed", "Thu", "Fri", "Sat"])

// 1D Array of Int
logger.table([2, 94231, 241245125125])

// 1D Array of Double
logger.table([2.0, 931, 214.24124])

// 2D Array of String
logger.table([["1", "HELLOW"], ["2", "WOLLEH"]], header: ["Index", "Words"])

// 2D Array with unequal columns
logger.table([["1", "b2"], ["Hellow", "Great!"], ["sdjfklsjdfklsadf", "dsf", "1"]])

// 2D Array of Int
logger.table([[1, 2, 3], [4, 5, 6], [7, 8, 9, 10]])

// Dictionary
logger.table(["name": "Alice", "age": 30] as [AnyHashable: Any], header: ["key", "value"])
```

### Logger Options

```swift
// Choose table style (default: .unicode)
logger.table(data, style: .ascii) // +--+--+
logger.table(data, style: .unicode) // ┌──┬──┐

// Choose log level (default: .info)
logger.table(data, level: .debug)
logger.table(data, level: .error)

// Choose distribution
logger.table(data, distribution: .fillEqually)
```

Output in Console.app:
```
┌─────┬───┐
│Name │Age│
├─────┼───┤
│Alice│30 │
├─────┼───┤
│Bob │25 │
└─────┴───┘
```

## What's the next step?!
I'm going to support more types!
- tuple
- decodable / encodable
- custom data type
- emoticon / unicode


Table Style
- ascii table
- dashed table
- and more

## Unit Tests
I'm going to add testCases for dictionary next time.
The library uses Swift Testing framework with 25+ test cases covering Unicode handling, performance, and edge cases.

## Contributing to Table
Contributions to the Table are welcomed and encouraged!

## Next Step
- Export CSV from Table
- Unicode

## Contact Me
If you have any questions about `Table`, please email me at shawn@shawnbaek.com

Loading