# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['textomatic', 'textomatic.app', 'textomatic.processor']

package_data = \
{'': ['*']}

install_requires = \
['clevercsv>=0.6.4,<0.7.0',
 'click>=7.1.2,<8.0.0',
 'prompt-toolkit>=3.0.7,<4.0.0',
 'pygments>=2.7.1,<3.0.0',
 'pyparsing>=2.4.7,<3.0.0',
 'pyperclip>=1.8.0,<2.0.0',
 'tabulate>=0.8.7,<0.9.0']

entry_points = \
{'console_scripts': ['tm = textomatic.main:main']}

setup_kwargs = {
    'name': 'textomatic',
    'version': '0.3.0',
    'description': 'Scratchpad for tabular data transformations, and then some',
    'long_description': '# textomatic\nScratchpad for tabular data transformations\n\nGiven input of some tabular data (AKA `INPUT`), \nand a command (AKA `COMMAND`), transform that input \ninto some other output (AKA `OUTPUT`).\n\n![Screencast Demo](https://i.ibb.co/bL9MJkm/demo.gif)\n\n## Installation\n```shell script\npip install textomatic\n```\n\nAt the moment, Python 3.8 or greater is required.\n\n## Running\nStart it by running\n```shell script\n$ tm\n```\n\nThe above will start `textomatic` with a blank slate.\n\nYou can load a file by passing it as the first argument:\n```shell script\n$ tm <PATH_TO_FILE>\n```\n\nYou can also pipe content from stdin:\n```shell script\n$ ls | tm\n```\n\nTo see what arguments/options are available, run:\n```\n$ tm --help\n```\n\nWhen `textomatic` is running, type `F1` to see available keyboard shortcuts.\n\nTo exit `textomatic` use `CTRL-C` to exit without any output or `CTRL-O` to print\ncurrent `OUTPUT` into standard out.\n\nUse `CTRL-P` to put the current `OUTPUT` in the system clipboard.\n\n## Examples\n\n### Parsing `ps aux` output\nPipeing content from shell using `ps aux | tm` and transforming it into json lines where\neach line containes the `USER` and `PID` columns with lower cased keys.\n`PID` is casted into an integer.\n\n`COMMAND`:\n* `h` says `INPUT` includes a header\n* `i:sh` says the `INPUT` should be parsed like shell output\n* `s:{user:USER,pid:PID}` specifies the output structure\n* `o:jl` specifies the output format to be json lines\n* `t:PID:i` specifies the `PID` column shouldd ge parsed as integer\n```\nINPUT                                  │OUTPUT                                  \nUSER               PID  %CPU %MEM      │{"user": "dan", "pid": 63507}           \ndan              63507   6.3  0.4  6178│{"user": "_windowserver", "pid": 250}   \n_windowserver      250   4.4  0.3 12494│{"user": "dan", "pid": 54987}           \ndan              54987   3.8 12.8 16080│{"user": "_hidd", "pid": 184}           \n_hidd              184   2.0  0.0  5608│                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \nvi-insert|COMMAND|live|in:sh|out:jl|delim:auto|header:true                      \n> h;i:sh;s:{user:USER,pid:PID};o:jl;t:PID:i                                     \n```\n\n### Pretty printing csv\n`COMMAND`:\n* `h` says `INPUT` includes a header\n* `o:t` specifies the output format to be a pretty printed table\n```\nINPUT                                  │OUTPUT                                  \nName,Age,City                          │╒═══════════╤═══════╤════════╕          \nJames Joe,34,NYC                       ││ Name      │   Age │ City   │          \nJohn Doe,25,London                     │╞═══════════╪═══════╪════════╡          \n                                       ││ James Joe │    34 │ NYC    │          \n                                       │├───────────┼───────┼────────┤          \n                                       ││ John Doe  │    25 │ London │          \n                                       │╘═══════════╧═══════╧════════╛          \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \nvi-insert|COMMAND|live|in:c|out:t|delim:auto|header:true                        \n> h;o:t                                                                         \n```\n\n### Correcting bad input\n`COMMAND`:\n* `h` says `INPUT` includes a header\n* `t:Age:i/76/` provides a default value when the `Age` column cannot be parsed as integer\n```\nINPUT                                  │OUTPUT                                  \nName,Age,City                          │[[\'James Joe\', 34, \'NYC\'],              \nJames Joe,34,NYC                       │ [\'John Doe\', 76, \'London\'],            \nJohn Doe,Not a number,London           │ [\'Jane Row\', 24, \'Tel Aviv\']]          \nJane Row,24,Tel Aviv                   │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \nvi-insert|COMMAND|live|in:c|out:l|delim:auto|header:true                        \n> h;t:Age:i/76/                                                                 \n```\n\n### Interactive `jq`\n`COMMAND`:\n* `r` puts evaluation into raw mode where input is not assumed to be raw based\n* `o:jq` use the `jq` output and pass arguments to it wrapped with backticks.\n```\nINPUT                                  │OUTPUT                                  \n{"one": 1, "two": 2, "three": 3}       │{"o":1,"t1":2,"t2":3}                   \n{"one": 1.0, "two": 2.0, "three": 3.0} │{"o":1,"t1":2,"t2":3}                   \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \n                                       │                                        \nvi-insert|COMMAND|live|in:c|out:jq|delim:auto|header:false|raw:true             \n> r;o:jq`{o: .one, t1: .two, t2: .three}`                                       \n```\n\n## Usage\n`textomatic` is split into 3 parts:\n* `INPUT`: The input data that is to be transformed\n* `OUTPUT`: The result of applying the `COMMAND` on `INPUT`\n* `COMMAND`: The transformation logic using a succinct expression language described below\n    \nUse the `Tab` key to move between them.\n\n`INPUT` and `COMMAND` are edited using `vim` bindings.\n\n### `COMMAND` Expression Language\n`COMMAND` is composed of different parts separated by `;`, e.g.\n\n```\n> h;i:c;o:jl;s:[1,2]\n```\n\nThe above will be explained in detail later on but for now we can see it has 4 parts:\n* `h`: specifies that the input `csv` has a header\n* `i:c` specifies that the input is in fact a `csv`\n* `o:jl` specified that the output should be in jsonlines format\n* `s:[1,2]` specifies that the output should only include the first and\n            second columns from the input, in that order\n\nTo use a different expression separator, start the command with `:<SEP>`, e.g.\n```\n> :|h|i:c\n```\n\n#### Expressions\n\n##### The `h` expression (header)\nThe simplest expression. It is basically a flag denoting whether the input\nincludes headers. This is relevent for inputs like `csv`\n\n##### The `d` expression (delimiter)\nUsed by the `csv` input. In most cases, the delimiter can be automatically\ndeduced. In cases where it cannot, use `d`, e.g. to set a `,` delimiter:\n```\n> d:,\n```\n\nTo specify delimiters that are not easy to input, start the delimiter with\n`\\`, the remaining part will then be parsed as a python literal\n(wrapped in string), for example this will set the delimiter to the unicode\ncharacter `─` (U+2500):\n```\n> d:\\u2500\n```\n\n##### The `i` expression (input)\nUsed to specify the input format. Currently these are the available inputs:\n* `c` (`csv`, this is the default. The delimiter musn\'t be a `,` as the name may imply)\n* `jl` (jsonlines)\n* `sh` (shell, e.g. the output of `ps aux`)\n* `jq` (Using [jq](https://stedolan.github.io/jq/))\n\n##### The `o` expression (output)\nUsed to specify the output format. Currently these are the available outputs:\n* `l` (python literal, this is the default)\n* `j` (json)\n* `jl` (jsonlines)\n* `c` (csv)\n* `t` (pretty printed table)\n* `h` (table html)\n* `jq` (Using [jq](https://stedolan.github.io/jq/))\n\n##### The `t` expression (types)\nFor inputs with no clear types (e.g. csv/shell), all columns are initially assumed to\nbe strings. To modify types of different columns use `t`.\n\nThe types are:\n* `s` (string, the default)\n* `f` (float)\n* `i` (integer)\n* `b` (boolean, case insensitive `true/yes/y/on/1` will be parsed as `true`)\n* `j` (json, will JSON parse the column)\n* `l` (literal, will parse a python literal using `ast.literal_eval`)\n\nUsing positional syntax:\n```\n> t:i,i,b\n```\nIn the above:\n* the first 2 columns will be parsed as integers\n* the third column will be parsed as boolean\n* the rest will be strings\n\nUsing indexed syntax:\n```\n> t:1:i,3:f\n```\nIn the above:\n* the first column will be parsed as integer\n* the third column will be parsed as float\n* the rest will be strings\n\nUsing named syntax:\n```\n> t:col1:b,col4:i\n```\nIn the above, assuming the input contains headers:\n* the column named `col1` will be parsed as boolean\n* the column named `col4` will be parsed as integer\n* the rest will be strings\n\nOptional types:\n\nIf a certain value may be invalid, you can use `?` to\nmark it as optional, in this case, its value will be \nconverted to `null` when it is invalid:\n```\n> t:col1:i?,col4:i?\n```\n\nDefaults:\n\nIf you want the specify a value different than `null` for invalid entries\nuse the following syntax:\n```\n> t:col1:i/0/,col4:f/0.0/\n```\n\nThe value between the `/`\'s will be evaluated as a python literal.\n\n##### The `s` expression (structure)\nThe `s` expression is used to specify the structure of the `OUTPUT`.\nSome of the options are catered to the python output but they will fallback\nto a reasonable alternative for other outputs.\n\nSimple transformations:\n* `s:[]` - Each row will be a list in `OUTPUT`\n* `s:()` - Each row will be a tuple in `OUTPUT`\n* `s:{}` - Each row will be an object in `OUTPUT` (assumes input has headers)\n* `s:d()` - Same as `s:{}`\n* `s:s()` - Each row will be as set in `OUTPUT`\n\nComplex transformations:\n* `s:[1,2,col6]` - Each row will contain the first and second columns and a column\n                   named `col6`. Note that it is wrapped with `[]`. This only\n                   means the output row will be a list. You can just as well\n                   wrap it with `{}` to get objects e.g. `s:{1,2,col6}`.\n                   The different wrapping options are desribed in "Simple Transformations"\n                   of the previous section.\n* `s:{first:1,second:2}` - Each row will contain the first and second columns with\n                           The specified new headers (`first` and `second`)\n* `s:[-2,-1]` - Each row will contain the two last columns from `INPUT`\n* `s:{1,second:2}` - Column definitions can be mixed.\n\nNested transformations:\n* `s:[{1,2},{3,4}]` - Each row will contain two objects, the first object will\n                      contain the first and second columns, the second object\n                      will contain the third and fourth columns.\n\nNesting can be as complex as you wish and rules from previous sections\ncan be applied freely. As an overly complex example:\n```\n> s:{k1:1,k2:{2,three},k3:[{four,5},d(-4,s7:seven)],eight,k4:(one, two, (four, five)),s:s(1,1,1)}\n``` \n\nFetching values of nested data:\n* `s:[some_obj.key1.key2]` - Each row will contain a single nested value from\n                             the `some_obj` column. \n* `s:[some_obj.key1?.key2]` - Same as above, but don\'t fail if `key1` doesn\'t exist,\n                              instead, replace it with `null`.\n* `s:[some_obj.key1?.key2/100/]` - Same as above, but use `100` instead of `null`.\n* `s:[some_obj.key1.key2/100/]` - Default value without optional `?` is equivalent to\n                                  `s:[some_obj?.key1?.key2?/100/]`                               \n\nA caveat of using `//` for default values is that the default value cannot\ninclude `/`. This is mostly due to a very simple parser that is currently\nimplemented for the expression language.',
    'author': 'Dan Kilman',
    'author_email': 'dankilman@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/dankilman/textomatic',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'entry_points': entry_points,
    'python_requires': '>=3.8,<4.0',
}


setup(**setup_kwargs)
