or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli.mdconfiguration.mdfile-processing.mdformatting.mdindex.mdindividual-fixes.mdtext-fixing.mdutilities.md

formatting.mddocs/

0

# Display and Formatting

1

2

Unicode-aware text formatting for terminal display, including width calculation and justification functions that handle fullwidth characters and zero-width characters correctly.

3

4

## Capabilities

5

6

### Character Width Calculation

7

8

Functions for calculating the display width of Unicode characters in monospaced terminals.

9

10

```python { .api }

11

def character_width(char: str) -> int:

12

"""

13

Determine display width of character in monospaced terminal.

14

15

Returns width in terminal columns: 0 for zero-width, 1 for normal,

16

2 for wide characters (CJK), -1 for control/non-printable chars.

17

Uses wcwidth library for accurate Unicode width calculation.

18

19

Args:

20

char: Single Unicode character

21

22

Returns:

23

Display width (0, 1, 2, or -1)

24

25

Examples:

26

>>> character_width('A')

27

1

28

>>> character_width('車') # Wide CJK character

29

2

30

>>> character_width('\\u200b') # Zero-width space

31

0

32

>>> character_width('\\x1b') # Control character

33

-1

34

"""

35

36

def monospaced_width(text: str) -> int:

37

"""

38

Calculate total display width of text in monospaced terminal.

39

40

Sums the display widths of all characters, handling wide characters,

41

zero-width characters, and control sequences properly.

42

43

Args:

44

text: Unicode string

45

46

Returns:

47

Total display width in terminal columns, or -1 if contains

48

control characters that make width undetermined

49

50

Examples:

51

>>> monospaced_width("hello")

52

5

53

>>> monospaced_width("café")

54

4

55

>>> monospaced_width("hello世界") # Mixed ASCII and wide chars

56

9

57

>>> monospaced_width("hello\\x1b[31m") # Contains control chars

58

-1

59

"""

60

```

61

62

### Text Justification

63

64

Unicode-aware text justification functions that properly handle character width for terminal display.

65

66

```python { .api }

67

def display_ljust(text: str, width: int, fillchar: str = " ") -> str:

68

"""

69

Left-justify text in field of given width, accounting for Unicode display width.

70

71

Unlike str.ljust(), correctly handles wide characters (CJK), zero-width

72

characters, and combining characters for proper terminal alignment.

73

74

Args:

75

text: String to justify

76

width: Target display width in terminal columns

77

fillchar: Character to pad with (default space)

78

79

Returns:

80

Left-justified string

81

82

Examples:

83

>>> display_ljust("hello", 10)

84

'hello '

85

>>> display_ljust("café", 10, '-')

86

'café------'

87

>>> display_ljust("世界", 6) # Wide chars count as 2

88

'世界 '

89

"""

90

91

def display_rjust(text: str, width: int, fillchar: str = " ") -> str:

92

"""

93

Right-justify text in field of given width, accounting for Unicode display width.

94

95

Unicode-aware version of str.rjust() that handles wide characters,

96

zero-width characters, and combining characters correctly.

97

98

Args:

99

text: String to justify

100

width: Target display width in terminal columns

101

fillchar: Character to pad with (default space)

102

103

Returns:

104

Right-justified string

105

106

Examples:

107

>>> display_rjust("hello", 10)

108

' hello'

109

>>> display_rjust("世界", 6) # Wide chars handled correctly

110

' 世界'

111

"""

112

113

def display_center(text: str, width: int, fillchar: str = " ") -> str:

114

"""

115

Center text in field of given width, accounting for Unicode display width.

116

117

Unicode-aware version of str.center() that properly centers text

118

containing wide characters, zero-width characters, and combining chars.

119

120

Args:

121

text: String to center

122

width: Target display width in terminal columns

123

fillchar: Character to pad with (default space)

124

125

Returns:

126

Centered string

127

128

Examples:

129

>>> display_center("hello", 11)

130

' hello '

131

>>> display_center("世界", 8) # Wide chars centered correctly

132

' 世界 '

133

"""

134

```

135

136

## Usage Examples

137

138

### Basic Width Calculation

139

140

```python

141

from ftfy.formatting import character_width, monospaced_width

142

143

# Check individual character widths

144

print(character_width('A')) # 1 - normal ASCII

145

print(character_width('世')) # 2 - wide CJK

146

print(character_width('\u0300')) # 0 - combining accent

147

print(character_width('\t')) # -1 - control character

148

149

# Calculate total text width

150

text = "Hello 世界!"

151

width = monospaced_width(text)

152

print(f"'{text}' displays as {width} columns") # 9 columns

153

```

154

155

### Terminal-Aware Text Alignment

156

157

```python

158

from ftfy.formatting import display_ljust, display_rjust, display_center

159

160

texts = ["hello", "café", "世界", "mixed 世界 text"]

161

width = 20

162

163

print("Left justified:")

164

for text in texts:

165

justified = display_ljust(text, width, '.')

166

print(f"'{justified}'")

167

168

print("\nRight justified:")

169

for text in texts:

170

justified = display_rjust(text, width, '.')

171

print(f"'{justified}'")

172

173

print("\nCentered:")

174

for text in texts:

175

justified = display_center(text, width, '.')

176

print(f"'{justified}'")

177

```

178

179

### Table Formatting

180

181

```python

182

from ftfy.formatting import display_ljust, display_rjust, monospaced_width

183

184

def format_table(data, headers, widths):

185

"""Format table with proper Unicode alignment."""

186

187

# Print headers

188

header_row = " | ".join(

189

display_ljust(header, width)

190

for header, width in zip(headers, widths)

191

)

192

print(header_row)

193

print("-" * monospaced_width(header_row))

194

195

# Print data rows

196

for row in data:

197

formatted_row = " | ".join(

198

display_ljust(str(cell), width)

199

for cell, width in zip(row, widths)

200

)

201

print(formatted_row)

202

203

# Example with mixed character widths

204

headers = ["Name", "City", "Score"]

205

widths = [15, 10, 8]

206

data = [

207

["Alice Smith", "NYC", "95.5"],

208

["田中太郎", "東京", "87.2"], # Japanese name and city

209

["José García", "México", "92.1"] # Accented characters

210

]

211

212

format_table(data, headers, widths)

213

```

214

215

### Progress Bar with Unicode

216

217

```python

218

from ftfy.formatting import display_ljust, monospaced_width

219

220

def unicode_progress_bar(current, total, width=40, fill='█', empty='░'):

221

"""Create progress bar that handles Unicode fill characters."""

222

223

# Calculate fill amount based on actual character widths

224

fill_width = monospaced_width(fill)

225

empty_width = monospaced_width(empty)

226

227

# Adjust for character widths

228

if fill_width > 1:

229

width = width // fill_width * fill_width

230

231

percent = current / total

232

filled_chars = int(width * percent // fill_width)

233

empty_chars = (width - filled_chars * fill_width) // empty_width

234

235

bar = fill * filled_chars + empty * empty_chars

236

237

return f"[{bar}] {current}/{total} ({percent:.1%})"

238

239

# Example with Unicode characters

240

print(unicode_progress_bar(7, 10)) # [██████████████████████████████░░░░░░░░░░] 7/10 (70.0%)

241

print(unicode_progress_bar(3, 5)) # [████████████████████████░░░░░░░░░░░░░░░░] 3/5 (60.0%)

242

```

243

244

### Command Line Output Formatting

245

246

```python

247

from ftfy.formatting import display_ljust, display_center, monospaced_width

248

249

def print_status_table(statuses):

250

"""Print status table with proper alignment."""

251

252

# Calculate column widths based on actual display widths

253

name_width = max(monospaced_width(s['name']) for s in statuses) + 2

254

status_width = max(monospaced_width(s['status']) for s in statuses) + 2

255

256

print(display_center("System Status", name_width + status_width))

257

print("=" * (name_width + status_width))

258

259

for item in statuses:

260

name_col = display_ljust(item['name'], name_width)

261

status_col = display_ljust(item['status'], status_width)

262

print(f"{name_col}{status_col}")

263

264

# Example with international text

265

statuses = [

266

{'name': 'Database', 'status': '✓ Running'},

267

{'name': 'サーバー', 'status': '✓ 動作中'}, # Japanese

268

{'name': 'Señales', 'status': '⚠ Alerta'}, # Spanish with warning

269

{'name': 'Система', 'status': '✗ Ошибка'} # Russian with error

270

]

271

272

print_status_table(statuses)

273

```

274

275

### Width-Aware Text Processing

276

277

```python

278

from ftfy.formatting import monospaced_width, display_ljust

279

280

def wrap_text_unicode(text, max_width):

281

"""Wrap text accounting for Unicode display width."""

282

words = text.split()

283

lines = []

284

current_line = []

285

current_width = 0

286

287

for word in words:

288

word_width = monospaced_width(word)

289

space_width = 1 if current_line else 0

290

291

if current_width + word_width + space_width <= max_width:

292

current_line.append(word)

293

current_width += word_width + space_width

294

else:

295

if current_line:

296

lines.append(' '.join(current_line))

297

current_line = [word]

298

current_width = word_width

299

300

if current_line:

301

lines.append(' '.join(current_line))

302

303

return lines

304

305

# Example with mixed character widths

306

mixed_text = "This text contains 中文字符 and עברית characters with different display widths"

307

wrapped = wrap_text_unicode(mixed_text, 30)

308

for line in wrapped:

309

print(f"'{line}' ({monospaced_width(line)} columns)")

310

```