fix for line wrapping

This commit is contained in:
Will McGugan 2020-03-09 17:28:49 +00:00
parent 34cfcee6e7
commit e69d216d97
6 changed files with 42 additions and 56 deletions

View File

@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added Console.show_cursor method
### Fixed
- Fixed wrapping when a single word was too large to fit in a line
## [0.6.0] - 2020-03-03
### Added

View File

@ -4,24 +4,28 @@ from typing import Iterable, List, Tuple
re_word = re.compile(r"\s*\S+\s*")
def words(text: str) -> Iterable[Tuple[int, str]]:
def words(text: str) -> Iterable[Tuple[int, int, str]]:
position = 0
word_match = re_word.match(text, position)
while word_match is not None:
start, position = word_match.span()
start, end = word_match.span()
word = word_match.group(0)
yield start, word
word_match = re_word.match(text, position)
yield start, end, word
word_match = re_word.match(text, end)
def divide_line(text: str, width: int) -> List[int]:
divides: List[int] = []
append = divides.append
line_size = 0
for position, word in words(text):
if line_size + len(word.rstrip()) > width:
if position:
append(position)
line_size = 0
line_size += len(word)
line_position = 0
for start, end, word in words(text):
if line_position + len(word.rstrip()) > width:
if line_position and start:
append(start)
line_position = len(word)
else:
divides.extend(range(start or width, end + 1, width))
line_position = len(word) % width
else:
line_position += len(word)
return divides

View File

@ -57,6 +57,9 @@ class Lines:
def __init__(self, lines: Iterable["Text"] = ()) -> None:
self._lines: List["Text"] = list(lines)
def __repr__(self) -> str:
return f"Lines({self._lines!r})"
def __iter__(self) -> Iterator["Text"]:
return iter(self._lines)

View File

@ -3,7 +3,7 @@ from dataclasses import dataclass, field
import sys
from time import monotonic
from threading import Event, RLock, Thread
from typing import Callable, Dict, List, Optional, NewType, Union
from typing import Any, Callable, Dict, List, Optional, NewType, Union
from .bar import Bar
from .console import Console, RenderableType
@ -29,7 +29,7 @@ class Task:
total: float
completed: float
visible: bool = True
fields: Dict[str, str] = field(default_factory=dict)
fields: Dict[str, Any] = field(default_factory=dict)
@property
def finished(self) -> bool:
@ -45,7 +45,7 @@ class Task:
class RefreshThread(Thread):
"""A thread that calls refresh on the Process object at regular intervals."""
"""A thread that calls refresh() on the Process object at regular intervals."""
def __init__(self, progress: "Progress", refresh_per_second: int = 10) -> None:
self.progress = progress
@ -59,10 +59,7 @@ class RefreshThread(Thread):
def run(self) -> None:
while not self.done.wait(1.0 / self.refresh_per_second):
try:
self.progress.refresh()
except Exception as error:
raise
self.progress.refresh()
def bar_widget(task: Task) -> Bar:
@ -95,11 +92,13 @@ class Progress:
@property
def tasks(self) -> List[TaskID]:
"""Get a list of task IDs."""
with self._lock:
return list(self._tasks.keys())
@property
def finished(self) -> bool:
"""Check if all tasks have been completed."""
with self._lock:
if not self._tasks:
return True
@ -125,11 +124,12 @@ class Progress:
def update(
self,
task_id: TaskID,
*,
total: float = None,
completed: float = None,
advance: float = None,
visible: bool = None,
**fields: RenderableType
**fields: Any
) -> None:
with self._lock:
task = self._tasks[task_id]
@ -143,6 +143,7 @@ class Progress:
task.visible = True
def refresh(self) -> None:
"""Refresh (render) the progress information."""
with self._lock:
self._live_render.set_renderable(self._table)
self.console.print(self._live_render)
@ -192,14 +193,14 @@ class Progress:
if __name__ == "__main__":
import random
import time
with Progress() as progress:
task1 = progress.add_task("[red]Downloading")
task2 = progress.add_task("[green]Processing")
task3 = progress.add_task("[cyan]Cooking...")
task3 = progress.add_task("[cyan]Cooking")
while not progress.finished:
progress.update(task1, advance=1.0)

View File

@ -303,6 +303,7 @@ class Table:
flex_widths = [_range.span for _range in width_ranges]
if not any(flex_widths):
flex_widths = [1] * len(flex_widths)
flex_widths = [0 if column.no_wrap else 1 for column in columns]
excess_width = table_width - max_width
widths = [
width - excess_width
@ -457,29 +458,15 @@ class Table:
if __name__ == "__main__": # pragma: no cover
from .console import Console
from . import box
c = Console(markup=True)
table = Table(
Column(
"Foo", footer=Text("Total", justify="right"), footer_style="bold", ratio=1
),
Column("Bar", style="red", footer="123", ratio=1),
expand=True,
show_footer=True,
show_edge=True,
style="on blue",
c = Console(width=80)
table = Table()
table.add_column(no_wrap=True)
table.add_column()
table.add_row(
"Magnet",
"pneumonoultramicroscopicsilicovolcanoconiosispneumonoultramicroscopicsilicovolcanoconiosispneumonoultramicroscopicsilicovolcanoconiosis",
)
# table.columns[0].width = 50
# table.columns[1].ratio = 1
table.add_row("Hello, [b]World[/b]! " * 3, "cake" * 10)
from .markdown import Markdown
table.add_row(Markdown("# This is *Markdown*!"), "More text", "Hello WOrld")
table.columns[0].justify = "center"
table.columns[1].justify = "right"
c.print(table)

View File

@ -644,16 +644,3 @@ class Text:
append(line)
return lines
if __name__ == "__main__": # pragma: no cover
from .console import Console
console = Console()
text = Text(
"""Hello, self! hello World
hello worhello\n"""
)
text.highlight_regex("self", "reverse")
console.print(text)