2021-01-29 06:31:58 -05:00
|
|
|
|
|
|
|
[![Arduino CI](https://github.com/RobTillaart/LineFormatter/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
|
2021-11-06 12:49:23 -04:00
|
|
|
[![Arduino-lint](https://github.com/RobTillaart/LineFormatter/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/LineFormatter/actions/workflows/arduino-lint.yml)
|
|
|
|
[![JSON check](https://github.com/RobTillaart/LineFormatter/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/LineFormatter/actions/workflows/jsoncheck.yml)
|
2023-11-07 09:04:39 -05:00
|
|
|
[![GitHub issues](https://img.shields.io/github/issues/RobTillaart/LineFormatter.svg)](https://github.com/RobTillaart/LineFormatter/issues)
|
|
|
|
|
2021-01-29 06:31:58 -05:00
|
|
|
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/LineFormatter/blob/master/LICENSE)
|
|
|
|
[![GitHub release](https://img.shields.io/github/release/RobTillaart/LineFormatter.svg?maxAge=3600)](https://github.com/RobTillaart/LineFormatter/releases)
|
2023-11-07 09:04:39 -05:00
|
|
|
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/robtillaart/library/LineFormatter.svg)](https://registry.platformio.org/libraries/robtillaart/LineFormatter)
|
2021-01-29 06:31:58 -05:00
|
|
|
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2020-05-17 04:37:41 -04:00
|
|
|
# LineFormatter
|
|
|
|
|
|
|
|
Arduino library to enhance the layout of tabular data on serial output,
|
|
|
|
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2020-05-17 04:37:41 -04:00
|
|
|
# Description
|
|
|
|
|
|
|
|
LineFormatter is a wrapper class for Serial (and other streams) to enhance
|
|
|
|
layout of tabular data.
|
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
The class intercepts the **TAB (\t)** characters printed and replaces them with spaces to
|
2024-02-19 14:13:19 -05:00
|
|
|
the next defined tab-position. These positions can be created with **addTab(position)**
|
2023-01-31 07:39:06 -05:00
|
|
|
for absolute positions and **addRelTab(n)** for relative positions.
|
2024-02-19 14:13:19 -05:00
|
|
|
Since 0.3.0 one can set all tab positions with **setTabs(arr, size)**.
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
Absolute tab positions must be added in **increasing** order as the class does not
|
|
|
|
check or sort the input. Adding the same tab position is not possible since 0.2.0.
|
|
|
|
Also position 0 will be ignored as tabStop.
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
The maximum number of tabs is defined by **MAX_TAB_STOPS** == 12 default.
|
|
|
|
This value can be overruled by -D compile flag or edited in the LineFormatter.h file.
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
All tab positions can be cleared in one call by **clearTabs()**.
|
2024-02-19 14:13:19 -05:00
|
|
|
Since 0.2.0 the library also supports **removeTab(position)** to remove a single tab.
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
The function **autoNewLine(n)** prints a newline after every n lines automatically.
|
|
|
|
This makes it easier to count the lines in a table, e.g after every 10 lines.
|
|
|
|
Setting **n** to 0 disables this function.
|
|
|
|
|
2024-02-19 14:13:19 -05:00
|
|
|
The function **gotoPos(position)** prints spaces until the cursor is on position **position**.
|
|
|
|
If the current position is beyond **position**, it does nothing (check the returned position!).
|
2020-05-17 04:37:41 -04:00
|
|
|
Besides for tabular data, this function can be used to make simple text based
|
2023-01-31 07:39:06 -05:00
|
|
|
graphs, e.g. a sine wave.
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
The function **repeat(n, s, nl)** which repeats a character or a string n times.
|
2020-05-17 04:37:41 -04:00
|
|
|
This is followed by **nl** newlines which is zero by default.
|
|
|
|
**repeat()** is useful to make separator lines or to print several newlines at once.
|
2023-01-31 07:39:06 -05:00
|
|
|
A simple histogram is easy to make.
|
2020-05-17 04:37:41 -04:00
|
|
|
|
|
|
|
The function **setMaxLength(n)** to cut off (brute force, no intelligence) lines
|
|
|
|
after n characters by injecting an extra newline. This prevents scrolling hundreds
|
2023-01-31 07:39:06 -05:00
|
|
|
of positions to the right.
|
2020-05-17 04:37:41 -04:00
|
|
|
Setting the value to 0 results in no maximum line length.
|
2023-01-31 07:39:06 -05:00
|
|
|
|
|
|
|
Note: the maximum line length is 255 as all internal positions are 8 bit.
|
|
|
|
A 16 bit lineFormatter is planned for future (on request).
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2023-11-07 09:04:39 -05:00
|
|
|
#### Related
|
|
|
|
|
|
|
|
- https://github.com/RobTillaart/ANSI
|
2024-02-19 14:13:19 -05:00
|
|
|
- https://github.com/RobTillaart/PrintSize helper for right alignment
|
|
|
|
- https://github.com/RobTillaart/printHelpers formatters
|
2023-11-07 09:04:39 -05:00
|
|
|
|
|
|
|
|
2021-11-06 12:49:23 -04:00
|
|
|
## Interface
|
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
```cpp
|
|
|
|
#include "LineFormatter.h"
|
|
|
|
```
|
|
|
|
|
|
|
|
#### Constructor
|
|
|
|
|
|
|
|
- **LineFormatter(Print\* stream = &Serial)** constructor.
|
|
|
|
Connects to a stream, default Serial.
|
|
|
|
- **reset()** reset internal variables to restart from default again.
|
2021-11-06 12:49:23 -04:00
|
|
|
|
|
|
|
|
|
|
|
#### Printing
|
|
|
|
|
2024-02-19 14:13:19 -05:00
|
|
|
- **size_t write(uint8_t ch)** implements printing per character.
|
|
|
|
- **uint8_t gotoPos(uint8_t position)** if position is smaller than position, move to the right.
|
2023-01-31 07:39:06 -05:00
|
|
|
Returns the updated position.
|
2024-02-19 14:13:19 -05:00
|
|
|
- **void repeat(uint8_t n, char ch, uint8_t newLine = 0)** repeat a char n times.
|
2023-01-31 07:39:06 -05:00
|
|
|
Typical used to create separation lines, or multiple line feeds.
|
|
|
|
The repeated string is optionally followed by a number of newlines.
|
2021-12-20 14:09:13 -05:00
|
|
|
- **void repeat(uint8_t n, const char\* str, uint8_t newLine = 0)** repeat a "string" n times.
|
2023-01-31 07:39:06 -05:00
|
|
|
The repeated string is optionally followed by a number of newlines.
|
|
|
|
Typical used to create separation lines.
|
2024-02-19 14:13:19 -05:00
|
|
|
- **void tab(uint8_t n = 1)** print zero or more tabs, similar as e.g. "\t\t\t".
|
|
|
|
|
|
|
|
|
|
|
|
As the library implements the **Print** interface, all data types can be printed.
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2024-02-19 14:13:19 -05:00
|
|
|
```cpp
|
|
|
|
LF.print(3.1425);
|
|
|
|
```
|
2021-11-06 12:49:23 -04:00
|
|
|
|
|
|
|
#### Tab configuration
|
|
|
|
|
2024-02-19 14:13:19 -05:00
|
|
|
- **bool addTab(uint8_t n)** Add a tab at an **absolute** position.
|
2023-01-31 07:39:06 -05:00
|
|
|
Returns true on success.
|
|
|
|
Note: no tab can be set on position 0 (return false)
|
|
|
|
Note: existing tabs will be ignored (return false)
|
2024-02-19 14:13:19 -05:00
|
|
|
- **bool addRelTab(uint8_t n)** Add a tab at a **relative** position to the last
|
|
|
|
position in the internal array.
|
|
|
|
Often this is easier to setup the positions, (think column width).
|
2023-01-31 07:39:06 -05:00
|
|
|
Returns true on success.
|
2021-11-06 12:49:23 -04:00
|
|
|
- **void clearTabs()** remove all the tabs.
|
2024-02-19 14:13:19 -05:00
|
|
|
- **bool removeTab(uint8_t position)** remove a tab at given position.
|
|
|
|
Returns true if a tab exists at **position**.
|
|
|
|
Returns false if no tab existed at that index.
|
|
|
|
|
|
|
|
|
|
|
|
- **bool setTabs(uint8_t \* positions, uint8_t size)** Set the internal array
|
|
|
|
of tabs in one call. Clears all existing tabs.
|
|
|
|
If **size < MAX_TAB_STOPS** the user might add additional tabs with **addTab()**
|
|
|
|
or with **addRelTab()** and remove with **removeTab()**
|
|
|
|
- **uint8_t getTabs(uint8_t \* positions)** get the positions stored in the
|
|
|
|
internal array of tabs. Returns the amount of tab stops.
|
|
|
|
User must take care that the positions array is large enough.
|
|
|
|
Typical use is to be able to adjust positions outside this library.
|
|
|
|
After that the new array can be used as parameter in **setTabs()**.
|
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
|
|
|
|
Note:
|
2024-02-19 14:13:19 -05:00
|
|
|
Removing a tab is in essence non-reversible, so one cannot insert a removed tab stop again.
|
|
|
|
By calling **size = getTabs(arr)** before the removal and call **setTabs(arr, size)** after
|
|
|
|
the remove one can "restore" the tab.
|
|
|
|
|
|
|
|
Replacing a tab can be done with **getTabs()** and **setTabs()** too.
|
|
|
|
|
|
|
|
```cpp
|
|
|
|
// shift all tab positions 4 places to the right.
|
|
|
|
size = getTabs(arr);
|
|
|
|
for (int i = 0; i < size; i++) arr[i] += 4;
|
|
|
|
setTabs(arr, size);
|
|
|
|
```
|
2021-11-06 12:49:23 -04:00
|
|
|
|
|
|
|
|
|
|
|
#### Line configuration
|
|
|
|
|
2021-12-20 14:09:13 -05:00
|
|
|
- **void setMaxLength(uint8_t maxPos)** set the maximum line length - bold cut off.
|
2023-01-31 07:39:06 -05:00
|
|
|
Will be disabled when set to 0.
|
2024-02-19 14:13:19 -05:00
|
|
|
Note: maximum line length == 255 (uint8_t range)
|
2021-11-06 12:49:23 -04:00
|
|
|
- **uint8_t getMaxLength()** return max line length set.
|
2023-01-31 07:39:06 -05:00
|
|
|
- **void setAutoNewLine(uint8_t n = 1)** n = 0 switches autoNewLine off.
|
|
|
|
- **uint8_t getAutoNewLine()** returns number of newlines set before.
|
2021-11-06 12:49:23 -04:00
|
|
|
|
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
#### Miscellaneous
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
For debugging and other purposes there are the following functions:
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2021-12-20 14:09:13 -05:00
|
|
|
- **uint8_t getPos()** returns current position.
|
|
|
|
- **void resetLineCount()** sets internal lineCounter to zero.
|
2023-01-31 07:39:06 -05:00
|
|
|
- **uint32_t getLineCount()** returns current line number (since last reset).
|
|
|
|
- **uint8_t getTabCount()** get the number of tab positions.
|
|
|
|
- **uint8_t getTabStop(uint8_t n)** returns the position of the n-th tab.
|
|
|
|
- **void printRuler(uint8_t length)** prints a dotted line with 5 and 10 markers,
|
|
|
|
and # for tab positions.
|
2024-02-19 14:13:19 -05:00
|
|
|
The ruler is length long.
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2020-05-17 04:37:41 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
## Future
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
#### Must
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
- redo documentation misc/debug part
|
2021-11-06 12:49:23 -04:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
#### Should
|
2022-11-14 14:50:36 -05:00
|
|
|
|
2023-01-31 07:39:06 -05:00
|
|
|
- investigate correct working of maxPosition handling.
|
|
|
|
- investigate position 1 as tabStop?
|
|
|
|
- 0 is ignored but 1 is ambiguous
|
|
|
|
|
|
|
|
#### Could
|
|
|
|
|
2024-02-19 14:13:19 -05:00
|
|
|
- add sorting to **addTab()** 0.X.0?
|
|
|
|
- insert sort - bit like in removeTab()
|
|
|
|
- would allow dynamic inserting.
|
|
|
|
- add examples
|
|
|
|
- DS18B20 demo - 6 readings per line, followed by average?
|
|
|
|
- 0.X.0 ?
|
2023-01-31 07:39:06 -05:00
|
|
|
- addTab ==> addAbsoluteTab()
|
|
|
|
- addRelTab ==> addRelativeTab()
|
|
|
|
- error handling in addTab()?
|
|
|
|
- lineFormatter16
|
|
|
|
- or just make it 16 bit version to allow tables more than 255 chars wide
|
|
|
|
- uses more memory!
|
|
|
|
- separate class as 8 bit is everywhere
|
|
|
|
- right alignment for numbers
|
|
|
|
- point alignment for floats
|
|
|
|
- investigate macros again.
|
|
|
|
- filter for unprintable characters,
|
|
|
|
- isAscii() test
|
2023-11-07 09:04:39 -05:00
|
|
|
- define replace char, default point / space?
|
2023-01-31 07:39:06 -05:00
|
|
|
|
2022-11-14 14:50:36 -05:00
|
|
|
#### Wont
|
2023-01-31 07:39:06 -05:00
|
|
|
|
2021-12-20 14:09:13 -05:00
|
|
|
- check if print interface is completely covered.
|
|
|
|
- due to tab parsing it is, so no speed up.
|
|
|
|
|
|
|
|
|
2023-11-07 09:04:39 -05:00
|
|
|
## Support
|
|
|
|
|
|
|
|
If you appreciate my libraries, you can support the development and maintenance.
|
|
|
|
Improve the quality of the libraries by providing issues and Pull Requests, or
|
|
|
|
donate through PayPal or GitHub sponsors.
|
|
|
|
|
|
|
|
Thank you,
|
|
|
|
|