diff --git a/README.md b/README.md index 83613911..45a7d0d4 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ option. - `--airport` enables the `airport -I` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/airport)) - `--airport-s` enables the `airport -s` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/airport_s)) - `--arp` enables the `arp` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/arp)) +- `--asciitable` enables the ASCII and Unicode table parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/asciitable)) - `--asciitable-m` enables the multi-line ASCII and Unicode table parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/asciitable_m)) - `--blkid` enables the `blkid` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/blkid)) - `--cksum` enables the `cksum` and `sum` command parser ([documentation](https://kellyjonbrazil.github.io/jc/docs/parsers/cksum)) diff --git a/docs/parsers/asciitable.md b/docs/parsers/asciitable.md new file mode 100644 index 00000000..8a4ced2a --- /dev/null +++ b/docs/parsers/asciitable.md @@ -0,0 +1,97 @@ +[Home](https://kellyjonbrazil.github.io/jc/) + + +# jc.parsers.asciitable + +jc - JSON Convert `asciitable` parser + +This parser converts ASCII and Unicode text tables with single-line rows. + +Column headers must be at least two spaces apart from each other and must +be unique. + +For example: + + ╒══════════╤═════════╤════════╕ + │ foo │ bar │ baz │ + ╞══════════╪═════════╪════════╡ + │ good day │ │ 12345 │ + ├──────────┼─────────┼────────┤ + │ hi there │ abc def │ 3.14 │ + ╘══════════╧═════════╧════════╛ + + or + + +-----------------------------+ + | foo bar baz | + +-----------------------------+ + | good day 12345 | + | hi there abc def 3.14 | + +-----------------------------+ + + or + + | foo | bar | baz | + |----------|---------|--------| + | good day | | 12345 | + | hi there | abc def | 3.14 | + + or + + foo bar baz + --------- -------- ------ + good day 12345 + hi there abc def + + etc. + +Usage (cli): + + $ cat table.txt | jc --asciitable + +Usage (module): + + import jc + result = jc.parse('asciitable', asciitable_string) + +Schema: + + [ + { + "column_name1": string, # empty string is null + "column_name2": string # empty string is null + } + ] + +Examples: + + $ asciitable | jc --asciitable -p + [] + + $ asciitable | jc --asciitable -p -r + [] + + + +### parse + +```python +def parse(data: str, raw: bool = False, quiet: bool = False) -> List[Dict] +``` + +Main text parsing function + +Parameters: + + data: (string) text data to parse + raw: (boolean) unprocessed output if True + quiet: (boolean) suppress warning messages if True + +Returns: + + List of Dictionaries. Raw or processed structured data. + +### Parser Information +Compatibility: linux, darwin, cygwin, win32, aix, freebsd + +Version 1.0 by Kelly Brazil (kellyjonbrazil@gmail.com) diff --git a/docs/parsers/asciitable_m.md b/docs/parsers/asciitable_m.md index 8afd2e3d..7c416618 100644 --- a/docs/parsers/asciitable_m.md +++ b/docs/parsers/asciitable_m.md @@ -41,8 +41,8 @@ Schema: [ { - "column_name1": string, - "column_name2": string + "column_name1": string, # empty string is null + "column_name2": string # empty string is null } ] diff --git a/jc/parsers/asciitable_m.py b/jc/parsers/asciitable_m.py index c3f1c575..415fef0b 100644 --- a/jc/parsers/asciitable_m.py +++ b/jc/parsers/asciitable_m.py @@ -36,8 +36,8 @@ Schema: [ { - "column_name1": string, - "column_name2": string + "column_name1": string, # empty string is null + "column_name2": string # empty string is null } ] @@ -92,7 +92,7 @@ Examples: ] """ import re -from typing import Iterable, Tuple, List, Dict +from typing import Iterable, Tuple, List, Dict, Optional import jc.utils from jc.exceptions import ParseError @@ -350,11 +350,21 @@ def _collapse_data(table: List[List[List[str]]]) -> List[List[str]]: return result -def _create_table_dict(header: List[str], data: List[List[str]]) -> List[Dict[str, str]]: - return [dict(zip(header, r)) for r in data] +def _create_table_dict(header: List[str], data: List[List[str]]) -> List[Dict[str, Optional[str]]]: + """ + zip the headers and data to create a list of dictionaries. Also convert + empty strings to None. + """ + table_list_dict: List[Dict[str, Optional[str]]] = [dict(zip(header, r)) for r in data] + for row in table_list_dict: + for k, v in row.items(): + if v == '': + row[k] = None + + return table_list_dict -def _parse_pretty(string: str) -> List[Dict[str, str]]: +def _parse_pretty(string: str) -> List[Dict[str, Optional[str]]]: string_lines: List[str] = string.splitlines() clean: List[Tuple[int, List[str]]] = _normalize_rows(string_lines) raw_headers: List[List[str]] = _get_headers(clean) @@ -362,7 +372,7 @@ def _parse_pretty(string: str) -> List[Dict[str, str]]: new_headers: List[str] = _collapse_headers(raw_headers) new_data: List[List[str]] = _collapse_data(raw_data) - final_table: List[Dict[str, str]] = _create_table_dict(new_headers, new_data) + final_table: List[Dict[str, Optional[str]]] = _create_table_dict(new_headers, new_data) return final_table diff --git a/man/jc.1 b/man/jc.1 index e29c47d6..7b642f1b 100644 --- a/man/jc.1 +++ b/man/jc.1 @@ -37,6 +37,11 @@ Parsers: \fB--arp\fP `arp` command parser +.TP +.B +\fB--asciitable\fP +ASCII and Unicode table parser + .TP .B \fB--asciitable-m\fP