1 /* 2 ------------------------------------------------------------------- 3 4 Copyright (C) 2014, Edwin van Leeuwen 5 6 This file is part of plotd plotting library. 7 8 Plotd is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 Plotd is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with Plotd. If not, see <http://www.gnu.org/licenses/>. 20 21 ------------------------------------------------------------------- 22 */ 23 24 module cli.options; 25 26 import std.conv : to; 27 import std.string : split; 28 29 import docopt : ArgValue; 30 31 version( unittest ) { 32 import std.algorithm : equal; 33 import std.stdio : writeln; 34 import docopt : docopt; 35 } 36 37 import cli.column; 38 39 /// Merge given associative arrays 40 V[K] merge( K, V )( V[K] aaBase, in V[K] aa ) { 41 foreach ( k, v; aa ) 42 aaBase[k] = v; 43 return aaBase; 44 } 45 46 /// 47 unittest { 48 auto aa1 = ["x" : 1.0, "y": 2.0]; 49 auto aa2 = ["y":3.0]; 50 assert( aa1.merge( aa2 ) == ["x" : 1.0, "y": 3.0] ); 51 aa2 = ["y":3.0, "z":4.0]; 52 assert( aa1.merge( aa2 ) == ["x" : 1.0, "y": 3.0, "z":4.0] ); 53 } 54 55 auto helpText = "Usage: plotcli [-f] [-o OUTPUT] [-d FORMAT] 56 57 Plotcli is a plotting program that will plot data from provided data streams (files). It will ignore any lines it doesn't understand, making it possible to feed it \"dirty\" streams/files. All options can also be provided within the stream by using the prefix #plotcli (e.g. #plotcli -d x,y). 58 59 Options: 60 -f Follow the stream, i.e. keep listening for new lines. 61 -d FORMAT String describing the content of each row. Different row formats supported: x, y and h, with h indication histogram data. For more information see Data format section. 62 -o OUTPUT Outputfile (without extension). 63 64 Data format: 65 Using -d it is possible to specify what each column in your data file represents. Supported formats are: 66 67 x,y The x and y coordinate for points 68 lx,ly Line data 69 h Histogram data 70 .. Extrapolate from previous options, i.e. x,y,.. -> x,y,x,y,.. 71 72 Examples: x,y,y or h,x,y. When there are more ys provided than xs (or vice versa) the last x will be matched to all remaining ys. 73 74 Data ids: plotcli by default does a good job of figuring out which x and y data belong together, but you can optionally provide an numeric id to make this completely clear. I.e. x1,y1. Data ids always need to directly follow the format type (before plot ids). 75 76 Plot ids: if you want to plot the data to different figures you can add a letter/name at the end: xa,ya or x1a,y1a. This plot id will be appended to the OUTPUT file name. 77 78 Extrapolatin (..): plotcli will try to extrapolate from your previous options. This also works for simple plot ids. I.e. if you want a separate histogram for each column: ha,hb,.. results in ha,hb,hc,hd,he etc. Other examples: y,.. -> y,y,y,y etc. x,y,y,.. -> x,y,y,y,y etc. 79 80 "; 81 82 /* Future options 83 84 --adaptive MODE (not adaptive, scrolling, full) First two need bounds or alternatively adaptive-cache for initial bounds 85 --adaptive-cache CACHESIZE (does it stop being adaptive after this or does it stop caching? Maybe combine with not adaptive or scrolling) 86 --bounds BOUNDS (minx,maxx,miny,maxy) sets default MODE to not 87 --image IMAGETYPE (pdf,png) 88 --xlabel XLABEL 89 --ylabel YLABEL 90 --debug Output lines that are not successfully parsed 91 92 Future Data formats: 93 hx,hy 2D Histogram data (Not supported yet) 94 95 You can also start a new plot by passing a new output file name in the stream (e.g. #plotcli -o newplot). 96 97 */ 98 99 struct Settings { 100 Formats formats; 101 string outputFile = "plotcli"; 102 bool follow = false; 103 } 104 105 unittest { 106 Settings settings; 107 assert( settings.formats.empty ); 108 assert( settings.outputFile == "plotcli" ); 109 } 110 111 Settings updateSettings( Settings settings, ArgValue[string] options ) { 112 if ( !options["-d"].isNull ) 113 { 114 settings.formats = parseDataFormat( options["-d"].to!string ); 115 } 116 if ( !options["-o"].isNull ) 117 settings.outputFile = options["-o"].to!string; 118 if ( options["-f"].isTrue ) 119 settings.follow = true; 120 return settings; 121 } 122 123 unittest { 124 Settings settings; 125 auto args = docopt(helpText, [], true, "plotcli"); 126 assert( args["-d"].isNull ); 127 settings = settings.updateSettings( 128 docopt(helpText, [], true, "plotcli") ); 129 assert( settings.formats.empty ); 130 assert( settings.outputFile == "plotcli" ); 131 132 settings = settings.updateSettings( 133 docopt(helpText, ["-d", "x,y"], true, "plotcli") ); 134 assert( settings.formats.front.mode == "x" ); 135 assert( settings.outputFile == "plotcli" ); 136 137 settings = settings.updateSettings( 138 docopt(helpText, ["-o", "name"], true, "plotcli") ); 139 assert( settings.outputFile == "name" ); 140 assert( settings.follow == false ); 141 142 settings = settings.updateSettings( 143 docopt(helpText, ["-f"], true, "plotcli") ); 144 assert( settings.follow == true ); 145 settings = settings.updateSettings( 146 docopt(helpText, ["-o", "name"], true, "plotcli") ); 147 assert( settings.follow == true ); 148 }