From 6c6993b4043416e5b58d0f57da35b9d82fd43aa7 Mon Sep 17 00:00:00 2001 From: nbedos Date: Sat, 14 Jul 2018 11:47:53 +0200 Subject: [PATCH 01/16] Proof of concept --- examples/awesome_js.svg | 1468 +++++++++++++++++++++++++++++++++++++++ fiddle/fiddle.css | 2 + fiddle/fiddle.js | 44 ++ fiddle/fiddle.svg | 27 + 4 files changed, 1541 insertions(+) create mode 100644 examples/awesome_js.svg create mode 100644 fiddle/fiddle.css create mode 100644 fiddle/fiddle.js create mode 100644 fiddle/fiddle.svg diff --git a/examples/awesome_js.svg b/examples/awesome_js.svg new file mode 100644 index 0000000..2190d50 --- /dev/null +++ b/examples/awesome_js.svg @@ -0,0 +1,1468 @@ + + + + + + + + + + + + + + + nico  + + ~ +  $  + +   + + + nico  + + ~ +  $  + + t +   + + + nico  + + ~ +  $  + + te + +   + + + nico  + + ~ +  $  + + ter + +   + + + nico  + + ~ +  $  + + term + +   + + + nico  + + ~ +  $  + + termt + +   + + + nico  + + ~ +  $  + + termto + +   + + + nico  + + ~ +  $  + + termtos + +   + + + nico  + + ~ +  $  + + termtosv + +   + + + nico  + + ~ +  $  + + + termtosvg + +   + + +   + + + nico  + + ~ +  $  + + f +   + + + nico  + + ~ +  $  + + fo + +   + + + nico  + + ~ +  $  + + for + +   + + + nico  + + ~ +  $  + + for  + +   + + + nico  + + ~ +  $  + + for i + +   + + + nico  + + ~ +  $  + + for i  + +   + + + nico  + + ~ +  $  + + for i i + +   + + + nico  + + ~ +  $  + + for i in + +   + + + nico  + + ~ +  $  + + + for i in  + +   + + + nico  + + ~ +  $  + + + for i in { + +   + + + nico  + + ~ +  $  + + + for i in {0 + +   + + + nico  + + ~ +  $  + + + for i in {0. + +   + + + nico  + + ~ +  $  + + + for i in {0.. + +   + + + nico  + + ~ +  $  + + + for i in {0..1 + +   + + + nico  + + ~ +  $  + + + for i in {0..10 + +   + + + nico  + + ~ +  $  + + + for i in {0..10} + +   + + + nico  + + ~ +  $  + + + for i in {0..10}; + +   + + + nico  + + ~ +  $  + + + for i in {0..10};  + +   + + + nico  + + ~ +  $  + + + for i in {0..10}; d + +   + + + nico  + + ~ +  $  + + + for i in {0..10}; do + +   + + + >  + +   + + + > e + +   + + + > ec + +   + + + > ech + +   + + + > echo + +   + + + > echo  + +   + + + > echo " + +   + + + + > echo "t + +   + + + + > echo "te + +   + + + > echo "ter +   + + + > echo "term +   + + + > echo "termt +   + + + > echo "termto +   + + + > echo "termtos +   + + + > echo "termtosv +   + + + > echo "termtosvg +   + + + > echo "termtosvg  +   + + + > echo "termtosvg i +   + + + > echo "termtosvg is +   + + + > echo "termtosvg is  +   + + + > echo "termtosvg is a +   + + + > echo "termtosvg is aw +   + + + > echo "termtosvg is awe +   + + + > echo "termtosvg is awes +   + + + > echo "termtosvg is aweso +   + + + > echo "termtosvg is awesom +   + + + > echo "termtosvg is awesome +   + + + > echo "termtosvg is awesome! +   + + + > echo "termtosvg is awesome!" +   + + + > d + +   + + + > do + +   + + + > don + +   + + + > done + +   + + + > done  + +   + + + > done | + +   + + + + > done |  + +   + + + + > done | l + +   + + + > done | lo +   + + + > done | lol +   + + + > done | lolc +   + + + > done | lolca +   + + + > done | lolcat +   + + + term + +   + + + termt + + + osvg is a + + we + + s +   + + + termt + + + osvg is a + + we + + so + +   + + + termt + + os + + + vg is awe + +   + + + nico  + + ~ +  $  + + + termtosvg + + + + + Recording started, enter "exit" command or Control-D to end + + + + nico  + + ~ +  $  + + + for i in {0..10}; do + + + + > echo "termtosvg is awesome!" + + + > done | lolcat + + + term + + t + + osvg is a + + wesome! + + + + t + e + + rmtosvg i + + + s awesome + + ! + + + termtosv + + + g is awes + + om + + e! + + + + termt + + + osvg is a + + we + + some! + + + + te + + rmtosvg i + + s  + + + awesome! + + + + termtosv + + g  + + + is awesome + + ! + + + termt + + os + + + vg is awes + + o + me! + + + + te + rm + + + tosvg is a + + w + esome! + + + + t + + ermtosvg i + + s + +  awesome! + + + + termtosv + + g +  is  + +   + + + nico  + + ~ +  $  + + e +   + + + nico  + + ~ +  $  + + ex + +   + + + nico  + + ~ +  $  + + exi + +   + + + nico  + + ~ +  $  + + exit + +   + + + termtosv + + g + +  is awesom + + e! + + + + termt + + o + + svg is awe + + some! + + + + nico  + + ~ +  $  + + exit + + + + exit + + + + + Recording ended, SVG animation is /tmp/termtosvg__20rwx67.svg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/fiddle/fiddle.css b/fiddle/fiddle.css new file mode 100644 index 0000000..d2a1ff4 --- /dev/null +++ b/fiddle/fiddle.css @@ -0,0 +1,2 @@ +svg { border: 1px solid #000; margin: 1.5em; } +.slidable { cursor: w-resize; } diff --git a/fiddle/fiddle.js b/fiddle/fiddle.js new file mode 100644 index 0000000..cdf3466 --- /dev/null +++ b/fiddle/fiddle.js @@ -0,0 +1,44 @@ +var price_chart = document.getElementsByTagName('svg')[0]; +var screen = price_chart.getElementsByTagName('svg')[0]; +var pt = price_chart.createSVGPoint(); + +console.log(price_chart) +console.log(screen) + +function mx(evt){ + pt.x = evt.clientX; + return pt.matrixTransform(price_chart.getScreenCTM().inverse()); +} + +// HTML elements +var slider_1 = document.querySelector('#slider_1'); +console.log(slider_1) + +var dragging = false; +slider_1.addEventListener('mousedown',function(evt){ + price_chart.pauseAnimations() + var offset = mx(evt); + dragging = true; + offset.x = slider_1.x.baseVal.value - offset.x; + var move = function(evt){ + var now = mx(evt); + //var x = offset.x + now.x; + var x = now.x; + var limitLower = 0; + var limitUpper = 300; + console.log(evt) + if ( x < limitLower || x > limitUpper ) { + return; + } + //slider_1.x.baseVal.value = x; + //x = Math.abs(x)*scale; + price_chart.setCurrentTime(10.0 * x / 300.0) + }; + + price_chart.addEventListener('mousemove',move,false); + document.documentElement.addEventListener('mouseup',function(){ + dragging = false; + price_chart.unpauseAnimations() + price_chart.removeEventListener('mousemove',move,false); + },false); +},false); diff --git a/fiddle/fiddle.svg b/fiddle/fiddle.svg new file mode 100644 index 0000000..0839ab5 --- /dev/null +++ b/fiddle/fiddle.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + From d9e085da7062e55f60549935314ee8f571175ed8 Mon Sep 17 00:00:00 2001 From: nbedos Date: Sun, 15 Jul 2018 19:28:03 +0200 Subject: [PATCH 02/16] Replace svgwrite by lxml --- examples/awesome.svg | 17 +- examples/colors.svg | 17 +- examples/htop.svg | 17 +- examples/ipython.svg | 17 +- examples/unittest.svg | 17 +- setup.py | 2 +- termtosvg/anim.py | 382 ++++++++++++++++++----------- termtosvg/data/templates/plain.svg | 40 +++ tests/test_anim.py | 153 ++++++++---- 9 files changed, 455 insertions(+), 207 deletions(-) create mode 100644 termtosvg/data/templates/plain.svg diff --git a/examples/awesome.svg b/examples/awesome.svg index a4bfbaa..95d55c9 100644 --- a/examples/awesome.svg +++ b/examples/awesome.svg @@ -1,4 +1,15 @@ - -nico ~ $  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termt nico ~ $ termto nico ~ $ termtos nico ~ $ termtosv nico ~ $ termtosvg  nico ~ $ f nico ~ $ fo nico ~ $ for nico ~ $ for  nico ~ $ for i nico ~ $ for i  nico ~ $ for i i nico ~ $ for i in nico ~ $ for i in  nico ~ $ for i in { nico ~ $ for i in {0 nico ~ $ for i in {0. nico ~ $ for i in {0.. nico ~ $ for i in {0..1 nico ~ $ for i in {0..10 nico ~ $ for i in {0..10} nico ~ $ for i in {0..10}; nico ~ $ for i in {0..10};  nico ~ $ for i in {0..10}; d nico ~ $ for i in {0..10}; do  > e > ec > ech > echo > echo  > echo " > echo "t > echo "te > echo "ter > echo "term > echo "termt > echo "termto > echo "termtos > echo "termtosv > echo "termtosvg > echo "termtosvg  > echo "termtosvg i > echo "termtosvg is > echo "termtosvg is  > echo "termtosvg is a > echo "termtosvg is aw > echo "termtosvg is awe > echo "termtosvg is awes > echo "termtosvg is aweso > echo "termtosvg is awesom > echo "termtosvg is awesome > echo "termtosvg is awesome! > echo "termtosvg is awesome!" > d > do > don > done > done  > done | > done |  > done | l > done | lo > done | lol > done | lolc > done | lolca > done | lolcat term termtosvg is awes termtosvg is aweso termtosvg is awe nico ~ $ termtosvgRecording started, enter "exit" command or Control-D to endnico ~ $ for i in {0..10}; do> echo "termtosvg is awesome!"> done | lolcattermtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg iawesome!termtosvis awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is  nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit termtosvg is awesome!termtosvg is awesome!nico ~ $ exitexitRecording ended, SVG animation is /tmp/termtosvg__20rwx67.svg \ No newline at end of file +.background {fill: #002b36}]]>nico ~ $  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termt nico ~ $ termto nico ~ $ termtos nico ~ $ termtosv nico ~ $ termtosvg  nico ~ $ f nico ~ $ fo nico ~ $ for nico ~ $ for  nico ~ $ for i nico ~ $ for i  nico ~ $ for i i nico ~ $ for i in nico ~ $ for i in  nico ~ $ for i in { nico ~ $ for i in {0 nico ~ $ for i in {0. nico ~ $ for i in {0.. nico ~ $ for i in {0..1 nico ~ $ for i in {0..10 nico ~ $ for i in {0..10} nico ~ $ for i in {0..10}; nico ~ $ for i in {0..10};  nico ~ $ for i in {0..10}; d nico ~ $ for i in {0..10}; do  > e > ec > ech > echo > echo  > echo " > echo "t > echo "te > echo "ter > echo "term > echo "termt > echo "termto > echo "termtos > echo "termtosv > echo "termtosvg > echo "termtosvg  > echo "termtosvg i > echo "termtosvg is > echo "termtosvg is  > echo "termtosvg is a > echo "termtosvg is aw > echo "termtosvg is awe > echo "termtosvg is awes > echo "termtosvg is aweso > echo "termtosvg is awesom > echo "termtosvg is awesome > echo "termtosvg is awesome! > echo "termtosvg is awesome!" > d > do > don > done > done  > done | > done |  > done | l > done | lo > done | lol > done | lolc > done | lolca > done | lolcat term termtosvg is awes termtosvg is aweso termtosvg is awe nico ~ $ termtosvgRecording started, enter "exit" command or Control-D to endnico ~ $ for i in {0..10}; do> echo "termtosvg is awesome!"> done | lolcattermtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg iawesome!termtosvis awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is  nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit termtosvg is awesome!termtosvg is awesome!nico ~ $ exitexitRecording ended, SVG animation is /tmp/termtosvg__20rwx67.svg + \ No newline at end of file diff --git a/examples/colors.svg b/examples/colors.svg index 9d5ab3e..cf1782f 100644 --- a/examples/colors.svg +++ b/examples/colors.svg @@ -1,4 +1,15 @@ - -nico ~ $  nico ~ $ ~ nico ~ $ ~/ nico ~ $ ~/s nico ~ $ ~/sc nico ~ $ ~/scr nico ~ $ ~/scri nico ~ $ ~/scrip nico ~ $ ~/scripts/ nico ~ $ ~/scripts/c nico ~ $ ~/scripts/co nico ~ $ ~/scripts/col nico ~ $ ~/scripts/colo nico ~ $ ~/scripts/colors nico ~ $ ~/scripts/colors_ nico ~ $ ~/scripts/colors_2 nico ~ $ ~/scripts/colors_25 nico ~ $ ~/scripts/colors_256 nico ~ $ ~/scripts/colors_256.sh                                                                                                                                                                nico ~ $ ~/scripts/t nico ~ $ ~/scripts/tr nico ~ $ ~/scripts/tru nico ~ $ ~/scripts/true_colors. nico ~ $ ~/scripts/true_colors.s nico ~ $ ~/scripts/true_colors.sh nico ~ $ ~/scripts/true_colors.sh  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termm nico ~ $ termmt nico ~ $ termm                                                                    nico ~ $ term                                                                     nico ~ $ termt                                                                    nico ~ $ termtosvg                                                                nico ~ $ termtosvg                                                                nico ~ $ termtosvg -                                                              nico ~ $ termtosvg --                                                             nico ~ $ termtosvg --h                                                            nico ~ $ termtosvg --he                                                           nico ~ $ termtosvg --hel                                                          nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help | l                                                     nico ~ $ termtosvg --help | lo                                                    nico ~ $ termtosvg --help | loc                                                   nico ~ $ termtosvg --help | locl                                                  nico ~ $ termtosvg --help | lol                                                   nico ~ $ termtosvg --help | lolc                                                  nico ~ $ termtosvg --help | lolca                                                 nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [-- nico ~ $ ~/scripts/colors_256.sh                                                                 nico ~ $ ~/scripts/true_colors.sh                                                                              nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [--theme THEME] [--help Record a ter usage: termtosvg [output_file] [--theme THEME] [--help] [--verbose]Record a terminal session and render an SVG anim Record a terminal session and render an SVG animation on the flypositional    output_file    optiona positional arguments:  output_file    optional filename of the SVG animation; if missi                    output_file    optional filename of the SVG animation; if missing, a random                 filename will be automatically gene                    filename will be automatically generatedoptional arguments:  -h, --help     show this help    -h, --help     show this help message and exit  --theme THEME  color theme used to render the te                            classic-dark, clas   --theme THEME  color theme used to render the terminal session (circus,                 classic-dark, classic-light, dracula,                                 material, monokai, solari                  classic-dark, classic-light, dracula, isotope, marrakesh,                 material, monokai, solarized-dark, solarized-light, zenburn)                  material, monokai, solarized-dark, solarized-light, zenburn)  -v, --verbose  increase log mess See also 'termtosvg re   -v, --verbose  increase log messages verbositySee also 'termtosvg record --help' and 'termtosvg See also 'termtosvg record --help' and 'termtosvg render --help'nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit nico ~ $ exitexit \ No newline at end of file +.background {fill: #002b36}]]>nico ~ $  nico ~ $ ~ nico ~ $ ~/ nico ~ $ ~/s nico ~ $ ~/sc nico ~ $ ~/scr nico ~ $ ~/scri nico ~ $ ~/scrip nico ~ $ ~/scripts/ nico ~ $ ~/scripts/c nico ~ $ ~/scripts/co nico ~ $ ~/scripts/col nico ~ $ ~/scripts/colo nico ~ $ ~/scripts/colors nico ~ $ ~/scripts/colors_ nico ~ $ ~/scripts/colors_2 nico ~ $ ~/scripts/colors_25 nico ~ $ ~/scripts/colors_256 nico ~ $ ~/scripts/colors_256.sh                                                                                                                                                                nico ~ $ ~/scripts/t nico ~ $ ~/scripts/tr nico ~ $ ~/scripts/tru nico ~ $ ~/scripts/true_colors. nico ~ $ ~/scripts/true_colors.s nico ~ $ ~/scripts/true_colors.sh nico ~ $ ~/scripts/true_colors.sh  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termm nico ~ $ termmt nico ~ $ termm                                                                    nico ~ $ term                                                                     nico ~ $ termt                                                                    nico ~ $ termtosvg                                                                nico ~ $ termtosvg                                                                nico ~ $ termtosvg -                                                              nico ~ $ termtosvg --                                                             nico ~ $ termtosvg --h                                                            nico ~ $ termtosvg --he                                                           nico ~ $ termtosvg --hel                                                          nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help | l                                                     nico ~ $ termtosvg --help | lo                                                    nico ~ $ termtosvg --help | loc                                                   nico ~ $ termtosvg --help | locl                                                  nico ~ $ termtosvg --help | lol                                                   nico ~ $ termtosvg --help | lolc                                                  nico ~ $ termtosvg --help | lolca                                                 nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [-- nico ~ $ ~/scripts/colors_256.sh                                                                 nico ~ $ ~/scripts/true_colors.sh                                                                              nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [--theme THEME] [--help Record a ter usage: termtosvg [output_file] [--theme THEME] [--help] [--verbose]Record a terminal session and render an SVG anim Record a terminal session and render an SVG animation on the flypositional    output_file    optiona positional arguments:  output_file    optional filename of the SVG animation; if missi                    output_file    optional filename of the SVG animation; if missing, a random                 filename will be automatically gene                    filename will be automatically generatedoptional arguments:  -h, --help     show this help    -h, --help     show this help message and exit  --theme THEME  color theme used to render the te                            classic-dark, clas   --theme THEME  color theme used to render the terminal session (circus,                 classic-dark, classic-light, dracula,                                 material, monokai, solari                  classic-dark, classic-light, dracula, isotope, marrakesh,                 material, monokai, solarized-dark, solarized-light, zenburn)                  material, monokai, solarized-dark, solarized-light, zenburn)  -v, --verbose  increase log mess See also 'termtosvg re   -v, --verbose  increase log messages verbositySee also 'termtosvg record --help' and 'termtosvg See also 'termtosvg record --help' and 'termtosvg render --help'nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit nico ~ $ exitexit + \ No newline at end of file diff --git a/examples/htop.svg b/examples/htop.svg index 94bcf1c..9443331 100644 --- a/examples/htop.svg +++ b/examples/htop.svg @@ -1,4 +1,15 @@ - -nico ~ $  nico ~ $ h nico ~ $ ht nico ~ $ hto nico ~ $ htop nico ~ $ htop nico ~ $ htop                                                                                    1  [|||||||||||||||||||||||||100.0%]   Tasks: 391 running2  [0.0%]   Load average: 0.33 0.32 0.30 3  [0.0%]   Uptime: 09:45:004  [0.0%]29184 nico20   0 21412  4192  3420 160.  0.1  0:00.04 │  │              └    1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash3  [|||5.3%]   Uptime: 09:45:0227104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27173 nico20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash2  [|||7.4%]   Load average: 0.33 0.32 0.30 27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico20   0 21412  4192  3420  0.7  0.1  0:00.05 │  │              └  1  [||||                       6.5%]   Tasks: 391 running2  [|||7.4%]   Load average: 0.31 0.32 0.30 3  [|||5.3%]   Uptime: 09:45:034  [||5.3%]27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us29184 nico       20   0 21412  4192  3420 R  0.7  0.1  0:00.05 │  │              └23028 nico20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash  1  [||                         6.0%]   Tasks: 391 running2  [|||6.5%]   Load average: 0.31 0.32 0.30 3  [|||8.4%]   Uptime: 09:45:034  [|||6.4%]Mem[|||||||||||||||||   2.45G/7.74G]Swp[0K/0K]  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.87 │  │  └─ python /us27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.06 │  │              └23028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        F1Help  F2Setup F3SearchF4FilterF5SortedF6CollapF7Nice -F8Nice +F9Kill  F10Quit    3  [|||8.4%]   Uptime: 09:45:0423028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto  759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user    710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user   3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service 3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la3  [|||8.4%]   Uptime: 09:45:05  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       1  [|||                        7.6%]   Tasks: 391 running2  [|||5.2%]   Load average: 0.31 0.32 0.30 3  [|||6.4%]   Uptime: 09:45:054  [|| 5.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.45 ├─ compton -b        711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s3  [|||6.4%]   Uptime: 09:45:06  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        1  [||||                       9.8%]   Tasks: 392 running2  [|||7.3%]   Load average: 0.31 0.32 0.30 3  [|||7.4%]   Uptime: 09:45:074  [|||6.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s29184 nico       20   0 21412  4192  3420 R  1.2  0.1  0:00.10 │  │              └29184 nico       20   0 21412  4192  3420  1.2  0.1  0:00.10 │  │              └3  [|||7.4%]   Uptime: 09:45:0829180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth29180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us2  [|||7.3%]   Load average: 0.28 0.31 0.30 27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us  1  [|||||                     12.7%]   Tasks: 391 running2  [|||8.2%]   Load average: 0.28 0.31 0.30 3  [||||||13.9%]   Uptime: 09:45:084  [|||||13.2%]23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.88 │  │  └─ python /us29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.11 │  │              └3  [||||||13.9%]   Uptime: 09:45:0923027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            3  [||||||13.9%]   Uptime: 09:45:1027170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us3  [|||    8.6%]   Uptime: 09:45:10  1  [||||                       8.8%]   Tasks: 391 running2  [||||9.6%]   Load average: 0.28 0.31 0.30 3  [|||    8.6%]   Uptime: 09:45:114  [|||   7.5%]29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.12 │  │              └nico ~ $                                                                           nico ~ $ e                                                                         nico ~ $ ex                                                                        nico ~ $ exi                                                                                                                                                           1  [|||                        5.0%]   Tasks: 392 running2  [||  5.4%]   Load average: 0.28 0.31 0.30 3  [||||  10.8%]   Uptime: 09:45:124  [|||   7.0%]29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.8  0.1  0:00.14 │  │              └nico ~ $ exit                                                                      nico ~ $ exit                                                                      exit \ No newline at end of file +.background {fill: #002b36}]]>nico ~ $  nico ~ $ h nico ~ $ ht nico ~ $ hto nico ~ $ htop nico ~ $ htop nico ~ $ htop                                                                                    1  [|||||||||||||||||||||||||100.0%]   Tasks: 391 running2  [0.0%]   Load average: 0.33 0.32 0.30 3  [0.0%]   Uptime: 09:45:004  [0.0%]29184 nico20   0 21412  4192  3420 160.  0.1  0:00.04 │  │              └    1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash3  [|||5.3%]   Uptime: 09:45:0227104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27173 nico20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash2  [|||7.4%]   Load average: 0.33 0.32 0.30 27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico20   0 21412  4192  3420  0.7  0.1  0:00.05 │  │              └  1  [||||                       6.5%]   Tasks: 391 running2  [|||7.4%]   Load average: 0.31 0.32 0.30 3  [|||5.3%]   Uptime: 09:45:034  [||5.3%]27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us29184 nico       20   0 21412  4192  3420 R  0.7  0.1  0:00.05 │  │              └23028 nico20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash  1  [||                         6.0%]   Tasks: 391 running2  [|||6.5%]   Load average: 0.31 0.32 0.30 3  [|||8.4%]   Uptime: 09:45:034  [|||6.4%]Mem[|||||||||||||||||   2.45G/7.74G]Swp[0K/0K]  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.87 │  │  └─ python /us27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.06 │  │              └23028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        F1Help  F2Setup F3SearchF4FilterF5SortedF6CollapF7Nice -F8Nice +F9Kill  F10Quit    3  [|||8.4%]   Uptime: 09:45:0423028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto  759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user    710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user   3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service 3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la3  [|||8.4%]   Uptime: 09:45:05  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       1  [|||                        7.6%]   Tasks: 391 running2  [|||5.2%]   Load average: 0.31 0.32 0.30 3  [|||6.4%]   Uptime: 09:45:054  [|| 5.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.45 ├─ compton -b        711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s3  [|||6.4%]   Uptime: 09:45:06  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        1  [||||                       9.8%]   Tasks: 392 running2  [|||7.3%]   Load average: 0.31 0.32 0.30 3  [|||7.4%]   Uptime: 09:45:074  [|||6.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s29184 nico       20   0 21412  4192  3420 R  1.2  0.1  0:00.10 │  │              └29184 nico       20   0 21412  4192  3420  1.2  0.1  0:00.10 │  │              └3  [|||7.4%]   Uptime: 09:45:0829180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth29180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us2  [|||7.3%]   Load average: 0.28 0.31 0.30 27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us  1  [|||||                     12.7%]   Tasks: 391 running2  [|||8.2%]   Load average: 0.28 0.31 0.30 3  [||||||13.9%]   Uptime: 09:45:084  [|||||13.2%]23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.88 │  │  └─ python /us29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.11 │  │              └3  [||||||13.9%]   Uptime: 09:45:0923027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            3  [||||||13.9%]   Uptime: 09:45:1027170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us3  [|||    8.6%]   Uptime: 09:45:10  1  [||||                       8.8%]   Tasks: 391 running2  [||||9.6%]   Load average: 0.28 0.31 0.30 3  [|||    8.6%]   Uptime: 09:45:114  [|||   7.5%]29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.12 │  │              └nico ~ $                                                                           nico ~ $ e                                                                         nico ~ $ ex                                                                        nico ~ $ exi                                                                                                                                                           1  [|||                        5.0%]   Tasks: 392 running2  [||  5.4%]   Load average: 0.28 0.31 0.30 3  [||||  10.8%]   Uptime: 09:45:124  [|||   7.0%]29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.8  0.1  0:00.14 │  │              └nico ~ $ exit                                                                      nico ~ $ exit                                                                      exit + \ No newline at end of file diff --git a/examples/ipython.svg b/examples/ipython.svg index bb1369b..cc4d4bf 100644 --- a/examples/ipython.svg +++ b/examples/ipython.svg @@ -1,4 +1,15 @@ - -nico ~ $  nico ~ $ i nico ~ $ ip nico ~ $ ipy nico ~ $ ipyt nico ~ $ ipyth nico ~ $ ipytho nico ~ $ ipython  In [1]:                                                                           In [1]: i                                                                         In [1]: im                                                                        In [1]: imp                                                                       In [1]: impo                                                                      In [1]: impor                                                                     In [1]: import                                                                    In [1]: import                                                                    In [1]: import t                                                                  In [1]: import ti                                                                 In [1]: import tim                                                                In [1]: import time                                                               In [2]:                                                                           In [2]: f                                                                         In [2]: fo                                                                        In [2]: for                                                                       In [2]: for                                                                       In [2]: for i                                                                     In [2]: for i                                                                     In [2]: for i i                                                                   In [2]: for i in                                                                  In [2]: for i in                                                                  In [2]: for i in r                                                                In [2]: for i in ra                                                               In [2]: for i in ran                                                              In [2]: for i in rang                                                             In [2]: for i in range                                                            In [2]: for i in range(                                                           In [2]: for i in range(4                                                          In [2]: for i in range(40                                                         In [2]: for i in range(40                                                       In [2]: for i in range(40):                                                          ...:         ...:     p    ...:     pr    ...:     pri    ...:     prin    ...:     print    ...:     print(    ...:     print('    ...:     print('=    ...:     print('='    ...:     print('='     ...:     print('=' *    ...:     print('=' *     ...:     print('=' * i    ...:     print('=' * i     ...:     print('=' * i +    ...:     print('=' * i +     ...:     print('=' * i + '    ...:     print('=' * i + '+    ...:     print('=' * i + '+'    ...:     print('=' * i + '+'     ...:     print('=' * i + '+'      ...:     print('=' * i + '+' +    ...:     print('=' * i + '+' +     ...:     print('=' * i + '+' + '    ...:     print('=' * i + '+' + '=    ...:     print('=' * i + '+' + '='    ...:     print('=' * i + '+' + '='     ...:     print('=' * i + '+' + '=' *    ...:     print('=' * i + '+' + '=' *     ...:     print('=' * i + '+' + '=' * (    ...:     print('=' * i + '+' + '=' * (4    ...:     print('=' * i + '+' + '=' * (40    ...:     print('=' * i + '+' + '=' * (40     ...:     print('=' * i + '+' + '=' * (40-    ...:     print('=' * i + '+' + '=' * (40-i    ...:     print('=' * i + '+' + '=' * (40-i   ...:     print('=' * i + '+' + '=' * (40-i)   ...:     t    ...:     ti    ...:     tim    ...:     time    ...:     time.    ...:     time.s  time.sleep       time.strptime       ...:     time.sleep  time.sleep       time.strptime     time.strftime    time.struct_time  <unknown>    ...:     time.sleep(    ...:     time.sleep(0    ...:     time.sleep(0.    ...:     time.sleep(0.1    ...:     time.sleep(0.1                                   In [2]: for i in range(40):                                                          ...:     print('=' * i + '+' + '=' * (40-i))   ...:     time.sleep(0.1)   ...:                                                                                                                                                  nico ~ $ ipythonPython 3.6.5 (default, May 11 2018, 04:00:52) Type 'copyright', 'credits' or 'license' for more informationIPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.In [1]: import time                                                                                                                                                    ...:                                        +========================================                                         =+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=In [3]:                                                                           In [3]: e                                                                         In [3]: ex                                                                        In [3]: exi                                                                       In [3]: exit                                                                      nico ~ $                                                                          nico ~ $ e                                                                        nico ~ $ ex                                                                       nico ~ $ exi                                                                      In [3]: exit                                                                      nico ~ $ exit                                                                     nico ~ $ exit                                                                     exit \ No newline at end of file +.background {fill: #002b36}]]>nico ~ $  nico ~ $ i nico ~ $ ip nico ~ $ ipy nico ~ $ ipyt nico ~ $ ipyth nico ~ $ ipytho nico ~ $ ipython  In [1]:                                                                           In [1]: i                                                                         In [1]: im                                                                        In [1]: imp                                                                       In [1]: impo                                                                      In [1]: impor                                                                     In [1]: import                                                                    In [1]: import                                                                    In [1]: import t                                                                  In [1]: import ti                                                                 In [1]: import tim                                                                In [1]: import time                                                               In [2]:                                                                           In [2]: f                                                                         In [2]: fo                                                                        In [2]: for                                                                       In [2]: for                                                                       In [2]: for i                                                                     In [2]: for i                                                                     In [2]: for i i                                                                   In [2]: for i in                                                                  In [2]: for i in                                                                  In [2]: for i in r                                                                In [2]: for i in ra                                                               In [2]: for i in ran                                                              In [2]: for i in rang                                                             In [2]: for i in range                                                            In [2]: for i in range(                                                           In [2]: for i in range(4                                                          In [2]: for i in range(40                                                         In [2]: for i in range(40                                                       In [2]: for i in range(40):                                                          ...:         ...:     p    ...:     pr    ...:     pri    ...:     prin    ...:     print    ...:     print(    ...:     print('    ...:     print('=    ...:     print('='    ...:     print('='     ...:     print('=' *    ...:     print('=' *     ...:     print('=' * i    ...:     print('=' * i     ...:     print('=' * i +    ...:     print('=' * i +     ...:     print('=' * i + '    ...:     print('=' * i + '+    ...:     print('=' * i + '+'    ...:     print('=' * i + '+'     ...:     print('=' * i + '+'      ...:     print('=' * i + '+' +    ...:     print('=' * i + '+' +     ...:     print('=' * i + '+' + '    ...:     print('=' * i + '+' + '=    ...:     print('=' * i + '+' + '='    ...:     print('=' * i + '+' + '='     ...:     print('=' * i + '+' + '=' *    ...:     print('=' * i + '+' + '=' *     ...:     print('=' * i + '+' + '=' * (    ...:     print('=' * i + '+' + '=' * (4    ...:     print('=' * i + '+' + '=' * (40    ...:     print('=' * i + '+' + '=' * (40     ...:     print('=' * i + '+' + '=' * (40-    ...:     print('=' * i + '+' + '=' * (40-i    ...:     print('=' * i + '+' + '=' * (40-i   ...:     print('=' * i + '+' + '=' * (40-i)   ...:     t    ...:     ti    ...:     tim    ...:     time    ...:     time.    ...:     time.s  time.sleep       time.strptime       ...:     time.sleep  time.sleep       time.strptime     time.strftime    time.struct_time  <unknown>    ...:     time.sleep(    ...:     time.sleep(0    ...:     time.sleep(0.    ...:     time.sleep(0.1    ...:     time.sleep(0.1                                   In [2]: for i in range(40):                                                          ...:     print('=' * i + '+' + '=' * (40-i))   ...:     time.sleep(0.1)   ...:                                                                                                                                                  nico ~ $ ipythonPython 3.6.5 (default, May 11 2018, 04:00:52) Type 'copyright', 'credits' or 'license' for more informationIPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.In [1]: import time                                                                                                                                                    ...:                                        +========================================                                         =+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=In [3]:                                                                           In [3]: e                                                                         In [3]: ex                                                                        In [3]: exi                                                                       In [3]: exit                                                                      nico ~ $                                                                          nico ~ $ e                                                                        nico ~ $ ex                                                                       nico ~ $ exi                                                                      In [3]: exit                                                                      nico ~ $ exit                                                                     nico ~ $ exit                                                                     exit + \ No newline at end of file diff --git a/examples/unittest.svg b/examples/unittest.svg index ea918c6..77147cd 100644 --- a/examples/unittest.svg +++ b/examples/unittest.svg @@ -1,4 +1,15 @@ - -nico ~/termtosvg $  nico ~/termtosvg $ m nico ~/termtosvg $ ma nico ~/termtosvg $ mak nico ~/termtosvg $ make nico ~/termtosvg $ make  nico ~/termtosvg $ make t nico ~/termtosvg $ make te nico ~/termtosvg $ make tes nico ~/termtosvg $ make test nico ~/termtosvg $ make tests  nico ~/termtosvg $ make tests(test -d .venv || python -m venv .venv). .venv/bin/activate && \    pip install -U -e .[dev]Obtaining file:///home/nico/termtosvgRequirement already up-to-date: setuptools in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: pyte in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: python-xlib in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: svgwrite in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: coverage in ./.venv/lib/python3.6/site-packages (fRequirement already up-to-date: twine in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: wheel in ./.venv/lib/python3.6/site-packages (fromRequirement already up-to-date: wcwidth in ./.venv/lib/python3.6/site-packages (from pyte->termtosvg==0.1.0)Requirement already up-to-date: six>=1.10.0 in ./.venv/lib/python3.6/site-packages (from python-xlib->termtosvg==0.1.0)Requirement already up-to-date: pyparsing>=2.0.1 in ./.venv/lib/python3.6/site-packages (from svgwrite->termtosvg==0.1.0)Requirement already up-to-date: requests!=2.15,!=2.16,>=2.5.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: requests-toolbelt>=0.8.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: tqdm>=4.14 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: pkginfo>=1.4.2 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: certifi>=2017.4.17 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: idna<2.8,>=2.5 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: urllib3<1.24,>=1.21.1 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: chardet<3.1.0,>=3.0.2 in ./.venv/lib/python3.6/sitInstalling collected packages: termtosvg  Found existing installation: termtosvg 0.1.0    Uninstalling termtosvg-0.1.0:      Successfully uninstalled termtosvg-0.1.0  Running setup.py develop for termtosvgSuccessfully installed termtosvgYou are using pip version 9.0.3, however version 10.0.1 is available.You should consider upgrading via the 'pip install --upgrade pip' command.    pip freeze && \    coverage run --branch --source termtosvg -m unittest -v && \    coverage report && \    coverage htmlpython-xlib==0.23pytz==2018.4requests==2.19.1requests-toolbelt==0.8.0rsa==3.4.2six==1.11.0svgwrite==1.1.12-e git+git@github.com:nbedos/termtosvg.git@dab7f522c126e9938e896d023d8be453f0dcf1b9#egg=termtosvgtinydb==3.9.0.post1tinyrecord==0.1.5tox==3.0.0tqdm==4.23.4twine==1.11.0urllib3==1.23virtualenv==16.0.0wcwidth==0.1.7wrapt==1.10.11test_main (tests.test___main__.TestMain) ...  test_main (tests.test___main__.TestMain) ... Recording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_3vqhnplh.castRecording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_s7tgsv75.castRendering startedRendering ended, SVG animation is /tmp/termtosvg_wts11qev.svgRendering ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgRendering ended, SVG animation is /tmp/termtosvg_i8zp1z7w.svgLogging to /tmp/termtosvg.logRecording ended, SVG animation is /tmp/termtosvg_fkz0r2vk.svgRecording ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgoktest_parse (tests.test___main__.TestMain) ...  test_parse (tests.test___main__.TestMain) ... oktest__render_characters (tests.test_anim.TestAnim) ... oktest__render_line_bg_colors (tests.test_anim.TestAnim) ...  test__render_line_bg_colors (tests.test_anim.TestAnim) ... oktest_from_pyte (tests.test_anim.TestAnim) ... oktest_render_animation (tests.test_anim.TestAnim) ...  test_render_animation (tests.test_anim.TestAnim) ... oktest_serialize_css_dict (tests.test_anim.TestAnim) ... oktest_AsciiCastEvent (tests.test_asciicast.TestAsciicast) ... oktest_AsciiCastHeader (tests.test_asciicast.TestAsciicast) ... oktest_from_json (tests.test_asciicast.TestAsciicast) ...  test_from_json (tests.test_asciicast.TestAsciicast) ... oktest_from_xresources (tests.test_asciicast.TestAsciicast) ...  test_from_xresources (tests.test_asciicast.TestAsciicast) ... oktest_to_json (tests.test_asciicast.TestAsciicast) ... oktest__group_by_time (tests.test_term.TestTerm) ... oktest__record (tests.test_term.TestTerm) ...  test__record (tests.test_term.TestTerm) ... oktest_default_themes (tests.test_term.TestTerm) ...  test_default_themes (tests.test_term.TestTerm) ... oktest_get_configuration (tests.test_term.TestTerm) ...  test_get_configuration (tests.test_term.TestTerm) ... oktest_record (tests.test_term.TestTerm) ...  test_record (tests.test_term.TestTerm) ... oktest_replay (tests.test_term.TestTerm) ...  test_replay (tests.test_term.TestTerm) ... ok----------------------------------------------------------------------Ran 18 tests in 5.164sOKnico ~/termtosvg $ e nico ~/termtosvg $ ex nico ~/termtosvg $ exi Name                     Stmts   Miss Branch BrPart  Cover----------------------------------------------------------termtosvg/__init__.py        0      0      0      0   100%termtosvg/__main__.py      106      4     38      4    94%termtosvg/anim.py          146      3     60      3    97%termtosvg/asciicast.py      93      6     38      3    93%termtosvg/term.py          192     13     66      8    91%TOTAL                      537     26    202     18    94%nico ~/termtosvg $ exit nico ~/termtosvg $ exitexit \ No newline at end of file +.background {fill: #002b36}]]>nico ~/termtosvg $  nico ~/termtosvg $ m nico ~/termtosvg $ ma nico ~/termtosvg $ mak nico ~/termtosvg $ make nico ~/termtosvg $ make  nico ~/termtosvg $ make t nico ~/termtosvg $ make te nico ~/termtosvg $ make tes nico ~/termtosvg $ make test nico ~/termtosvg $ make tests  nico ~/termtosvg $ make tests(test -d .venv || python -m venv .venv). .venv/bin/activate && \    pip install -U -e .[dev]Obtaining file:///home/nico/termtosvgRequirement already up-to-date: setuptools in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: pyte in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: python-xlib in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: svgwrite in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: coverage in ./.venv/lib/python3.6/site-packages (fRequirement already up-to-date: twine in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: wheel in ./.venv/lib/python3.6/site-packages (fromRequirement already up-to-date: wcwidth in ./.venv/lib/python3.6/site-packages (from pyte->termtosvg==0.1.0)Requirement already up-to-date: six>=1.10.0 in ./.venv/lib/python3.6/site-packages (from python-xlib->termtosvg==0.1.0)Requirement already up-to-date: pyparsing>=2.0.1 in ./.venv/lib/python3.6/site-packages (from svgwrite->termtosvg==0.1.0)Requirement already up-to-date: requests!=2.15,!=2.16,>=2.5.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: requests-toolbelt>=0.8.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: tqdm>=4.14 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: pkginfo>=1.4.2 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: certifi>=2017.4.17 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: idna<2.8,>=2.5 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: urllib3<1.24,>=1.21.1 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: chardet<3.1.0,>=3.0.2 in ./.venv/lib/python3.6/sitInstalling collected packages: termtosvg  Found existing installation: termtosvg 0.1.0    Uninstalling termtosvg-0.1.0:      Successfully uninstalled termtosvg-0.1.0  Running setup.py develop for termtosvgSuccessfully installed termtosvgYou are using pip version 9.0.3, however version 10.0.1 is available.You should consider upgrading via the 'pip install --upgrade pip' command.    pip freeze && \    coverage run --branch --source termtosvg -m unittest -v && \    coverage report && \    coverage htmlpython-xlib==0.23pytz==2018.4requests==2.19.1requests-toolbelt==0.8.0rsa==3.4.2six==1.11.0svgwrite==1.1.12-e git+git@github.com:nbedos/termtosvg.git@dab7f522c126e9938e896d023d8be453f0dcf1b9#egg=termtosvgtinydb==3.9.0.post1tinyrecord==0.1.5tox==3.0.0tqdm==4.23.4twine==1.11.0urllib3==1.23virtualenv==16.0.0wcwidth==0.1.7wrapt==1.10.11test_main (tests.test___main__.TestMain) ...  test_main (tests.test___main__.TestMain) ... Recording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_3vqhnplh.castRecording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_s7tgsv75.castRendering startedRendering ended, SVG animation is /tmp/termtosvg_wts11qev.svgRendering ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgRendering ended, SVG animation is /tmp/termtosvg_i8zp1z7w.svgLogging to /tmp/termtosvg.logRecording ended, SVG animation is /tmp/termtosvg_fkz0r2vk.svgRecording ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgoktest_parse (tests.test___main__.TestMain) ...  test_parse (tests.test___main__.TestMain) ... oktest__render_characters (tests.test_anim.TestAnim) ... oktest__render_line_bg_colors (tests.test_anim.TestAnim) ...  test__render_line_bg_colors (tests.test_anim.TestAnim) ... oktest_from_pyte (tests.test_anim.TestAnim) ... oktest_render_animation (tests.test_anim.TestAnim) ...  test_render_animation (tests.test_anim.TestAnim) ... oktest_serialize_css_dict (tests.test_anim.TestAnim) ... oktest_AsciiCastEvent (tests.test_asciicast.TestAsciicast) ... oktest_AsciiCastHeader (tests.test_asciicast.TestAsciicast) ... oktest_from_json (tests.test_asciicast.TestAsciicast) ...  test_from_json (tests.test_asciicast.TestAsciicast) ... oktest_from_xresources (tests.test_asciicast.TestAsciicast) ...  test_from_xresources (tests.test_asciicast.TestAsciicast) ... oktest_to_json (tests.test_asciicast.TestAsciicast) ... oktest__group_by_time (tests.test_term.TestTerm) ... oktest__record (tests.test_term.TestTerm) ...  test__record (tests.test_term.TestTerm) ... oktest_default_themes (tests.test_term.TestTerm) ...  test_default_themes (tests.test_term.TestTerm) ... oktest_get_configuration (tests.test_term.TestTerm) ...  test_get_configuration (tests.test_term.TestTerm) ... oktest_record (tests.test_term.TestTerm) ...  test_record (tests.test_term.TestTerm) ... oktest_replay (tests.test_term.TestTerm) ...  test_replay (tests.test_term.TestTerm) ... ok----------------------------------------------------------------------Ran 18 tests in 5.164sOKnico ~/termtosvg $ e nico ~/termtosvg $ ex nico ~/termtosvg $ exi Name                     Stmts   Miss Branch BrPart  Cover----------------------------------------------------------termtosvg/__init__.py        0      0      0      0   100%termtosvg/__main__.py      106      4     38      4    94%termtosvg/anim.py          146      3     60      3    97%termtosvg/asciicast.py      93      6     38      3    93%termtosvg/term.py          192     13     66      8    91%TOTAL                      537     26    202     18    94%nico ~/termtosvg $ exit nico ~/termtosvg $ exitexit + \ No newline at end of file diff --git a/setup.py b/setup.py index 18c7889..096b673 100644 --- a/setup.py +++ b/setup.py @@ -46,9 +46,9 @@ ] }, install_requires=[ + 'lxml', 'pyte', 'setuptools', - 'svgwrite' ], extras_require={ 'dev': [ diff --git a/termtosvg/anim.py b/termtosvg/anim.py index 8bbb64e..78f1612 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -4,16 +4,13 @@ from itertools import groupby from typing import Dict, List, Iterable, Iterator, Union, Tuple, Any +import pkg_resources import pyte.graphics import pyte.screens -import svgwrite.animate -import svgwrite.container -import svgwrite.path -import svgwrite.shapes -import svgwrite.text +from lxml import etree # Ugliest hack: Replace the first 16 colors rgb values by their names so that termtosvg can -# distinguish FG_BG_256[0] (which defaults to black #000000 but can be styled with e.g. Xresources) +# distinguish FG_BG_256[0] (which defaults to black #000000 but can be styled with themes) # from FG_BG_256[16] (which is also black #000000 but should be displayed as is). colors = ['black', 'red', 'green', 'brown', 'blue', 'magenta', 'cyan', 'white'] brightcolors = ['bright{}'.format(color) for color in colors] @@ -22,6 +19,10 @@ logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) +# Id for the very last SVG animation. This is used to make the first animations start when the +# last one ends (animation looping) +LAST_ANIMATION_ID = 'anim_last' + _CharacterCell = namedtuple('_CharacterCell', ['text', 'color', 'background_color', 'bold']) _CharacterCell.__doc__ = 'Representation of a character cell' _CharacterCell.text.__doc__ = 'Text content of the cell' @@ -91,84 +92,102 @@ def from_pyte(cls, char, palette): CharacterCellRecord = Union[CharacterCellConfig, CharacterCellLineEvent] -def _render_line_bg_colors(screen_line, height, line_height, cell_width, background_color): - # type: (Dict[int, CharacterCell], float, float) -> List[svgwrite.shapes.Rect] - def make_rectangle(group: List[int]) -> svgwrite.shapes.Rect: - x = group[0] * cell_width - y = height - sx = len(group) * cell_width - sy = line_height - args = { - 'insert': (x, y), - 'size': (sx, sy), - 'fill': screen_line[group[0]].background_color - } - return svgwrite.shapes.Rect(**args) +class ConsecutiveWithSameAttributes: + """Callable to be used as a key for itertools.groupby to group together consecutive elements + of a list with the same attributes""" + def __init__(self, attributes): + self.group_index = None + self.last_index = None + self.attributes = attributes + self.last_key_attributes = None + + def __call__(self, arg): + index, obj = arg + key_attributes = {name: getattr(obj, name) for name in self.attributes} + if self.last_index != index - 1 or self.last_key_attributes != key_attributes: + self.group_index = index + self.last_index = index + self.last_key_attributes = key_attributes + return self.group_index, key_attributes + + +def make_rect_tag(column, length, height, cell_width, cell_height, background_color): + # type: (int, int, int, int, int, str) -> etree.ElementBase + attributes = { + 'x': str(column * cell_width), + 'y': str(height), + 'width': str(length * cell_width), + 'height': str(cell_height), + 'fill': background_color + } + rect_tag = etree.Element('rect', attributes) + return rect_tag - group = [] - groups = [] - cols = {col for col in screen_line if screen_line[col].background_color is not None} - for index in sorted(cols): - group.append(index) - if index + 1 not in screen_line or \ - screen_line[index].background_color != screen_line[index + 1].background_color: - if screen_line[index].background_color != background_color: - groups.append(group) - group = [] - rectangles = [make_rectangle(group) for group in groups] - return rectangles +def _render_line_bg_colors(screen_line, height, cell_height, cell_width, default_bg_color): + # type: (Dict[int, CharacterCell], int, int, int) -> List[etree.ElementBase] + """Return a list of 'rect' tags representing the background of 'screen_line' + If consecutive cells have the same background color, a single 'rect' tag is returned for all + these cells. + If a cell background uses default_bg_color, no 'rect' will be generated for this cell since + the default background is always displayed. -def _render_characters(screen_line, height, cell_width): - # type: (Dict[int, CharacterCell], float) -> List[svgwrite.text.Tspan] - """Render a screen of the terminal as a list of SVG text elements + :param screen_line: Mapping between column numbers and CharacterCells + :param height: Vertical position of the line on the screen in pixels + :param cell_height: Height of the a character cell in pixels + :param cell_width: Width of a character cell in pixels + :param default_bg_color: Default background color + """ + non_default_bg_cells = [(index, cell) for (index, cell) in sorted(screen_line.items()) + if cell.background_color != default_bg_color] - Characters with the same attributes (color) are grouped together in a - single text element. + key = ConsecutiveWithSameAttributes(['background_color']) + rect_tags = [make_rect_tag(column, len(list(group)), height, cell_width, cell_height, + attributes['background_color']) + for (column, attributes), group in groupby(non_default_bg_cells, key)] - :param screen_line: Mapping between positions on the row and characters - :param height: Vertical position of the line - :return: List of SVG text elements - """ + return rect_tags - def make_text(group: List[int]) -> svgwrite.text.Text: - text = ''.join(screen_line[c].text for c in group) - attributes = { - 'text': text.replace(' ', u'\u00A0'), - 'x': [str(group[0] * cell_width)], - 'textLength': len(group) * cell_width, - 'lengthAdjust': 'spacingAndGlyphs', - 'fill': screen_line[group[0]].color - } - if screen_line[group[0]].bold: - attributes['font-weight'] = 'bold' - return svgwrite.text.Text(**attributes) - group = [] - groups = [] - cols = {col for col in screen_line if screen_line[col].background_color is not None} - for col in sorted(cols): - group.append(col) - if col + 1 not in screen_line or \ - screen_line[col].color != screen_line[col+1].color: - groups.append(group) - group = [] +def make_text_tag(column, attributes, text, cell_width): + # type: (List[Tuple[int, CharacterCell]], Dict[str, str], str, int) -> etree.ElementBase + text_tag_attributes = { + 'x': str(column * cell_width), + 'textLength': str(len(text) * cell_width), + 'lengthAdjust': 'spacingAndGlyphs', + 'fill': attributes['color'] + } + if attributes['bold']: + text_tag_attributes['font-weight'] = 'bold' - texts = [make_text(group) for group in groups] - return texts + text_tag = etree.Element('text', text_tag_attributes) + # Replace usual spaces with unbreakable spaces so that indenting the SVG does not mess up + # the whole animation; this is somewhat better than the 'white-space: pre' CSS option + text_tag.text = text.replace(' ', u'\u00A0') + return text_tag -def render_animation(records, filename, font, font_size=14, cell_width=8, cell_height=17, end_pause=1): - # type: (Iterable[CharacterCellRecord], str, str, int, int, int, int) -> None - if end_pause <= 0: - raise ValueError('Invalid end_pause (must be > 0): "{}"'.format(end_pause)) +def _render_characters(screen_line, cell_width): + # type: (Dict[int, CharacterCell], int) -> List[etree.ElementBase] + """Return a list of 'text' elements representing the line of the screen - if not isinstance(records, Iterator): - records = iter(records) + Consecutive characters with the same styling attributes (text color and font weight) are + grouped together in a single text element. - header = next(records) + :param screen_line: Mapping between column numbers and characters + :param cell_width: Width of a character cell in pixels + """ + line = [(col, char) for (col, char) in sorted(screen_line.items())] + key = ConsecutiveWithSameAttributes(['color', 'bold']) + text_tags = [make_text_tag(column, attributes, ''.join(c.text for _, c in group), cell_width) + for (column, attributes), group in groupby(line, key)] + + return text_tags + +def build_style_tag(font, font_size, background_color): + # type: (str, int, str) -> etree.ElementBase css = { # Apply this style to each and every element since we are using coordinates that # depend on the size of the font @@ -181,91 +200,162 @@ def render_animation(records, filename, font, font_size=14, cell_width=8, cell_h 'dominant-baseline': 'text-before-edge', }, '.background': { - 'fill': header.background_color, + 'fill': background_color, }, } - width = header.width * cell_width - height = header.height * cell_height - - dwg = svgwrite.Drawing(filename, (width, height), debug=True) - dwg.defs.add(dwg.style(_serialize_css_dict(css))) - args = { - 'insert': (0, 0), - 'size': ('100%', '100%'), - 'class': 'background' + style_attributes = { + 'type': "text/css" + } + style_tag = etree.Element('style', style_attributes) + style_tag.text = etree.CDATA(_serialize_css_dict(css)) + return style_tag + + +_BG_RECT_TAG_ATTRIBUTES = { + 'class': 'background', + 'height': '100%', + 'width': '100%', + 'x': '0', + 'y': '0' +} +BG_RECT_TAG = etree.Element('rect', _BG_RECT_TAG_ATTRIBUTES) + + +def make_animated_group(records, time, duration, cell_height, cell_width, default_bg_color, defs): + # type: (Iterable[CharacterCellLineEvent], int, int, int, int, str, Dict[str, etree.ElementBase]) -> Tuple[etree.ElementBase, Dict[str, etree.ElementBase]] + """Return a group element containing an SVG version of the provided records. This group is + animated, that is to say displayede on the screen and then removed according to the timing + information provided by the caller. + + :param records: List of lines that should be included in the group + :param time: Time the group should appear on the screen (milliseconds) + :param duration: Duration of the appearance on the screen (milliseconds) + :param cell_height: Height of a character cell in pixels + :param cell_width: Width of a character cell in pixels + :param default_bg_color: Default background color + :param defs: Existing definitions + :return: A tuple consisting of the animated group and the new definitions + """ + animation_group_tag = etree.Element('g', attrib={'display': 'none'}) + new_definitions = {} + for event_record in records: + # Background elements + rect_tags = _render_line_bg_colors(screen_line=event_record.line, + height=event_record.row * cell_height, + cell_height=cell_height, + cell_width=cell_width, + default_bg_color=default_bg_color) + for tag in rect_tags: + animation_group_tag.append(tag) + + # Group text elements for the current line into text_group_tag + text_group_tag = etree.Element('g') + text_tags = _render_characters(event_record.line, cell_width) + for tag in text_tags: + text_group_tag.append(tag) + + # Find or create a definition for text_group_tag + text_group_tag_str = etree.tostring(text_group_tag) + if text_group_tag_str in defs: + group_id = defs[text_group_tag_str].attrib['id'] + elif text_group_tag_str in new_definitions: + group_id = new_definitions[text_group_tag_str].attrib['id'] + else: + group_id = 'g{}'.format(len(defs) + len(new_definitions) + 1) + assert group_id not in defs.values() and group_id not in new_definitions.values() + text_group_tag.attrib['id'] = group_id + new_definitions[text_group_tag_str] = text_group_tag + + # Add a reference to the definition of text_group_tag with a 'use' tag + use_attributes = { + '{http://www.w3.org/1999/xlink}href': '#{}'.format(group_id), + 'y': str(event_record.row * cell_height), + } + use_tag = etree.Element('use', use_attributes) + animation_group_tag.append(use_tag) + + # Finally, add an animation tag so that the whole group goes from 'display: none' to + # 'display: inline' at the time the line should appear on the screen + if time == 0: + # Animations starting at 0ms should also start when the last animation ends (looping) + begin_time = '0ms; {id}.end'.format(id=LAST_ANIMATION_ID) + else: + begin_time = '{time}ms; {id}.end+{time}ms'.format(time=time, id=LAST_ANIMATION_ID) + attributes = { + 'attributeName': 'display', + 'from': 'inline', + 'to': 'inline', + 'begin': begin_time, + 'dur': '{}ms'.format(duration), + 'fill': 'remove', } - r = svgwrite.shapes.Rect(**args) - dwg.add(r) - def by_time(record: CharacterCellRecord) -> Tuple[int, int]: - return record.time, record.duration + animation = etree.Element('animate', attributes) + animation_group_tag.append(animation) - row_animations = {} - definitions = {} - last_animation_id_str = 'anim_last' - animation = None - for animation_id, (key, record_group) in enumerate(groupby(records, key=by_time)): - line_time, line_duration = key - frame = svgwrite.container.Group(display='none') - - animation_begin = None - animation_id_str = 'anim_{}'.format(animation_id) - for event_record in record_group: - height = event_record.row * cell_height - rects = _render_line_bg_colors(event_record.line, - height, - cell_height, - cell_width, - header.background_color) - for rect in rects: - frame.add(rect) - - g = svgwrite.container.Group() - for text in _render_characters(event_record.line, height, cell_width): - g.add(text) - - # Define this line or reuse the existing definition - g_str = g.tostring() - if g_str in definitions: - group_id = definitions[g_str] - else: - group_id = len(definitions) + 1 - assert group_id not in definitions - definitions[g_str] = group_id - g.attribs['id'] = group_id - dwg.defs.add(g) - - frame.add(svgwrite.container.Use('#{}'.format(group_id), y=height)) - - # If the current row has already been animated, chain the current animation and the - # last one - if animation_begin is None and event_record.row in row_animations: - row_anim_id, row_anim_end = row_animations[event_record.row] - offset = line_time - row_anim_end - animation_begin = '{}.end+{}ms'.format(row_anim_id, offset) - - row_animations[event_record.row] = (animation_id_str, line_time + line_duration) - - if animation_begin is None: - animation_begin = '{}ms;{}.end+{}ms'.format(line_time, last_animation_id_str, line_time) - - extra = { - 'begin': animation_begin, - 'dur': '{}ms'.format(line_duration), - 'from': 'inline', - 'to': 'inline', - 'fill': 'remove', - 'id': animation_id_str - } + return animation_group_tag, new_definitions + + +def render_animation(records, filename, font, font_size=14, cell_width=8, cell_height=17): + root = _render_animation(records, font, font_size, cell_width, cell_height) + with open(filename, 'wb') as f: + f.write(etree.tostring(root)) + + +def _render_animation(records, font, font_size, cell_width, cell_height): + # type: (Iterable[CharacterCellRecord], str, int, int, int) -> etree.ElementBase + with pkg_resources.resource_stream(__name__, 'data/templates/plain.svg') as bytestream: + tree = etree.parse(bytestream) - animation = svgwrite.animate.Animate('display', **extra) - frame.add(animation) + # Get a SVG template + root = tree.getroot() + svg_screen_tag = root.find('.//{http://www.w3.org/2000/svg}svg[@id="screen"]') + if svg_screen_tag is None: + raise ValueError('Missing tag: ...') - dwg.add(frame) + for child in svg_screen_tag.getchildren(): + svg_screen_tag.remove(child) - animation.attribs['id'] = last_animation_id_str - dwg.save() + # Reader header record and add the corresponding information to the SVG + if not isinstance(records, Iterator): + records = iter(records) + header = next(records) + + def_tag = etree.SubElement(svg_screen_tag, 'defs') + style_tag = build_style_tag(font, font_size, header.background_color) + def_tag.append(style_tag) + svg_screen_tag.append(BG_RECT_TAG) + + # Process event records + def by_time(record: CharacterCellRecord) -> Tuple[int, int]: + return record.time, record.duration + + definitions = {} + last_animated_group = None + for (line_time, line_duration), record_group in groupby(records, key=by_time): + animated_group, new_defs = make_animated_group(records=record_group, + time=line_time, + duration=line_duration, + cell_height=cell_height, + cell_width=cell_width, + default_bg_color=header.background_color, + defs=definitions) + definitions.update(new_defs) + for definition in new_defs.values(): + def_tag.append(definition) + + svg_screen_tag.append(animated_group) + last_animated_group = animated_group + + # Add id attribute to the last 'animate' tag so that it can be refered to by the first + # animations (enables animation looping) + if last_animated_group is not None: + animate_tags = last_animated_group.findall('animate') + assert len(animate_tags) == 1 + animate_tags.pop().attrib['id'] = LAST_ANIMATION_ID + + return root def _serialize_css_dict(css): diff --git a/termtosvg/data/templates/plain.svg b/termtosvg/data/templates/plain.svg new file mode 100644 index 0000000..9e5eadf --- /dev/null +++ b/termtosvg/data/templates/plain.svg @@ -0,0 +1,40 @@ + + + + Plain template + No terminal UI, no controls, nothing but the screen of the terminal. + + + + + + + + termtosvg is awesome! + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/test_anim.py b/tests/test_anim.py index 36b3d2a..1175fc2 100644 --- a/tests/test_anim.py +++ b/tests/test_anim.py @@ -1,8 +1,9 @@ -import os import tempfile import unittest +from collections import namedtuple import pyte.screens +from lxml import etree from termtosvg import anim @@ -60,7 +61,21 @@ def test_from_pyte(self): with self.subTest(case=pyte_char): self.assertEqual(anim.CharacterCell.from_pyte(pyte_char, palette), cell_char) - def test__render_line_bg_colors(self): + def test_serialize_css_dict(self): + css = { + 'text': { + 'font-family': 'Dejavu Sans Mono', + 'font-style': 'normal', + 'font-size': '14px', + 'fill': '#839496' + }, + '.red': { + 'fill': '#dc322f' + } + } + anim._serialize_css_dict(css) + + def test__render_line_bg_colors_xml(self): cell_width = 8 screen_line = { 0: anim.CharacterCell('A', 'black', 'red', False), @@ -76,25 +91,29 @@ def test__render_line_bg_colors(self): } rectangles = anim._render_line_bg_colors(screen_line=screen_line, - height=0, - line_height=1, - cell_width=cell_width, - background_color='black') - rect_0, rect_3, rect_4, rect_6, rect_8, rect_9 = sorted(rectangles, - key=lambda r: r.attribs['x']) - - self.assertEqual(rect_0.attribs['x'], 0) - self.assertEqual(rect_0.attribs['width'], 16) - self.assertEqual(rect_0.attribs['fill'], 'red') - self.assertEqual(rect_3.attribs['x'], 24) - self.assertEqual(rect_3.attribs['width'], 8) - self.assertEqual(rect_4.attribs['x'], 32) - self.assertEqual(rect_6.attribs['x'], 48) - self.assertEqual(rect_6.attribs['width'], 16) - self.assertEqual(rect_6.attribs['fill'], 'blue') - self.assertEqual(rect_8.attribs['x'], 64) - self.assertEqual(rect_8.attribs['fill'], 'green') - self.assertEqual(rect_9.attribs['x'], 72) + height=0, + cell_height=1, + cell_width=cell_width, + default_bg_color='black') + + def key(r): + return r.attrib['x'] + + rect_0, rect_3, rect_4, rect_6, rect_8, rect_9 = sorted(rectangles, key=key) + + self.assertEqual(rect_0.attrib['x'], '0') + self.assertEqual(rect_0.attrib['width'], '16') + self.assertEqual(rect_0.attrib['height'], '1') + self.assertEqual(rect_0.attrib['fill'], 'red') + self.assertEqual(rect_3.attrib['x'], '24') + self.assertEqual(rect_3.attrib['width'], '8') + self.assertEqual(rect_4.attrib['x'], '32') + self.assertEqual(rect_6.attrib['x'], '48') + self.assertEqual(rect_6.attrib['width'], '16') + self.assertEqual(rect_6.attrib['fill'], 'blue') + self.assertEqual(rect_8.attrib['x'], '64') + self.assertEqual(rect_8.attrib['fill'], 'green') + self.assertEqual(rect_9.attrib['x'], '72') def test__render_characters(self): screen_line = { @@ -111,35 +130,77 @@ def test__render_characters(self): with self.subTest(case='Content'): cell_width = 8 - texts = anim._render_characters(screen_line, 1.23, cell_width) + texts = anim._render_characters(screen_line, cell_width) sorted_texts = sorted(texts, key=lambda x: x.text) [text_a, text_bc, text_defg, text_h, text_space] = sorted_texts self.assertEqual(text_a.text, 'A') - self.assertEqual(text_a.attribs['fill'], 'red') - self.assertEqual(text_a.attribs['x'], '0') + self.assertEqual(text_a.attrib['fill'], 'red') + self.assertEqual(text_a.attrib['x'], '0') self.assertEqual(text_bc.text, 'BC') - self.assertEqual(text_bc.attribs['fill'], 'blue') - self.assertEqual(text_bc.attribs['x'], '8') + self.assertEqual(text_bc.attrib['fill'], 'blue') + self.assertEqual(text_bc.attrib['x'], '8') self.assertEqual(text_defg.text, 'DEFG') - self.assertEqual(text_defg.attribs['fill'], 'green') - self.assertEqual(text_defg.attribs['x'], '56') + self.assertEqual(text_defg.attrib['fill'], 'green') + self.assertEqual(text_defg.attrib['x'], '56') + + + def test_build_style_tag(self): + style_tag = anim.build_style_tag('Roboto', 14, 'blue') + + def test_ConsecutiveWithSameAttributes(self): + testClass = namedtuple('testClass', ['field1', 'field2']) + test_cases = [ + (0, testClass('a', 'b')), + (2, testClass('a', 'b')), + (3, testClass('a', 'b')), + (4, testClass('b', 'b')), + (5, testClass('b', 'a')), + (10, testClass('c', 'd')), + (11, testClass('c', 'd')), + ] - def test_serialize_css_dict(self): - css = { - 'text': { - 'font-family': 'Dejavu Sans Mono', - 'font-style': 'normal', - 'font-size': '14px', - 'fill': '#839496' - }, - '.red': { - 'fill': '#dc322f' - } - } - anim._serialize_css_dict(css) + expected_results = [ + (0, {'field1': 'a', 'field2': 'b'}), + (2, {'field1': 'a', 'field2': 'b'}), + (2, {'field1': 'a', 'field2': 'b'}), + (4, {'field1': 'b', 'field2': 'b'}), + (5, {'field1': 'b', 'field2': 'a'}), + (10, {'field1': 'c', 'field2': 'd'}), + (10, {'field1': 'c', 'field2': 'd'}), + ] + + key = anim.ConsecutiveWithSameAttributes(['field1', 'field2']) + for case, result in zip(test_cases, expected_results): + with self.subTest(case=case): + self.assertEqual(key(case), result) + + def test_make_animated_group(self): + def line(i): + chars = [anim.CharacterCell(c, '#123456', '#789012', False) for c in 'line{}'.format(i)] + return dict(enumerate(chars)) + + records = [ + anim.CharacterCellLineEvent(1, line(1), None, None), + anim.CharacterCellLineEvent(2, line(2), None, None), + anim.CharacterCellLineEvent(3, line(3), None, None), + anim.CharacterCellLineEvent(4, line(4), None, None), + # Definition reuse + anim.CharacterCellLineEvent(5, line(4), None, None), + ] - def test_render_animation(self): + group, new_defs = anim.make_animated_group(records=records, + time=10, + duration=1, + cell_width=8, + cell_height=17, + default_bg_color='black', + defs={}) + from lxml import etree + print(etree.tostring(group, pretty_print=True).decode('utf-8')) + print(new_defs) + + def test__render_animation(self): def line(i): chars = [anim.CharacterCell(c, '#123456', '#789012', False) for c in 'line{}'.format(i)] return dict(enumerate(chars)) @@ -155,7 +216,9 @@ def line(i): # Override line for animation chaining anim.CharacterCellLineEvent(5, line(6), 300, 60), ] + svg_root = anim._render_animation(records, 'DejaVu Sans Mono', 14, 8, 17) - _, filename = tempfile.mkstemp(prefix='termtosvg_') - anim.render_animation(records, filename, 'DejaVu Sans Mono') - os.remove(filename) + _, filename = tempfile.mkstemp(prefix='termtosvg_', suffix='.svg') + with open(filename, 'wb') as f: + print(filename) + f.write(etree.tostring(svg_root)) \ No newline at end of file From 990d01386ce635171023aa66585ee3643684316c Mon Sep 17 00:00:00 2001 From: nbedos Date: Sun, 15 Jul 2018 22:56:30 +0200 Subject: [PATCH 03/16] Make file SVG 1.1 compliant --- termtosvg/data/templates/plain.svg | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/termtosvg/data/templates/plain.svg b/termtosvg/data/templates/plain.svg index 9e5eadf..75157d3 100644 --- a/termtosvg/data/templates/plain.svg +++ b/termtosvg/data/templates/plain.svg @@ -17,24 +17,24 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 9683c6063ac6560ea5893892c3cd3a807bdd11e4 Mon Sep 17 00:00:00 2001 From: nbedos Date: Sun, 15 Jul 2018 22:57:18 +0200 Subject: [PATCH 04/16] Setup DTD validation for SVG 1.1 --- termtosvg/anim.py | 25 +- termtosvg/data/svg11-flat-20110816.dtd | 5664 ++++++++++++++++++++++++ tests/test_anim.py | 26 +- 3 files changed, 5710 insertions(+), 5 deletions(-) create mode 100644 termtosvg/data/svg11-flat-20110816.dtd diff --git a/termtosvg/anim.py b/termtosvg/anim.py index 78f1612..1c1f1a9 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -222,6 +222,23 @@ def build_style_tag(font, font_size, background_color): BG_RECT_TAG = etree.Element('rect', _BG_RECT_TAG_ATTRIBUTES) +def validate_svg(svg_file): + """Validate an SVG file against the latest version of SVG 1.1 Document Type Definition""" + with pkg_resources.resource_stream(__name__, 'data/svg11-flat-20110816.dtd') as bstream: + dtd = etree.DTD(bstream) + + try: + tree = etree.parse(svg_file) + root = tree.getroot() + is_valid = dtd.validate(root) + except etree.Error as exc: + raise ValueError('Invalid SVG file') from exc + + if not is_valid: + reason = dtd.error_log.filter_from_errors()[0] + raise ValueError('Invalid SVG file: {}'.format(reason)) + + def make_animated_group(records, time, duration, cell_height, cell_width, default_bg_color, defs): # type: (Iterable[CharacterCellLineEvent], int, int, int, int, str, Dict[str, etree.ElementBase]) -> Tuple[etree.ElementBase, Dict[str, etree.ElementBase]] """Return a group element containing an SVG version of the provided records. This group is @@ -242,10 +259,10 @@ def make_animated_group(records, time, duration, cell_height, cell_width, defaul for event_record in records: # Background elements rect_tags = _render_line_bg_colors(screen_line=event_record.line, - height=event_record.row * cell_height, - cell_height=cell_height, - cell_width=cell_width, - default_bg_color=default_bg_color) + height=event_record.row * cell_height, + cell_height=cell_height, + cell_width=cell_width, + default_bg_color=default_bg_color) for tag in rect_tags: animation_group_tag.append(tag) diff --git a/termtosvg/data/svg11-flat-20110816.dtd b/termtosvg/data/svg11-flat-20110816.dtd new file mode 100644 index 0000000..72e733b --- /dev/null +++ b/termtosvg/data/svg11-flat-20110816.dtd @@ -0,0 +1,5664 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + +]]> + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + +]]> + + + +]]> + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + + + +]]> + + + +]]> + + + + + + +]]> + + + +]]> + + + + + + +]]> + + + +]]> + + +]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]]> + + + +]]> + + +]]> + + + diff --git a/tests/test_anim.py b/tests/test_anim.py index 1175fc2..67e44c3 100644 --- a/tests/test_anim.py +++ b/tests/test_anim.py @@ -1,7 +1,9 @@ +import io import tempfile import unittest from collections import namedtuple +import pkg_resources import pyte.screens from lxml import etree @@ -221,4 +223,26 @@ def line(i): _, filename = tempfile.mkstemp(prefix='termtosvg_', suffix='.svg') with open(filename, 'wb') as f: print(filename) - f.write(etree.tostring(svg_root)) \ No newline at end of file + f.write(etree.tostring(svg_root)) + + def test_validate_svg(self): + failure_test_cases = [ + '', + '', + '', + '', + None, + ] + for case in failure_test_cases: + with self.subTest(case=case): + with self.assertRaises(ValueError): + anim.validate_svg(io.StringIO(case)) + + success_test_cases = [ + pkg_resources.resource_stream('termtosvg', 'data/templates/plain.svg') + ] + + for bstream in success_test_cases: + with self.subTest(case=bstream): + anim.validate_svg(bstream) + From 4298bcf3618d8b06c55fcf124061a6c88186a98d Mon Sep 17 00:00:00 2001 From: nbedos Date: Sun, 15 Jul 2018 23:31:57 +0200 Subject: [PATCH 05/16] Replace pkg_resources by pkgutil --- MANIFEST.in | 3 +++ __main__.py | 6 ++++++ scripts/termtosvg | 6 ++++++ setup.py | 21 +++++---------------- termtosvg/anim.py | 11 ++++++----- termtosvg/config.py | 6 ++---- termtosvg/{__main__.py => main.py} | 5 ----- tests/test_anim.py | 10 +++++----- tests/{test___main__.py => test_main.py} | 6 +++--- 9 files changed, 36 insertions(+), 38 deletions(-) create mode 100644 MANIFEST.in create mode 100644 __main__.py create mode 100644 scripts/termtosvg rename termtosvg/{__main__.py => main.py} (99%) rename tests/{test___main__.py => test_main.py} (96%) diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..9441fc6 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +include LICENSE +include scripts/* +recursive-include termtosvg/data * diff --git a/__main__.py b/__main__.py new file mode 100644 index 0000000..37c6676 --- /dev/null +++ b/__main__.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import termtosvg.main + +if __name__ == '__main__': + termtosvg.main.main() diff --git a/scripts/termtosvg b/scripts/termtosvg new file mode 100644 index 0000000..37c6676 --- /dev/null +++ b/scripts/termtosvg @@ -0,0 +1,6 @@ +#!/usr/bin/env python3 + +import termtosvg.main + +if __name__ == '__main__': + termtosvg.main.main() diff --git a/setup.py b/setup.py index 096b673..2d44e69 100644 --- a/setup.py +++ b/setup.py @@ -5,8 +5,9 @@ setup( name='termtosvg', version='0.4.0', - licence='BSD 3-clause license', + license='BSD 3-clause license', author='Nicolas Bedos', + author_email='nicolas.bedos@gmail.com', description='Record terminal sessions as SVG animations', long_description='A Linux terminal recorder written in Python ' 'which renders your command line sessions as ' @@ -25,30 +26,18 @@ 'Topic :: Terminals' ], packages=['termtosvg'], - package_data={ - '': [ - 'LICENSE' - ], - 'termtosvg': [ - 'data/LICENSE.md', - 'data/termtosvg.ini', - ] - }, py_modules=[ 'termtosvg.anim', 'termtosvg.asciicast', 'termtosvg.config', + 'termtosvg.main', 'termtosvg.term', ], - entry_points={ - 'console_scripts': [ - 'termtosvg=termtosvg.__main__:main' - ] - }, + scripts=['scripts/termtosvg'], + include_package_data=True, install_requires=[ 'lxml', 'pyte', - 'setuptools', ], extras_require={ 'dev': [ diff --git a/termtosvg/anim.py b/termtosvg/anim.py index 1c1f1a9..dbe9914 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -1,10 +1,11 @@ +import io import logging import os +import pkgutil from collections import namedtuple from itertools import groupby from typing import Dict, List, Iterable, Iterator, Union, Tuple, Any -import pkg_resources import pyte.graphics import pyte.screens from lxml import etree @@ -224,8 +225,8 @@ def build_style_tag(font, font_size, background_color): def validate_svg(svg_file): """Validate an SVG file against the latest version of SVG 1.1 Document Type Definition""" - with pkg_resources.resource_stream(__name__, 'data/svg11-flat-20110816.dtd') as bstream: - dtd = etree.DTD(bstream) + data = pkgutil.get_data(__name__, 'data/svg11-flat-20110816.dtd') + dtd = etree.DTD(io.BytesIO(data)) try: tree = etree.parse(svg_file) @@ -322,8 +323,8 @@ def render_animation(records, filename, font, font_size=14, cell_width=8, cell_h def _render_animation(records, font, font_size, cell_width, cell_height): # type: (Iterable[CharacterCellRecord], str, int, int, int) -> etree.ElementBase - with pkg_resources.resource_stream(__name__, 'data/templates/plain.svg') as bytestream: - tree = etree.parse(bytestream) + data = pkgutil.get_data(__name__, 'data/templates/plain.svg') + tree = etree.parse(io.BytesIO(data)) # Get a SVG template root = tree.getroot() diff --git a/termtosvg/config.py b/termtosvg/config.py index 9a8f585..c2c6a6d 100644 --- a/termtosvg/config.py +++ b/termtosvg/config.py @@ -1,18 +1,16 @@ import configparser import logging import os +import pkgutil from typing import Union, Dict -import pkg_resources - import termtosvg.asciicast as asciicast - logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) PKG_CONF_PATH = os.path.join('data', 'termtosvg.ini') -DEFAULT_CONFIG = pkg_resources.resource_string(__name__, PKG_CONF_PATH).decode('utf-8') +DEFAULT_CONFIG = pkgutil.get_data(__name__, PKG_CONF_PATH).decode('utf-8') class CaseInsensitiveDict(dict): diff --git a/termtosvg/__main__.py b/termtosvg/main.py similarity index 99% rename from termtosvg/__main__.py rename to termtosvg/main.py index a061b41..786d6a6 100644 --- a/termtosvg/__main__.py +++ b/termtosvg/main.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import argparse import logging import sys @@ -197,7 +196,3 @@ def main(args=None, input_fileno=None, output_fileno=None): for handler in logger.handlers: handler.close() - - -if __name__ == '__main__': - main() diff --git a/tests/test_anim.py b/tests/test_anim.py index 67e44c3..a4f6138 100644 --- a/tests/test_anim.py +++ b/tests/test_anim.py @@ -3,7 +3,7 @@ import unittest from collections import namedtuple -import pkg_resources +import pkgutil import pyte.screens from lxml import etree @@ -239,10 +239,10 @@ def test_validate_svg(self): anim.validate_svg(io.StringIO(case)) success_test_cases = [ - pkg_resources.resource_stream('termtosvg', 'data/templates/plain.svg') + pkgutil.get_data('termtosvg', 'data/templates/plain.svg') ] - for bstream in success_test_cases: - with self.subTest(case=bstream): - anim.validate_svg(bstream) + for data in success_test_cases: + with self.subTest(case=data): + anim.validate_svg(io.BytesIO(data)) diff --git a/tests/test___main__.py b/tests/test_main.py similarity index 96% rename from tests/test___main__.py rename to tests/test_main.py index 4b3da7c..a3068d4 100644 --- a/tests/test___main__.py +++ b/tests/test_main.py @@ -3,7 +3,7 @@ import time import unittest -import termtosvg.__main__ as __main__ +import termtosvg.main SHELL_COMMANDS = [ 'echo $SHELL && sleep 0.1;\r\n', @@ -46,7 +46,7 @@ def test_parse(self): for args in test_cases: with self.subTest(case=args): - __main__.parse(args, ['solarized-light', 'solarized-dark']) + termtosvg.main.parse(args, ['solarized-light', 'solarized-dark']) @staticmethod def run_main(shell_commands, args): @@ -62,7 +62,7 @@ def run_main(shell_commands, args): time.sleep(0.060) os._exit(0) - __main__.main(args, fd_in_read, fd_out_write) + termtosvg.main.main(args, fd_in_read, fd_out_write) os.waitpid(pid, 0) for fd in fd_in_read, fd_in_write, fd_out_read, fd_out_write: From e92081bc0ee9a315643f5b2683b88d977fb448f5 Mon Sep 17 00:00:00 2001 From: nbedos Date: Mon, 16 Jul 2018 00:44:01 +0200 Subject: [PATCH 06/16] Import modules locally to improve script startup time --- termtosvg/main.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/termtosvg/main.py b/termtosvg/main.py index 786d6a6..348ce97 100644 --- a/termtosvg/main.py +++ b/termtosvg/main.py @@ -4,11 +4,6 @@ import tempfile from typing import List, Tuple, Union -import termtosvg.anim as anim -import termtosvg.config as config -import termtosvg.asciicast as asciicast -import termtosvg.term as term - logger = logging.getLogger('termtosvg') USAGE = """termtosvg [output_file] [--font FONT] [--theme THEME] [--help] [--verbose] @@ -112,6 +107,7 @@ def main(args=None, input_fileno=None, output_fileno=None): logger.handlers = [console_handler] logger.setLevel(logging.INFO) + import termtosvg.config as config configuration = config.init_read_conf() available_themes = config.CaseInsensitiveDict(**configuration) del available_themes['global'] @@ -127,6 +123,9 @@ def main(args=None, input_fileno=None, output_fileno=None): logger.handlers.append(file_handler) logger.info('Logging to {}'.format(log_filename)) + import termtosvg.anim as anim + import termtosvg.term as term + import termtosvg.asciicast as asciicast if command == 'record': logger.info('Recording started, enter "exit" command or Control-D to end') if args.output_file is None: From 54aa1382c0d0a1f28b681b5f5a491e95e5ff2b63 Mon Sep 17 00:00:00 2001 From: nbedos Date: Mon, 16 Jul 2018 21:12:35 +0200 Subject: [PATCH 07/16] Add pylint report to build process --- .travis.yml | 1 + Makefile | 2 ++ setup.py | 1 + 3 files changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index d3ffd38..5c6979c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,7 @@ install: script: - coverage run --branch --source termtosvg -m unittest -v - coverage report + - pylint --extension-pkg-whitelist lxml termtosvg/*.py notifications: email: false diff --git a/Makefile b/Makefile index 3636fec..be54a89 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,8 @@ tests: venv_dev coverage run --branch --source termtosvg -m unittest -v && \ coverage report && \ coverage html + -$(VENV_ACTIVATE) && \ + pylint --extension-pkg-whitelist lxml termtosvg/*.py venv_dev: setup.py (test -d $(VENV_PATH) || python -m venv $(VENV_PATH)) diff --git a/setup.py b/setup.py index 2d44e69..638daa4 100644 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ extras_require={ 'dev': [ 'coverage', + 'pylint', 'twine', 'wheel', ] From 89149b456404ae93d328add6348e459d1653b769 Mon Sep 17 00:00:00 2001 From: nbedos Date: Mon, 16 Jul 2018 21:13:04 +0200 Subject: [PATCH 08/16] Fix typos and formatting --- termtosvg/anim.py | 8 +++----- termtosvg/asciicast.py | 2 +- tests/test_anim.py | 4 ---- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/termtosvg/anim.py b/termtosvg/anim.py index dbe9914..1703f4c 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -243,8 +243,7 @@ def validate_svg(svg_file): def make_animated_group(records, time, duration, cell_height, cell_width, default_bg_color, defs): # type: (Iterable[CharacterCellLineEvent], int, int, int, int, str, Dict[str, etree.ElementBase]) -> Tuple[etree.ElementBase, Dict[str, etree.ElementBase]] """Return a group element containing an SVG version of the provided records. This group is - animated, that is to say displayede on the screen and then removed according to the timing - information provided by the caller. + animated, that is to say displayed then removed according to the timing arguments. :param records: List of lines that should be included in the group :param time: Time the group should appear on the screen (milliseconds) @@ -326,7 +325,7 @@ def _render_animation(records, font, font_size, cell_width, cell_height): data = pkgutil.get_data(__name__, 'data/templates/plain.svg') tree = etree.parse(io.BytesIO(data)) - # Get a SVG template + # Get SVG template root = tree.getroot() svg_screen_tag = root.find('.//{http://www.w3.org/2000/svg}svg[@id="screen"]') if svg_screen_tag is None: @@ -335,11 +334,10 @@ def _render_animation(records, font, font_size, cell_width, cell_height): for child in svg_screen_tag.getchildren(): svg_screen_tag.remove(child) - # Reader header record and add the corresponding information to the SVG + # Read header record and add the corresponding information to the SVG if not isinstance(records, Iterator): records = iter(records) header = next(records) - def_tag = etree.SubElement(svg_screen_tag, 'defs') style_tag = build_style_tag(font, font_size, header.background_color) def_tag.append(style_tag) diff --git a/termtosvg/asciicast.py b/termtosvg/asciicast.py index 29c3c04..f560755 100644 --- a/termtosvg/asciicast.py +++ b/termtosvg/asciicast.py @@ -164,7 +164,7 @@ def __new__(cls, version, width, height, theme): if isinstance(attr, attr_type)] if not attr_types: raise AsciiCastError('Invalid type for attribute {}: {} (expected one of {})' - .format(attr_name, type(attr), cls.types[attr_name])) + .format(attr_name, type(attr), cls.types[attr_name])) if version != 2: raise AsciiCastError('Only asciicast v2 format is supported') return self diff --git a/tests/test_anim.py b/tests/test_anim.py index a4f6138..dd85236 100644 --- a/tests/test_anim.py +++ b/tests/test_anim.py @@ -198,9 +198,6 @@ def line(i): cell_height=17, default_bg_color='black', defs={}) - from lxml import etree - print(etree.tostring(group, pretty_print=True).decode('utf-8')) - print(new_defs) def test__render_animation(self): def line(i): @@ -222,7 +219,6 @@ def line(i): _, filename = tempfile.mkstemp(prefix='termtosvg_', suffix='.svg') with open(filename, 'wb') as f: - print(filename) f.write(etree.tostring(svg_root)) def test_validate_svg(self): From 3b61fb0327c4d29c838648b9df54cbdef0b179f9 Mon Sep 17 00:00:00 2001 From: nbedos Date: Tue, 17 Jul 2018 22:50:59 +0200 Subject: [PATCH 09/16] Resize template based on screen geometry --- .travis.yml | 2 + termtosvg/anim.py | 88 ++++++++++++++++++++++++++---- termtosvg/data/templates/plain.svg | 11 +++- tests/test_anim.py | 8 --- 4 files changed, 87 insertions(+), 22 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5c6979c..3716284 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,8 @@ install: script: - coverage run --branch --source termtosvg -m unittest -v + +after_success: - coverage report - pylint --extension-pkg-whitelist lxml termtosvg/*.py diff --git a/termtosvg/anim.py b/termtosvg/anim.py index 1703f4c..945571c 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -24,6 +24,14 @@ # last one ends (animation looping) LAST_ANIMATION_ID = 'anim_last' +# XML namespaces +SVG_NS = 'http://www.w3.org/2000/svg' +XLINK_NS = 'http://www.w3.org/1999/xlink' +TERMTOSVG_NS = 'https://github.com/nbedos/termtosvg' + +class TemplateError(Exception): + pass + _CharacterCell = namedtuple('_CharacterCell', ['text', 'color', 'background_color', 'bold']) _CharacterCell.__doc__ = 'Representation of a character cell' _CharacterCell.text.__doc__ = 'Text content of the cell' @@ -68,7 +76,6 @@ def from_pyte(cls, char, palette): raise ValueError('Invalid foreground color: {}'.format(char.fg)) if char.bg == 'default': - # Default colors background_color = palette['background'] elif char.bg in color_numbers: # Named colors @@ -140,7 +147,7 @@ def _render_line_bg_colors(screen_line, height, cell_height, cell_width, default :param cell_width: Width of a character cell in pixels :param default_bg_color: Default background color """ - non_default_bg_cells = [(index, cell) for (index, cell) in sorted(screen_line.items()) + non_default_bg_cells = [(column, cell) for (column, cell) in sorted(screen_line.items()) if cell.background_color != default_bg_color] key = ConsecutiveWithSameAttributes(['background_color']) @@ -165,7 +172,7 @@ def make_text_tag(column, attributes, text, cell_width): text_tag = etree.Element('text', text_tag_attributes) # Replace usual spaces with unbreakable spaces so that indenting the SVG does not mess up # the whole animation; this is somewhat better than the 'white-space: pre' CSS option - text_tag.text = text.replace(' ', u'\u00A0') + text_tag.text = text.replace(' ', '\u00A0') return text_tag @@ -286,7 +293,7 @@ def make_animated_group(records, time, duration, cell_height, cell_width, defaul # Add a reference to the definition of text_group_tag with a 'use' tag use_attributes = { - '{http://www.w3.org/1999/xlink}href': '#{}'.format(group_id), + '{{{}}}href'.format(XLINK_NS): '#{}'.format(group_id), 'y': str(event_record.row * cell_height), } use_tag = etree.Element('use', use_attributes) @@ -320,13 +327,72 @@ def render_animation(records, filename, font, font_size=14, cell_width=8, cell_h f.write(etree.tostring(root)) +def resize_template(template, columns, rows, cell_width, cell_height): + # type: (str, int, int, int, int) -> etree.ElementBase + def scaled_viewbox(element, template_columns, template_rows, columns, rows): + try: + viewbox = element.attrib['viewBox'].replace(',', ' ').split() + except KeyError: + raise TemplateError('Missing "viewBox" for element "{}"'.format(element)) + + vb_min_x, vb_min_y, vb_width, vb_height = [int(n) for n in viewbox] + vb_width += cell_width * (columns - template_columns) + vb_height += cell_height * (rows - template_rows) + return ' '.join([str(n) for n in (vb_min_x, vb_min_y, vb_width, vb_height)]) + + data = pkgutil.get_data(__name__, template) + + try: + tree = etree.parse(io.BytesIO(data)) + root = tree.getroot() + except etree.Error as exc: + raise TemplateError('Invalid template') from exc + + # Extract the screen geometry which is saved in a private data portion of the template + settings = root.find('.//{{{}}}defs/{{{}}}template_settings'.format(SVG_NS, TERMTOSVG_NS)) + if settings is None: + raise TemplateError('Missing "template_settings" element in definitions') + + geometry = settings.find('{{{}}}screen_geometry[@columns][@rows]'.format(TERMTOSVG_NS)) + if geometry is None: + raise TemplateError('Missing "screen_geometry" element in "template_settings"') + + attributes_err_msg = ('Missing or invalid "columns" or "rows" attribute for element ' + '"screen_geometry": expected positive integers') + try: + template_columns = int(geometry.attrib['columns']) + template_rows = int(geometry.attrib['rows']) + except (KeyError, ValueError) as exc: + raise TemplateError(attributes_err_msg) from exc + + if template_rows <= 0 or template_columns <= 0: + raise TemplateError(attributes_err_msg) + + # Scale the viewBox of the root svg element based on the size of the screen and the size + # registered in the template + root.attrib['viewBox'] = scaled_viewbox(root, template_columns, template_rows, columns, rows) + + # Also scale the viewBox of the svg element with id 'screen' + screen = root.find('.//{{{}}}svg[@id="screen"]'.format(SVG_NS)) + if screen is None: + raise TemplateError('svg element with id "screen" not found') + screen.attrib['viewBox'] = scaled_viewbox(screen, template_columns, template_rows, columns, rows) + + # Remove termtosvg private data so that the template can be validated against the DTD of SVG 1.1 + settings.getparent().remove(settings) + + return root + + def _render_animation(records, font, font_size, cell_width, cell_height): # type: (Iterable[CharacterCellRecord], str, int, int, int) -> etree.ElementBase - data = pkgutil.get_data(__name__, 'data/templates/plain.svg') - tree = etree.parse(io.BytesIO(data)) + # Read header record and add the corresponding information to the SVG + if not isinstance(records, Iterator): + records = iter(records) + header = next(records) + + root = resize_template('data/templates/plain.svg', header.width, header.height, cell_width, cell_height) - # Get SVG template - root = tree.getroot() svg_screen_tag = root.find('.//{http://www.w3.org/2000/svg}svg[@id="screen"]') if svg_screen_tag is None: raise ValueError('Missing tag: ...') @@ -334,10 +400,8 @@ def _render_animation(records, font, font_size, cell_width, cell_height): for child in svg_screen_tag.getchildren(): svg_screen_tag.remove(child) - # Read header record and add the corresponding information to the SVG - if not isinstance(records, Iterator): - records = iter(records) - header = next(records) + + def_tag = etree.SubElement(svg_screen_tag, 'defs') style_tag = build_style_tag(font, font_size, header.background_color) def_tag.append(style_tag) diff --git a/termtosvg/data/templates/plain.svg b/termtosvg/data/templates/plain.svg index 75157d3..2a7cd31 100644 --- a/termtosvg/data/templates/plain.svg +++ b/termtosvg/data/templates/plain.svg @@ -1,16 +1,23 @@ - + Plain template - No terminal UI, no controls, nothing but the screen of the terminal. + + + Nothing but the screen of the terminal + + + + termtosvg is awesome! diff --git a/tests/test_anim.py b/tests/test_anim.py index dd85236..549a528 100644 --- a/tests/test_anim.py +++ b/tests/test_anim.py @@ -3,7 +3,6 @@ import unittest from collections import namedtuple -import pkgutil import pyte.screens from lxml import etree @@ -234,11 +233,4 @@ def test_validate_svg(self): with self.assertRaises(ValueError): anim.validate_svg(io.StringIO(case)) - success_test_cases = [ - pkgutil.get_data('termtosvg', 'data/templates/plain.svg') - ] - - for data in success_test_cases: - with self.subTest(case=data): - anim.validate_svg(io.BytesIO(data)) From 1417557055a64ff6686c522f6d6b3a3086a57f56 Mon Sep 17 00:00:00 2001 From: nbedos Date: Sat, 21 Jul 2018 19:05:42 +0200 Subject: [PATCH 10/16] Add template scaling --- termtosvg/anim.py | 75 ++++++++++++++++++----- termtosvg/data/templates/plain.svg | 19 ++++-- termtosvg/data/templates/progress_bar.svg | 71 +++++++++++++++++++++ tests/test_anim.py | 8 +++ 4 files changed, 150 insertions(+), 23 deletions(-) create mode 100644 termtosvg/data/templates/progress_bar.svg diff --git a/termtosvg/anim.py b/termtosvg/anim.py index 945571c..f049458 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -13,12 +13,13 @@ # Ugliest hack: Replace the first 16 colors rgb values by their names so that termtosvg can # distinguish FG_BG_256[0] (which defaults to black #000000 but can be styled with themes) # from FG_BG_256[16] (which is also black #000000 but should be displayed as is). -colors = ['black', 'red', 'green', 'brown', 'blue', 'magenta', 'cyan', 'white'] -brightcolors = ['bright{}'.format(color) for color in colors] -pyte.graphics.FG_BG_256 = colors + brightcolors + pyte.graphics.FG_BG_256[16:] +_COLORS = ['black', 'red', 'green', 'brown', 'blue', 'magenta', 'cyan', 'white'] +_BRIGHTCOLORS = ['bright{}'.format(color) for color in _COLORS] +ALL_COLORS = _COLORS + _BRIGHTCOLORS +pyte.graphics.FG_BG_256 = ALL_COLORS + pyte.graphics.FG_BG_256[16:] -logger = logging.getLogger(__name__) -logger.addHandler(logging.NullHandler()) +LOGGER = logging.getLogger(__name__) +LOGGER.addHandler(logging.NullHandler()) # Id for the very last SVG animation. This is used to make the first animations start when the # last one ends (animation looping) @@ -29,9 +30,11 @@ XLINK_NS = 'http://www.w3.org/1999/xlink' TERMTOSVG_NS = 'https://github.com/nbedos/termtosvg' + class TemplateError(Exception): pass + _CharacterCell = namedtuple('_CharacterCell', ['text', 'color', 'background_color', 'bold']) _CharacterCell.__doc__ = 'Representation of a character cell' _CharacterCell.text.__doc__ = 'Text content of the cell' @@ -45,10 +48,8 @@ class CharacterCell(_CharacterCell): def from_pyte(cls, char, palette): # type: (pyte.screens.Char, Dict[Any, str]) -> CharacterCell """Create a CharacterCell from a pyte character""" - # Mappings between colors from Pyte and colors in the palette - all_colors = colors + brightcolors # Map named colors to their respective number - color_numbers = dict(zip(all_colors, range(len(all_colors)))) + color_numbers = dict(zip(ALL_COLORS, range(len(ALL_COLORS)))) if char.fg == 'default': text_color = palette['foreground'] else: @@ -323,13 +324,13 @@ def make_animated_group(records, time, duration, cell_height, cell_width, defaul def render_animation(records, filename, font, font_size=14, cell_width=8, cell_height=17): root = _render_animation(records, font, font_size, cell_width, cell_height) - with open(filename, 'wb') as f: - f.write(etree.tostring(root)) + with open(filename, 'wb') as output_file: + output_file.write(etree.tostring(root)) def resize_template(template, columns, rows, cell_width, cell_height): # type: (str, int, int, int, int) -> etree.ElementBase - def scaled_viewbox(element, template_columns, template_rows, columns, rows): + def scale(element, template_columns, template_rows, columns, rows): try: viewbox = element.attrib['viewBox'].replace(',', ' ').split() except KeyError: @@ -338,7 +339,21 @@ def scaled_viewbox(element, template_columns, template_rows, columns, rows): vb_min_x, vb_min_y, vb_width, vb_height = [int(n) for n in viewbox] vb_width += cell_width * (columns - template_columns) vb_height += cell_height * (rows - template_rows) - return ' '.join([str(n) for n in (vb_min_x, vb_min_y, vb_width, vb_height)]) + element.attrib['viewBox'] = ' '.join([str(n) for n in (vb_min_x, vb_min_y, vb_width, vb_height)]) + + scalable_attributes = { + 'width': cell_width * (columns - template_columns), + 'height': cell_height * (rows - template_rows) + } + + for attribute, delta in scalable_attributes.items(): + if attribute in element.attrib: + try: + element.attrib[attribute] = str(int(element.attrib[attribute]) + delta) + except ValueError: + raise TemplateError('"{}" attribute of {} must be in user units' + .format(attribute, element)) + return element data = pkgutil.get_data(__name__, template) @@ -370,13 +385,13 @@ def scaled_viewbox(element, template_columns, template_rows, columns, rows): # Scale the viewBox of the root svg element based on the size of the screen and the size # registered in the template - root.attrib['viewBox'] = scaled_viewbox(root, template_columns, template_rows, columns, rows) + scale(root, template_columns, template_rows, columns, rows) # Also scale the viewBox of the svg element with id 'screen' screen = root.find('.//{{{}}}svg[@id="screen"]'.format(SVG_NS)) if screen is None: raise TemplateError('svg element with id "screen" not found') - screen.attrib['viewBox'] = scaled_viewbox(screen, template_columns, template_rows, columns, rows) + scale(screen, template_columns, template_rows, columns, rows) # Remove termtosvg private data so that the template can be validated against the DTD of SVG 1.1 settings.getparent().remove(settings) @@ -391,7 +406,9 @@ def _render_animation(records, font, font_size, cell_width, cell_height): records = iter(records) header = next(records) - root = resize_template('data/templates/plain.svg', header.width, header.height, cell_width, cell_height) + #root = resize_template('data/templates/plain.svg', header.width, header.height, cell_width, cell_height) + root = resize_template('data/templates/carbon.svg', header.width, header.height, cell_width, + cell_height) svg_screen_tag = root.find('.//{http://www.w3.org/2000/svg}svg[@id="screen"]') if svg_screen_tag is None: @@ -400,8 +417,6 @@ def _render_animation(records, font, font_size, cell_width, cell_height): for child in svg_screen_tag.getchildren(): svg_screen_tag.remove(child) - - def_tag = etree.SubElement(svg_screen_tag, 'defs') style_tag = build_style_tag(font, font_size, header.background_color) def_tag.append(style_tag) @@ -413,6 +428,7 @@ def by_time(record: CharacterCellRecord) -> Tuple[int, int]: definitions = {} last_animated_group = None + animation_duration = None for (line_time, line_duration), record_group in groupby(records, key=by_time): animated_group, new_defs = make_animated_group(records=record_group, time=line_time, @@ -427,6 +443,7 @@ def by_time(record: CharacterCellRecord) -> Tuple[int, int]: svg_screen_tag.append(animated_group) last_animated_group = animated_group + animation_duration = line_time + line_duration # Add id attribute to the last 'animate' tag so that it can be refered to by the first # animations (enables animation looping) @@ -435,6 +452,30 @@ def by_time(record: CharacterCellRecord) -> Tuple[int, int]: assert len(animate_tags) == 1 animate_tags.pop().attrib['id'] = LAST_ANIMATION_ID + add_css_variables(root, header.text_color, header.background_color, animation_duration) + + return root + + +def add_css_variables(root, foreground_color, background_color, animation_duration): + # type: (etree.ElementBase, str, str, int) -> etree.ElementBase + try: + style = root.find('.//{{{}}}defs/{{{}}}style[@class="generated"]'.format(SVG_NS, SVG_NS)) + except etree.Error as exc: + raise TemplateError('Invalid template') from exc + + if style is None: + raise TemplateError('Missing nico ~ $  nico ~ $ h nico ~ $ ht nico ~ $ hto nico ~ $ htop  nico ~ $ htop  1  [|||||||||||||||||||||||||100.0%]   Tasks: 391 running2  [0.0%]   Load average: 0.33 0.32 0.30 3  [0.0%]   Uptime: 09:45:004  [0.0%]29184 nico20   0 21412  4192  3420 160.  0.1  0:00.04 │  │              └    1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash3  [|||5.3%]   Uptime: 09:45:0227104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27173 nico20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash2  [|||7.4%]   Load average: 0.33 0.32 0.30 27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico20   0 21412  4192  3420  0.7  0.1  0:00.05 │  │              └  1  [||||                       6.5%]   Tasks: 391 running2  [|||7.4%]   Load average: 0.31 0.32 0.30 3  [|||5.3%]   Uptime: 09:45:034  [||5.3%]27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us29184 nico       20   0 21412  4192  3420 R  0.7  0.1  0:00.05 │  │              └23028 nico20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash                                                                                    1  [||                         6.0%]   Tasks: 391 running2  [|||6.5%]   Load average: 0.31 0.32 0.30 3  [|||8.4%]   Uptime: 09:45:034  [|||6.4%]Mem[|||||||||||||||||   2.45G/7.74G]Swp[0K/0K]  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.87 │  │  └─ python /us27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.06 │  │              └23028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        F1Help  F2Setup F3SearchF4FilterF5SortedF6CollapF7Nice -F8Nice +F9Kill  F10Quit    3  [|||8.4%]   Uptime: 09:45:0423028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto  759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user    710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user   3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service 3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la3  [|||8.4%]   Uptime: 09:45:05  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       1  [|||                        7.6%]   Tasks: 391 running2  [|||5.2%]   Load average: 0.31 0.32 0.30 3  [|||6.4%]   Uptime: 09:45:054  [|| 5.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.45 ├─ compton -b        711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s3  [|||6.4%]   Uptime: 09:45:06  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        1  [||||                       9.8%]   Tasks: 392 running2  [|||7.3%]   Load average: 0.31 0.32 0.30 3  [|||7.4%]   Uptime: 09:45:074  [|||6.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s29184 nico       20   0 21412  4192  3420 R  1.2  0.1  0:00.10 │  │              └29184 nico       20   0 21412  4192  3420  1.2  0.1  0:00.10 │  │              └3  [|||7.4%]   Uptime: 09:45:0829180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth29180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us2  [|||7.3%]   Load average: 0.28 0.31 0.30 27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us  1  [|||||                     12.7%]   Tasks: 391 running2  [|||8.2%]   Load average: 0.28 0.31 0.30 3  [||||||13.9%]   Uptime: 09:45:084  [|||||13.2%]23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.88 │  │  └─ python /us29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.11 │  │              └3  [||||||13.9%]   Uptime: 09:45:0923027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            3  [||||||13.9%]   Uptime: 09:45:1027170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us3  [|||    8.6%]   Uptime: 09:45:10  1  [||||                       8.8%]   Tasks: 391 running2  [||||9.6%]   Load average: 0.28 0.31 0.30 3  [|||    8.6%]   Uptime: 09:45:114  [|||   7.5%]29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.12 │  │              └nico ~ $                                                                           nico ~ $ e                                                                         nico ~ $ ex                                                                        nico ~ $ exi                                                                         1  [|||                        5.0%]   Tasks: 392 running2  [||  5.4%]   Load average: 0.28 0.31 0.30 3  [||||  10.8%]   Uptime: 09:45:124  [|||   7.0%]29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.8  0.1  0:00.14 │  │              └nico ~ $ exit                                                                      nico ~ $ exit                                                                      exit \ No newline at end of file diff --git a/examples/ipython.svg b/examples/ipython.svg index cc4d4bf..e4386f9 100644 --- a/examples/ipython.svg +++ b/examples/ipython.svg @@ -1,12 +1,13 @@ - + + + minimal + - Plain template - No terminal UI, no controls, nothing but the screen of the terminal. + Minimal template - + + + + - nico ~ $  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termt nico ~ $ termto nico ~ $ termtos nico ~ $ termtosv nico ~ $ termtosvg  nico ~ $ f nico ~ $ fo nico ~ $ for nico ~ $ for  nico ~ $ for i nico ~ $ for i  nico ~ $ for i i nico ~ $ for i in nico ~ $ for i in  nico ~ $ for i in { nico ~ $ for i in {0 nico ~ $ for i in {0. nico ~ $ for i in {0.. nico ~ $ for i in {0..1 nico ~ $ for i in {0..10 nico ~ $ for i in {0..10} nico ~ $ for i in {0..10}; nico ~ $ for i in {0..10};  nico ~ $ for i in {0..10}; d nico ~ $ for i in {0..10}; do  > e > ec > ech > echo > echo  > echo " > echo "t > echo "te > echo "ter > echo "term > echo "termt > echo "termto > echo "termtos > echo "termtosv > echo "termtosvg > echo "termtosvg  > echo "termtosvg i > echo "termtosvg is > echo "termtosvg is  > echo "termtosvg is a > echo "termtosvg is aw > echo "termtosvg is awe > echo "termtosvg is awes > echo "termtosvg is aweso > echo "termtosvg is awesom > echo "termtosvg is awesome > echo "termtosvg is awesome! > echo "termtosvg is awesome!" > d > do > don > done > done  > done | > done |  > done | l > done | lo > done | lol > done | lolc > done | lolca > done | lolcat term termtosvg is awes termtosvg is aweso termtosvg is awe nico ~ $ termtosvgRecording started, enter "exit" command or Control-D to endnico ~ $ for i in {0..10}; do> echo "termtosvg is awesome!"> done | lolcattermtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg iawesome!termtosvis awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is  nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit termtosvg is awesome!termtosvg is awesome!nico ~ $ exitexitRecording ended, SVG animation is /tmp/termtosvg__20rwx67.svg +.background {fill: #002b36}]]> + + nico  + ~ +  $  +   + + + + nico  + ~ +  $  + t +   + + + + nico  + ~ +  $  + te + +   + + + + nico  + ~ +  $  + ter + +   + + + + nico  + ~ +  $  + term + +   + + + + nico  + ~ +  $  + termt + +   + + + + nico  + ~ +  $  + termto + +   + + + + nico  + ~ +  $  + + termtos + +   + + + + nico  + ~ +  $  + + termtosv + +   + + + + nico  + ~ +  $  + + termtosvg + +   + + + +   + + + + nico  + ~ +  $  + f +   + + + + nico  + ~ +  $  + fo + +   + + + + nico  + ~ +  $  + for + +   + + + + nico  + ~ +  $  + for  +   + + + + nico  + ~ +  $  + for i +   + + + + nico  + ~ +  $  + for i  +   + + + + nico  + ~ +  $  + for i i +   + + + + nico  + ~ +  $  + for i in +   + + + + nico  + ~ +  $  + for i in  +   + + + + nico  + ~ +  $  + for i in { +   + + + + nico  + ~ +  $  + for i in {0 +   + + + + nico  + ~ +  $  + for i in {0. +   + + + + nico  + ~ +  $  + for i in {0.. +   + + + + nico  + ~ +  $  + for i in {0..1 +   + + + + nico  + ~ +  $  + for i in {0..10 +   + + + + nico  + ~ +  $  + for i in {0..10} +   + + + + nico  + ~ +  $  + for i in {0..10}; +   + + + + nico  + ~ +  $  + for i in {0..10};  +   + + + + nico  + ~ +  $  + for i in {0..10}; d +   + + + + nico  + ~ +  $  + for i in {0..10}; do +   + + + + +   + + + + > e +   + + + + > ec +   + + + + > ech +   + + + + > echo +   + + + + > echo  +   + + + + > echo " +   + + + + > echo "t +   + + + + > echo "te +   + + + + > echo "ter +   + + + + > echo "term +   + + + + > echo "termt +   + + + + > echo "termto +   + + + + > echo "termtos +   + + + + > echo "termtosv +   + + + + > echo "termtosvg +   + + + + > echo "termtosvg  +   + + + + > echo "termtosvg i +   + + + + > echo "termtosvg is +   + + + + > echo "termtosvg is  +   + + + + > echo "termtosvg is a +   + + + + > echo "termtosvg is aw +   + + + + > echo "termtosvg is awe +   + + + + > echo "termtosvg is awes +   + + + + > echo "termtosvg is aweso +   + + + + > echo "termtosvg is awesom +   + + + + > echo "termtosvg is awesome +   + + + + > echo "termtosvg is awesome! +   + + + + > echo "termtosvg is awesome!" +   + + + + > d +   + + + + > do +   + + + + > don +   + + + + > done +   + + + + > done  +   + + + + > done | +   + + + + > done |  +   + + + + > done | l +   + + + + > done | lo +   + + + + > done | lol +   + + + + > done | lolc +   + + + + > done | lolca +   + + + + > done | lolcat +   + + + + term + +   + + + + termt + + osvg is a + we + + s +   + + + + termt + + osvg is a + we + + so + +   + + + + termt + + os + + vg is awe +   + + + + nico  + ~ +  $  + + termtosvg + + + + + Recording started, enter "exit" command or Control-D to end + + + + nico  + ~ +  $  + for i in {0..10}; do + + + > echo "termtosvg is awesome!" + + + > done | lolcat + + + term + + t + osvg is a + + wesome! + + + + t + e + rmtosvg i + s awesome + ! + + + + termtosv + + g is awes + om + + e! + + + + termt + + osvg is a + we + + some! + + + + te + rmtosvg i + + s  + + + awesome! + + + + + termtosv + + + g  + + is awesome + ! + + + termt + + os + + vg is awes + o + me! + + + + te + rm + + tosvg is a + w + + esome! + + + + t + ermtosvg i + s +  awesome! + + + + termtosv + + g +  is  +   + + + + nico  + ~ +  $  + e +   + + + + nico  + ~ +  $  + ex + +   + + + + nico  + ~ +  $  + exi + +   + + + + nico  + ~ +  $  + exit + +   + + + + + termtosv + + g +  is awesom + e! + + + + termt + + o + svg is awe + some! + + + + nico  + ~ +  $  + exit + + + + exit + + + + + Recording ended, SVG animation is /tmp/termtosvg__20rwx67.svg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/awesome_js.svg b/examples/awesome_js.svg index 2190d50..ec69633 100644 --- a/examples/awesome_js.svg +++ b/examples/awesome_js.svg @@ -1,1468 +1,180 @@ - - - - - - - - - - - - - - - nico  - - ~ -  $  - -   - - - nico  - - ~ -  $  - - t -   - - - nico  - - ~ -  $  - - te - -   - - - nico  - - ~ -  $  - - ter - -   - - - nico  - - ~ -  $  - - term - -   - - - nico  - - ~ -  $  - - termt - -   - - - nico  - - ~ -  $  - - termto - -   - - - nico  - - ~ -  $  - - termtos - -   - - - nico  - - ~ -  $  - - termtosv - -   - - - nico  - - ~ -  $  - - - termtosvg - -   - - -   - - - nico  - - ~ -  $  - - f -   - - - nico  - - ~ -  $  - - fo - -   - - - nico  - - ~ -  $  - - for - -   - - - nico  - - ~ -  $  - - for  - -   - - - nico  - - ~ -  $  - - for i - -   - - - nico  - - ~ -  $  - - for i  - -   - - - nico  - - ~ -  $  - - for i i - -   - - - nico  - - ~ -  $  - - for i in - -   - - - nico  - - ~ -  $  - - - for i in  - -   - - - nico  - - ~ -  $  - - - for i in { - -   - - - nico  - - ~ -  $  - - - for i in {0 - -   - - - nico  - - ~ -  $  - - - for i in {0. - -   - - - nico  - - ~ -  $  - - - for i in {0.. - -   - - - nico  - - ~ -  $  - - - for i in {0..1 - -   - - - nico  - - ~ -  $  - - - for i in {0..10 - -   - - - nico  - - ~ -  $  - - - for i in {0..10} - -   - - - nico  - - ~ -  $  - - - for i in {0..10}; - -   - - - nico  - - ~ -  $  - - - for i in {0..10};  - -   - - - nico  - - ~ -  $  - - - for i in {0..10}; d - -   - - - nico  - - ~ -  $  - - - for i in {0..10}; do - -   - - - >  - -   - - - > e - -   - - - > ec - -   - - - > ech - -   - - - > echo - -   - - - > echo  - -   - - - > echo " - -   - - - - > echo "t - -   - - - - > echo "te - -   - - - > echo "ter -   - - - > echo "term -   - - - > echo "termt -   - - - > echo "termto -   - - - > echo "termtos -   - - - > echo "termtosv -   - - - > echo "termtosvg -   - - - > echo "termtosvg  -   - - - > echo "termtosvg i -   - - - > echo "termtosvg is -   - - - > echo "termtosvg is  -   - - - > echo "termtosvg is a -   - - - > echo "termtosvg is aw -   - - - > echo "termtosvg is awe -   - - - > echo "termtosvg is awes -   - - - > echo "termtosvg is aweso -   - - - > echo "termtosvg is awesom -   - - - > echo "termtosvg is awesome -   - - - > echo "termtosvg is awesome! -   - - - > echo "termtosvg is awesome!" -   - - - > d - -   - - - > do - -   - - - > don - -   - - - > done - -   - - - > done  - -   - - - > done | - -   - - - - > done |  - -   - - - - > done | l - -   - - - > done | lo -   - - - > done | lol -   - - - > done | lolc -   - - - > done | lolca -   - - - > done | lolcat -   - - - term - -   - - - termt - - - osvg is a - - we - - s -   - - - termt - - - osvg is a - - we - - so - -   - - - termt - - os - - - vg is awe - -   - - - nico  - - ~ -  $  - - - termtosvg - - - - - Recording started, enter "exit" command or Control-D to end - - - - nico  - - ~ -  $  - - - for i in {0..10}; do - - - - > echo "termtosvg is awesome!" - - - > done | lolcat - - - term - - t - - osvg is a - - wesome! - - - - t - e - - rmtosvg i - - - s awesome - - ! - - - termtosv - - - g is awes - - om - - e! - - - - termt - - - osvg is a - - we - - some! - - - - te - - rmtosvg i - - s  - - - awesome! - - - - termtosv - - g  - - - is awesome - - ! - - - termt - - os - - - vg is awes - - o - me! - - - - te - rm - - - tosvg is a - - w - esome! - - - - t - - ermtosvg i - - s - -  awesome! - - - - termtosv - - g -  is  - -   - - - nico  - - ~ -  $  - - e -   - - - nico  - - ~ -  $  - - ex - -   - - - nico  - - ~ -  $  - - exi - -   - - - nico  - - ~ -  $  - - exit - -   - - - termtosv - - g - -  is awesom - - e! - - - - termt - - o - - svg is awe - - some! - - - - nico  - - ~ -  $  - - exit - - - - exit - - - - - Recording ended, SVG animation is /tmp/termtosvg__20rwx67.svg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + nico ~ $  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termt nico ~ $ termto nico ~ $ termtos nico ~ $ termtosv nico ~ $ termtosvg  nico ~ $ f nico ~ $ fo nico ~ $ for nico ~ $ for  nico ~ $ for i nico ~ $ for i  nico ~ $ for i i nico ~ $ for i in nico ~ $ for i in  nico ~ $ for i in { nico ~ $ for i in {0 nico ~ $ for i in {0. nico ~ $ for i in {0.. nico ~ $ for i in {0..1 nico ~ $ for i in {0..10 nico ~ $ for i in {0..10} nico ~ $ for i in {0..10}; nico ~ $ for i in {0..10};  nico ~ $ for i in {0..10}; d nico ~ $ for i in {0..10}; do  > e > ec > ech > echo > echo  > echo " > echo "t > echo "te > echo "ter > echo "term > echo "termt > echo "termto > echo "termtos > echo "termtosv > echo "termtosvg > echo "termtosvg  > echo "termtosvg i > echo "termtosvg is > echo "termtosvg is  > echo "termtosvg is a > echo "termtosvg is aw > echo "termtosvg is awe > echo "termtosvg is awes > echo "termtosvg is aweso > echo "termtosvg is awesom > echo "termtosvg is awesome > echo "termtosvg is awesome! > echo "termtosvg is awesome!" > d > do > don > done > done  > done | > done |  > done | l > done | lo > done | lol > done | lolc > done | lolca > done | lolcat term termtosvg is awes termtosvg is aweso termtosvg is awe nico ~ $ termtosvgRecording started, enter "exit" command or Control-D to endnico ~ $ for i in {0..10}; do> echo "termtosvg is awesome!"> done | lolcattermtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg iawesome!termtosvis awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is  nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit termtosvg is awesome!termtosvg is awesome!nico ~ $ exitexitRecording ended, SVG animation is /tmp/termtosvg__20rwx67.svg + 0:00/0:00 + + + + + + - + if (is_playing) { + terminal.unpauseAnimations() + screen.unpauseAnimations() + } + terminal.removeEventListener('mousemove', move, false); + }, false); +}, false); + \ No newline at end of file diff --git a/examples/colors.svg b/examples/colors.svg index 3cb2a6e..077cfff 100644 --- a/examples/colors.svg +++ b/examples/colors.svg @@ -6,11 +6,11 @@ Minimal template - + nico ~ $  nico ~ $ ~ nico ~ $ ~/ nico ~ $ ~/s nico ~ $ ~/sc nico ~ $ ~/scr nico ~ $ ~/scri nico ~ $ ~/scrip nico ~ $ ~/scripts/ nico ~ $ ~/scripts/c nico ~ $ ~/scripts/co nico ~ $ ~/scripts/col nico ~ $ ~/scripts/colo nico ~ $ ~/scripts/colors nico ~ $ ~/scripts/colors_ nico ~ $ ~/scripts/colors_2 nico ~ $ ~/scripts/colors_25 nico ~ $ ~/scripts/colors_256 nico ~ $ ~/scripts/colors_256.sh                                                                                                                                                                nico ~ $ ~/scripts/t nico ~ $ ~/scripts/tr nico ~ $ ~/scripts/tru nico ~ $ ~/scripts/true_colors. nico ~ $ ~/scripts/true_colors.s nico ~ $ ~/scripts/true_colors.sh nico ~ $ ~/scripts/true_colors.sh  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termm nico ~ $ termmt nico ~ $ termm                                                                    nico ~ $ term                                                                     nico ~ $ termt                                                                    nico ~ $ termtosvg                                                                nico ~ $ termtosvg                                                                nico ~ $ termtosvg -                                                              nico ~ $ termtosvg --                                                             nico ~ $ termtosvg --h                                                            nico ~ $ termtosvg --he                                                           nico ~ $ termtosvg --hel                                                          nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help | l                                                     nico ~ $ termtosvg --help | lo                                                    nico ~ $ termtosvg --help | loc                                                   nico ~ $ termtosvg --help | locl                                                  nico ~ $ termtosvg --help | lol                                                   nico ~ $ termtosvg --help | lolc                                                  nico ~ $ termtosvg --help | lolca                                                 nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [-- nico ~ $ ~/scripts/colors_256.sh                                                                 nico ~ $ ~/scripts/true_colors.sh                                                                              nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [--theme THEME] [--help Record a ter usage: termtosvg [output_file] [--theme THEME] [--help] [--verbose]Record a terminal session and render an SVG anim Record a terminal session and render an SVG animation on the flypositional    output_file    optiona positional arguments:  output_file    optional filename of the SVG animation; if missi                    output_file    optional filename of the SVG animation; if missing, a random                 filename will be automatically gene                    filename will be automatically generatedoptional arguments:  -h, --help     show this help    -h, --help     show this help message and exit  --theme THEME  color theme used to render the te                            classic-dark, clas   --theme THEME  color theme used to render the terminal session (circus,                 classic-dark, classic-light, dracula,                                 material, monokai, solari                  classic-dark, classic-light, dracula, isotope, marrakesh,                 material, monokai, solarized-dark, solarized-light, zenburn)                  material, monokai, solarized-dark, solarized-light, zenburn)  -v, --verbose  increase log mess See also 'termtosvg re   -v, --verbose  increase log messages verbositySee also 'termtosvg record --help' and 'termtosvg See also 'termtosvg record --help' and 'termtosvg render --help'nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit nico ~ $ exitexit +.background {fill: #002b36}]]>nico ~ $  nico ~ $ ~ nico ~ $ ~/ nico ~ $ ~/s nico ~ $ ~/sc nico ~ $ ~/scr nico ~ $ ~/scri nico ~ $ ~/scrip nico ~ $ ~/scripts/ nico ~ $ ~/scripts/c nico ~ $ ~/scripts/co nico ~ $ ~/scripts/col nico ~ $ ~/scripts/colo nico ~ $ ~/scripts/colors nico ~ $ ~/scripts/colors_ nico ~ $ ~/scripts/colors_2 nico ~ $ ~/scripts/colors_25 nico ~ $ ~/scripts/colors_256 nico ~ $ ~/scripts/colors_256.sh                                                                                                                                                                nico ~ $ ~/scripts/t nico ~ $ ~/scripts/tr nico ~ $ ~/scripts/tru nico ~ $ ~/scripts/true_colors. nico ~ $ ~/scripts/true_colors.s nico ~ $ ~/scripts/true_colors.sh nico ~ $ ~/scripts/true_colors.sh  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termm nico ~ $ termmt nico ~ $ termm                                                                    nico ~ $ term                                                                     nico ~ $ termt                                                                    nico ~ $ termtosvg                                                                nico ~ $ termtosvg                                                                nico ~ $ termtosvg -                                                              nico ~ $ termtosvg --                                                             nico ~ $ termtosvg --h                                                            nico ~ $ termtosvg --he                                                           nico ~ $ termtosvg --hel                                                          nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help | l                                                     nico ~ $ termtosvg --help | lo                                                    nico ~ $ termtosvg --help | loc                                                   nico ~ $ termtosvg --help | locl                                                  nico ~ $ termtosvg --help | lol                                                   nico ~ $ termtosvg --help | lolc                                                  nico ~ $ termtosvg --help | lolca                                                 nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [-- nico ~ $ ~/scripts/colors_256.sh                                                                 nico ~ $ ~/scripts/true_colors.sh                                                                              nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [--theme THEME] [--help Record a ter usage: termtosvg [output_file] [--theme THEME] [--help] [--verbose]Record a terminal session and render an SVG anim Record a terminal session and render an SVG animation on the flypositional    output_file    optiona positional arguments:  output_file    optional filename of the SVG animation; if missi                    output_file    optional filename of the SVG animation; if missing, a random                 filename will be automatically gene                    filename will be automatically generatedoptional arguments:  -h, --help     show this help    -h, --help     show this help message and exit  --theme THEME  color theme used to render the te                            classic-dark, clas   --theme THEME  color theme used to render the terminal session (circus,                 classic-dark, classic-light, dracula,                                 material, monokai, solari                  classic-dark, classic-light, dracula, isotope, marrakesh,                 material, monokai, solarized-dark, solarized-light, zenburn)                  material, monokai, solarized-dark, solarized-light, zenburn)  -v, --verbose  increase log mess See also 'termtosvg re   -v, --verbose  increase log messages verbositySee also 'termtosvg record --help' and 'termtosvg See also 'termtosvg record --help' and 'termtosvg render --help'nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit nico ~ $ exitexit \ No newline at end of file diff --git a/examples/htop.svg b/examples/htop.svg index cc01700..71fd5a0 100644 --- a/examples/htop.svg +++ b/examples/htop.svg @@ -6,11 +6,11 @@ Minimal template - + nico ~ $  nico ~ $ h nico ~ $ ht nico ~ $ hto nico ~ $ htop  nico ~ $ htop  1  [|||||||||||||||||||||||||100.0%]   Tasks: 391 running2  [0.0%]   Load average: 0.33 0.32 0.30 3  [0.0%]   Uptime: 09:45:004  [0.0%]29184 nico20   0 21412  4192  3420 160.  0.1  0:00.04 │  │              └    1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash3  [|||5.3%]   Uptime: 09:45:0227104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27173 nico20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash2  [|||7.4%]   Load average: 0.33 0.32 0.30 27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico20   0 21412  4192  3420  0.7  0.1  0:00.05 │  │              └  1  [||||                       6.5%]   Tasks: 391 running2  [|||7.4%]   Load average: 0.31 0.32 0.30 3  [|||5.3%]   Uptime: 09:45:034  [||5.3%]27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us29184 nico       20   0 21412  4192  3420 R  0.7  0.1  0:00.05 │  │              └23028 nico20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash                                                                                    1  [||                         6.0%]   Tasks: 391 running2  [|||6.5%]   Load average: 0.31 0.32 0.30 3  [|||8.4%]   Uptime: 09:45:034  [|||6.4%]Mem[|||||||||||||||||   2.45G/7.74G]Swp[0K/0K]  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.87 │  │  └─ python /us27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.06 │  │              └23028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        F1Help  F2Setup F3SearchF4FilterF5SortedF6CollapF7Nice -F8Nice +F9Kill  F10Quit    3  [|||8.4%]   Uptime: 09:45:0423028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto  759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user    710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user   3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service 3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la3  [|||8.4%]   Uptime: 09:45:05  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       1  [|||                        7.6%]   Tasks: 391 running2  [|||5.2%]   Load average: 0.31 0.32 0.30 3  [|||6.4%]   Uptime: 09:45:054  [|| 5.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.45 ├─ compton -b        711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s3  [|||6.4%]   Uptime: 09:45:06  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        1  [||||                       9.8%]   Tasks: 392 running2  [|||7.3%]   Load average: 0.31 0.32 0.30 3  [|||7.4%]   Uptime: 09:45:074  [|||6.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s29184 nico       20   0 21412  4192  3420 R  1.2  0.1  0:00.10 │  │              └29184 nico       20   0 21412  4192  3420  1.2  0.1  0:00.10 │  │              └3  [|||7.4%]   Uptime: 09:45:0829180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth29180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us2  [|||7.3%]   Load average: 0.28 0.31 0.30 27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us  1  [|||||                     12.7%]   Tasks: 391 running2  [|||8.2%]   Load average: 0.28 0.31 0.30 3  [||||||13.9%]   Uptime: 09:45:084  [|||||13.2%]23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.88 │  │  └─ python /us29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.11 │  │              └3  [||||||13.9%]   Uptime: 09:45:0923027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            3  [||||||13.9%]   Uptime: 09:45:1027170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us3  [|||    8.6%]   Uptime: 09:45:10  1  [||||                       8.8%]   Tasks: 391 running2  [||||9.6%]   Load average: 0.28 0.31 0.30 3  [|||    8.6%]   Uptime: 09:45:114  [|||   7.5%]29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.12 │  │              └nico ~ $                                                                           nico ~ $ e                                                                         nico ~ $ ex                                                                        nico ~ $ exi                                                                         1  [|||                        5.0%]   Tasks: 392 running2  [||  5.4%]   Load average: 0.28 0.31 0.30 3  [||||  10.8%]   Uptime: 09:45:124  [|||   7.0%]29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.8  0.1  0:00.14 │  │              └nico ~ $ exit                                                                      nico ~ $ exit                                                                      exit +.background {fill: #002b36}]]>nico ~ $  nico ~ $ h nico ~ $ ht nico ~ $ hto nico ~ $ htop  nico ~ $ htop  1  [|||||||||||||||||||||||||100.0%]   Tasks: 391 running2  [0.0%]   Load average: 0.33 0.32 0.30 3  [0.0%]   Uptime: 09:45:004  [0.0%]29184 nico20   0 21412  4192  3420 160.  0.1  0:00.04 │  │              └    1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash3  [|||5.3%]   Uptime: 09:45:0227104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27173 nico20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash2  [|||7.4%]   Load average: 0.33 0.32 0.30 27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico20   0 21412  4192  3420  0.7  0.1  0:00.05 │  │              └  1  [||||                       6.5%]   Tasks: 391 running2  [|||7.4%]   Load average: 0.31 0.32 0.30 3  [|||5.3%]   Uptime: 09:45:034  [||5.3%]27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us29184 nico       20   0 21412  4192  3420 R  0.7  0.1  0:00.05 │  │              └23028 nico20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash                                                                                    1  [||                         6.0%]   Tasks: 391 running2  [|||6.5%]   Load average: 0.31 0.32 0.30 3  [|||8.4%]   Uptime: 09:45:034  [|||6.4%]Mem[|||||||||||||||||   2.45G/7.74G]Swp[0K/0K]  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.87 │  │  └─ python /us27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.06 │  │              └23028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        F1Help  F2Setup F3SearchF4FilterF5SortedF6CollapF7Nice -F8Nice +F9Kill  F10Quit    3  [|||8.4%]   Uptime: 09:45:0423028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto  759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user    710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user   3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service 3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la3  [|||8.4%]   Uptime: 09:45:05  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       1  [|||                        7.6%]   Tasks: 391 running2  [|||5.2%]   Load average: 0.31 0.32 0.30 3  [|||6.4%]   Uptime: 09:45:054  [|| 5.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.45 ├─ compton -b        711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s3  [|||6.4%]   Uptime: 09:45:06  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        1  [||||                       9.8%]   Tasks: 392 running2  [|||7.3%]   Load average: 0.31 0.32 0.30 3  [|||7.4%]   Uptime: 09:45:074  [|||6.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s29184 nico       20   0 21412  4192  3420 R  1.2  0.1  0:00.10 │  │              └29184 nico       20   0 21412  4192  3420  1.2  0.1  0:00.10 │  │              └3  [|||7.4%]   Uptime: 09:45:0829180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth29180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us2  [|||7.3%]   Load average: 0.28 0.31 0.30 27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us  1  [|||||                     12.7%]   Tasks: 391 running2  [|||8.2%]   Load average: 0.28 0.31 0.30 3  [||||||13.9%]   Uptime: 09:45:084  [|||||13.2%]23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.88 │  │  └─ python /us29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.11 │  │              └3  [||||||13.9%]   Uptime: 09:45:0923027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            3  [||||||13.9%]   Uptime: 09:45:1027170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us3  [|||    8.6%]   Uptime: 09:45:10  1  [||||                       8.8%]   Tasks: 391 running2  [||||9.6%]   Load average: 0.28 0.31 0.30 3  [|||    8.6%]   Uptime: 09:45:114  [|||   7.5%]29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.12 │  │              └nico ~ $                                                                           nico ~ $ e                                                                         nico ~ $ ex                                                                        nico ~ $ exi                                                                         1  [|||                        5.0%]   Tasks: 392 running2  [||  5.4%]   Load average: 0.28 0.31 0.30 3  [||||  10.8%]   Uptime: 09:45:124  [|||   7.0%]29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.8  0.1  0:00.14 │  │              └nico ~ $ exit                                                                      nico ~ $ exit                                                                      exit \ No newline at end of file diff --git a/examples/ipython.svg b/examples/ipython.svg index e4386f9..6d9eb63 100644 --- a/examples/ipython.svg +++ b/examples/ipython.svg @@ -6,11 +6,11 @@ Minimal template - + nico ~ $  nico ~ $ i nico ~ $ ip nico ~ $ ipy nico ~ $ ipyt nico ~ $ ipyth nico ~ $ ipytho nico ~ $ ipython  In [1]:                                                                           In [1]: i                                                                         In [1]: im                                                                        In [1]: imp                                                                       In [1]: impo                                                                      In [1]: impor                                                                     In [1]: import                                                                    In [1]: import                                                                    In [1]: import t                                                                  In [1]: import ti                                                                 In [1]: import tim                                                                In [1]: import time                                                               In [2]:                                                                           In [2]: f                                                                         In [2]: fo                                                                        In [2]: for                                                                       In [2]: for                                                                       In [2]: for i                                                                     In [2]: for i                                                                     In [2]: for i i                                                                   In [2]: for i in                                                                  In [2]: for i in                                                                  In [2]: for i in r                                                                In [2]: for i in ra                                                               In [2]: for i in ran                                                              In [2]: for i in rang                                                             In [2]: for i in range                                                            In [2]: for i in range(                                                           In [2]: for i in range(4                                                          In [2]: for i in range(40                                                         In [2]: for i in range(40                                                       In [2]: for i in range(40):                                                          ...:         ...:     p    ...:     pr    ...:     pri    ...:     prin    ...:     print    ...:     print(    ...:     print('    ...:     print('=    ...:     print('='    ...:     print('='     ...:     print('=' *    ...:     print('=' *     ...:     print('=' * i    ...:     print('=' * i     ...:     print('=' * i +    ...:     print('=' * i +     ...:     print('=' * i + '    ...:     print('=' * i + '+    ...:     print('=' * i + '+'    ...:     print('=' * i + '+'     ...:     print('=' * i + '+'      ...:     print('=' * i + '+' +    ...:     print('=' * i + '+' +     ...:     print('=' * i + '+' + '    ...:     print('=' * i + '+' + '=    ...:     print('=' * i + '+' + '='    ...:     print('=' * i + '+' + '='     ...:     print('=' * i + '+' + '=' *    ...:     print('=' * i + '+' + '=' *     ...:     print('=' * i + '+' + '=' * (    ...:     print('=' * i + '+' + '=' * (4    ...:     print('=' * i + '+' + '=' * (40    ...:     print('=' * i + '+' + '=' * (40     ...:     print('=' * i + '+' + '=' * (40-    ...:     print('=' * i + '+' + '=' * (40-i    ...:     print('=' * i + '+' + '=' * (40-i   ...:     print('=' * i + '+' + '=' * (40-i)   ...:     t    ...:     ti    ...:     tim    ...:     time    ...:     time.    ...:     time.s  time.sleep       time.strptime       ...:     time.sleep  time.sleep       time.strptime     time.strftime    time.struct_time  <unknown>    ...:     time.sleep(    ...:     time.sleep(0    ...:     time.sleep(0.    ...:     time.sleep(0.1    ...:     time.sleep(0.1                                   In [2]: for i in range(40):                                                          ...:     print('=' * i + '+' + '=' * (40-i))   ...:     time.sleep(0.1)   ...:                                                                                                                                                  nico ~ $ ipythonPython 3.6.5 (default, May 11 2018, 04:00:52) Type 'copyright', 'credits' or 'license' for more informationIPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.In [1]: import time                                                                                                                                                    ...:                                        +========================================                                         =+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=In [3]:                                                                           In [3]: e                                                                         In [3]: ex                                                                        In [3]: exi                                                                       In [3]: exit                                                                      nico ~ $                                                                          nico ~ $ e                                                                        nico ~ $ ex                                                                       nico ~ $ exi                                                                      In [3]: exit                                                                      nico ~ $ exit                                                                     nico ~ $ exit                                                                     exit +.background {fill: #002b36}]]>nico ~ $  nico ~ $ i nico ~ $ ip nico ~ $ ipy nico ~ $ ipyt nico ~ $ ipyth nico ~ $ ipytho nico ~ $ ipython  In [1]:                                                                           In [1]: i                                                                         In [1]: im                                                                        In [1]: imp                                                                       In [1]: impo                                                                      In [1]: impor                                                                     In [1]: import                                                                    In [1]: import                                                                    In [1]: import t                                                                  In [1]: import ti                                                                 In [1]: import tim                                                                In [1]: import time                                                               In [2]:                                                                           In [2]: f                                                                         In [2]: fo                                                                        In [2]: for                                                                       In [2]: for                                                                       In [2]: for i                                                                     In [2]: for i                                                                     In [2]: for i i                                                                   In [2]: for i in                                                                  In [2]: for i in                                                                  In [2]: for i in r                                                                In [2]: for i in ra                                                               In [2]: for i in ran                                                              In [2]: for i in rang                                                             In [2]: for i in range                                                            In [2]: for i in range(                                                           In [2]: for i in range(4                                                          In [2]: for i in range(40                                                         In [2]: for i in range(40                                                       In [2]: for i in range(40):                                                          ...:         ...:     p    ...:     pr    ...:     pri    ...:     prin    ...:     print    ...:     print(    ...:     print('    ...:     print('=    ...:     print('='    ...:     print('='     ...:     print('=' *    ...:     print('=' *     ...:     print('=' * i    ...:     print('=' * i     ...:     print('=' * i +    ...:     print('=' * i +     ...:     print('=' * i + '    ...:     print('=' * i + '+    ...:     print('=' * i + '+'    ...:     print('=' * i + '+'     ...:     print('=' * i + '+'      ...:     print('=' * i + '+' +    ...:     print('=' * i + '+' +     ...:     print('=' * i + '+' + '    ...:     print('=' * i + '+' + '=    ...:     print('=' * i + '+' + '='    ...:     print('=' * i + '+' + '='     ...:     print('=' * i + '+' + '=' *    ...:     print('=' * i + '+' + '=' *     ...:     print('=' * i + '+' + '=' * (    ...:     print('=' * i + '+' + '=' * (4    ...:     print('=' * i + '+' + '=' * (40    ...:     print('=' * i + '+' + '=' * (40     ...:     print('=' * i + '+' + '=' * (40-    ...:     print('=' * i + '+' + '=' * (40-i    ...:     print('=' * i + '+' + '=' * (40-i   ...:     print('=' * i + '+' + '=' * (40-i)   ...:     t    ...:     ti    ...:     tim    ...:     time    ...:     time.    ...:     time.s  time.sleep       time.strptime       ...:     time.sleep  time.sleep       time.strptime     time.strftime    time.struct_time  <unknown>    ...:     time.sleep(    ...:     time.sleep(0    ...:     time.sleep(0.    ...:     time.sleep(0.1    ...:     time.sleep(0.1                                   In [2]: for i in range(40):                                                          ...:     print('=' * i + '+' + '=' * (40-i))   ...:     time.sleep(0.1)   ...:                                                                                                                                                  nico ~ $ ipythonPython 3.6.5 (default, May 11 2018, 04:00:52) Type 'copyright', 'credits' or 'license' for more informationIPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.In [1]: import time                                                                                                                                                    ...:                                        +========================================                                         =+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=In [3]:                                                                           In [3]: e                                                                         In [3]: ex                                                                        In [3]: exi                                                                       In [3]: exit                                                                      nico ~ $                                                                          nico ~ $ e                                                                        nico ~ $ ex                                                                       nico ~ $ exi                                                                      In [3]: exit                                                                      nico ~ $ exit                                                                     nico ~ $ exit                                                                     exit \ No newline at end of file diff --git a/examples/unittest.svg b/examples/unittest.svg index 9ad7602..55c4990 100644 --- a/examples/unittest.svg +++ b/examples/unittest.svg @@ -6,11 +6,11 @@ Minimal template - + nico ~/termtosvg $  nico ~/termtosvg $ m nico ~/termtosvg $ ma nico ~/termtosvg $ mak nico ~/termtosvg $ make nico ~/termtosvg $ make  nico ~/termtosvg $ make t nico ~/termtosvg $ make te nico ~/termtosvg $ make tes nico ~/termtosvg $ make test nico ~/termtosvg $ make tests  nico ~/termtosvg $ make tests(test -d .venv || python -m venv .venv). .venv/bin/activate && \    pip install -U -e .[dev]Obtaining file:///home/nico/termtosvgRequirement already up-to-date: setuptools in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: pyte in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: python-xlib in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: svgwrite in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: coverage in ./.venv/lib/python3.6/site-packages (fRequirement already up-to-date: twine in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: wheel in ./.venv/lib/python3.6/site-packages (fromRequirement already up-to-date: wcwidth in ./.venv/lib/python3.6/site-packages (from pyte->termtosvg==0.1.0)Requirement already up-to-date: six>=1.10.0 in ./.venv/lib/python3.6/site-packages (from python-xlib->termtosvg==0.1.0)Requirement already up-to-date: pyparsing>=2.0.1 in ./.venv/lib/python3.6/site-packages (from svgwrite->termtosvg==0.1.0)Requirement already up-to-date: requests!=2.15,!=2.16,>=2.5.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: requests-toolbelt>=0.8.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: tqdm>=4.14 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: pkginfo>=1.4.2 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: certifi>=2017.4.17 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: idna<2.8,>=2.5 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: urllib3<1.24,>=1.21.1 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: chardet<3.1.0,>=3.0.2 in ./.venv/lib/python3.6/sitInstalling collected packages: termtosvg  Found existing installation: termtosvg 0.1.0    Uninstalling termtosvg-0.1.0:      Successfully uninstalled termtosvg-0.1.0  Running setup.py develop for termtosvgSuccessfully installed termtosvgYou are using pip version 9.0.3, however version 10.0.1 is available.You should consider upgrading via the 'pip install --upgrade pip' command.    pip freeze && \    coverage run --branch --source termtosvg -m unittest -v && \    coverage report && \    coverage htmlpython-xlib==0.23pytz==2018.4requests==2.19.1requests-toolbelt==0.8.0rsa==3.4.2six==1.11.0svgwrite==1.1.12-e git+git@github.com:nbedos/termtosvg.git@dab7f522c126e9938e896d023d8be453f0dcf1b9#egg=termtosvgtinydb==3.9.0.post1tinyrecord==0.1.5tox==3.0.0tqdm==4.23.4twine==1.11.0urllib3==1.23virtualenv==16.0.0wcwidth==0.1.7wrapt==1.10.11test_main (tests.test___main__.TestMain) ...  test_main (tests.test___main__.TestMain) ... Recording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_3vqhnplh.castRecording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_s7tgsv75.castRendering startedRendering ended, SVG animation is /tmp/termtosvg_wts11qev.svgRendering ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgRendering ended, SVG animation is /tmp/termtosvg_i8zp1z7w.svgLogging to /tmp/termtosvg.logRecording ended, SVG animation is /tmp/termtosvg_fkz0r2vk.svgRecording ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgoktest_parse (tests.test___main__.TestMain) ...  test_parse (tests.test___main__.TestMain) ... oktest__render_characters (tests.test_anim.TestAnim) ... oktest__render_line_bg_colors (tests.test_anim.TestAnim) ...  test__render_line_bg_colors (tests.test_anim.TestAnim) ... oktest_from_pyte (tests.test_anim.TestAnim) ... oktest_render_animation (tests.test_anim.TestAnim) ...  test_render_animation (tests.test_anim.TestAnim) ... oktest_serialize_css_dict (tests.test_anim.TestAnim) ... oktest_AsciiCastEvent (tests.test_asciicast.TestAsciicast) ... oktest_AsciiCastHeader (tests.test_asciicast.TestAsciicast) ... oktest_from_json (tests.test_asciicast.TestAsciicast) ...  test_from_json (tests.test_asciicast.TestAsciicast) ... oktest_from_xresources (tests.test_asciicast.TestAsciicast) ...  test_from_xresources (tests.test_asciicast.TestAsciicast) ... oktest_to_json (tests.test_asciicast.TestAsciicast) ... oktest__group_by_time (tests.test_term.TestTerm) ... oktest__record (tests.test_term.TestTerm) ...  test__record (tests.test_term.TestTerm) ... oktest_default_themes (tests.test_term.TestTerm) ...  test_default_themes (tests.test_term.TestTerm) ... oktest_get_configuration (tests.test_term.TestTerm) ...  test_get_configuration (tests.test_term.TestTerm) ... oktest_record (tests.test_term.TestTerm) ...  test_record (tests.test_term.TestTerm) ... oktest_replay (tests.test_term.TestTerm) ...  test_replay (tests.test_term.TestTerm) ... ok----------------------------------------------------------------------Ran 18 tests in 5.164sOKnico ~/termtosvg $ e nico ~/termtosvg $ ex nico ~/termtosvg $ exi Name                     Stmts   Miss Branch BrPart  Cover----------------------------------------------------------termtosvg/__init__.py        0      0      0      0   100%termtosvg/__main__.py      106      4     38      4    94%termtosvg/anim.py          146      3     60      3    97%termtosvg/asciicast.py      93      6     38      3    93%termtosvg/term.py          192     13     66      8    91%TOTAL                      537     26    202     18    94%nico ~/termtosvg $ exit nico ~/termtosvg $ exitexit +.background {fill: #002b36}]]>nico ~/termtosvg $  nico ~/termtosvg $ m nico ~/termtosvg $ ma nico ~/termtosvg $ mak nico ~/termtosvg $ make nico ~/termtosvg $ make  nico ~/termtosvg $ make t nico ~/termtosvg $ make te nico ~/termtosvg $ make tes nico ~/termtosvg $ make test nico ~/termtosvg $ make tests  nico ~/termtosvg $ make tests(test -d .venv || python -m venv .venv). .venv/bin/activate && \    pip install -U -e .[dev]Obtaining file:///home/nico/termtosvgRequirement already up-to-date: setuptools in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: pyte in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: python-xlib in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: svgwrite in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: coverage in ./.venv/lib/python3.6/site-packages (fRequirement already up-to-date: twine in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: wheel in ./.venv/lib/python3.6/site-packages (fromRequirement already up-to-date: wcwidth in ./.venv/lib/python3.6/site-packages (from pyte->termtosvg==0.1.0)Requirement already up-to-date: six>=1.10.0 in ./.venv/lib/python3.6/site-packages (from python-xlib->termtosvg==0.1.0)Requirement already up-to-date: pyparsing>=2.0.1 in ./.venv/lib/python3.6/site-packages (from svgwrite->termtosvg==0.1.0)Requirement already up-to-date: requests!=2.15,!=2.16,>=2.5.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: requests-toolbelt>=0.8.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: tqdm>=4.14 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: pkginfo>=1.4.2 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: certifi>=2017.4.17 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: idna<2.8,>=2.5 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: urllib3<1.24,>=1.21.1 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: chardet<3.1.0,>=3.0.2 in ./.venv/lib/python3.6/sitInstalling collected packages: termtosvg  Found existing installation: termtosvg 0.1.0    Uninstalling termtosvg-0.1.0:      Successfully uninstalled termtosvg-0.1.0  Running setup.py develop for termtosvgSuccessfully installed termtosvgYou are using pip version 9.0.3, however version 10.0.1 is available.You should consider upgrading via the 'pip install --upgrade pip' command.    pip freeze && \    coverage run --branch --source termtosvg -m unittest -v && \    coverage report && \    coverage htmlpython-xlib==0.23pytz==2018.4requests==2.19.1requests-toolbelt==0.8.0rsa==3.4.2six==1.11.0svgwrite==1.1.12-e git+git@github.com:nbedos/termtosvg.git@dab7f522c126e9938e896d023d8be453f0dcf1b9#egg=termtosvgtinydb==3.9.0.post1tinyrecord==0.1.5tox==3.0.0tqdm==4.23.4twine==1.11.0urllib3==1.23virtualenv==16.0.0wcwidth==0.1.7wrapt==1.10.11test_main (tests.test___main__.TestMain) ...  test_main (tests.test___main__.TestMain) ... Recording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_3vqhnplh.castRecording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_s7tgsv75.castRendering startedRendering ended, SVG animation is /tmp/termtosvg_wts11qev.svgRendering ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgRendering ended, SVG animation is /tmp/termtosvg_i8zp1z7w.svgLogging to /tmp/termtosvg.logRecording ended, SVG animation is /tmp/termtosvg_fkz0r2vk.svgRecording ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgoktest_parse (tests.test___main__.TestMain) ...  test_parse (tests.test___main__.TestMain) ... oktest__render_characters (tests.test_anim.TestAnim) ... oktest__render_line_bg_colors (tests.test_anim.TestAnim) ...  test__render_line_bg_colors (tests.test_anim.TestAnim) ... oktest_from_pyte (tests.test_anim.TestAnim) ... oktest_render_animation (tests.test_anim.TestAnim) ...  test_render_animation (tests.test_anim.TestAnim) ... oktest_serialize_css_dict (tests.test_anim.TestAnim) ... oktest_AsciiCastEvent (tests.test_asciicast.TestAsciicast) ... oktest_AsciiCastHeader (tests.test_asciicast.TestAsciicast) ... oktest_from_json (tests.test_asciicast.TestAsciicast) ...  test_from_json (tests.test_asciicast.TestAsciicast) ... oktest_from_xresources (tests.test_asciicast.TestAsciicast) ...  test_from_xresources (tests.test_asciicast.TestAsciicast) ... oktest_to_json (tests.test_asciicast.TestAsciicast) ... oktest__group_by_time (tests.test_term.TestTerm) ... oktest__record (tests.test_term.TestTerm) ...  test__record (tests.test_term.TestTerm) ... oktest_default_themes (tests.test_term.TestTerm) ...  test_default_themes (tests.test_term.TestTerm) ... oktest_get_configuration (tests.test_term.TestTerm) ...  test_get_configuration (tests.test_term.TestTerm) ... oktest_record (tests.test_term.TestTerm) ...  test_record (tests.test_term.TestTerm) ... oktest_replay (tests.test_term.TestTerm) ...  test_replay (tests.test_term.TestTerm) ... ok----------------------------------------------------------------------Ran 18 tests in 5.164sOKnico ~/termtosvg $ e nico ~/termtosvg $ ex nico ~/termtosvg $ exi Name                     Stmts   Miss Branch BrPart  Cover----------------------------------------------------------termtosvg/__init__.py        0      0      0      0   100%termtosvg/__main__.py      106      4     38      4    94%termtosvg/anim.py          146      3     60      3    97%termtosvg/asciicast.py      93      6     38      3    93%termtosvg/term.py          192     13     66      8    91%TOTAL                      537     26    202     18    94%nico ~/termtosvg $ exit nico ~/termtosvg $ exitexit \ No newline at end of file diff --git a/termtosvg/anim.py b/termtosvg/anim.py index 483210a..165af97 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -96,7 +96,7 @@ def from_pyte(cls, char, palette): CharacterCellConfig = namedtuple('CharacterCellConfig', ['width', 'height', 'text_color', - 'background_color']) + 'background_color', 'palette']) CharacterCellLineEvent = namedtuple('CharacterCellLineEvent', ['row', 'line', 'time', 'duration']) CharacterCellRecord = Union[CharacterCellConfig, CharacterCellLineEvent] @@ -312,8 +312,7 @@ def make_animated_group(records, time, duration, cell_height, cell_width, defaul 'from': 'inline', 'to': 'inline', 'begin': begin_time, - 'dur': '{}ms'.format(duration), - 'fill': 'remove', + 'dur': '{}ms'.format(duration) } animation = etree.Element('animate', attributes) @@ -448,21 +447,25 @@ def by_time(record: CharacterCellRecord) -> Tuple[int, int]: assert len(animate_tags) == 1 animate_tags.pop().attrib['id'] = LAST_ANIMATION_ID - add_css_variables(root, header.text_color, header.background_color, animation_duration) + add_css_variables(root=root, + foreground_color=header.text_color, + background_color=header.background_color, + animation_duration=animation_duration, + palette=header.palette) return root -def add_css_variables(root, foreground_color, background_color, animation_duration): - # type: (etree.ElementBase, str, str, int) -> etree.ElementBase +def add_css_variables(root, foreground_color, background_color, animation_duration, palette): + # type: (etree.ElementBase, str, str, int, List[str]) -> etree.ElementBase try: - style = root.find('.//{{{namespace}}}defs/{{{namespace}}}style[@class="generated"]' + style = root.find('.//{{{namespace}}}defs/{{{namespace}}}style[@id="generated"]' .format(namespace=SVG_NS)) except etree.Error as exc: raise TemplateError('Invalid template') from exc if style is None: - raise TemplateError('Missing - - - + + + - + termtosvg is awesome! + .background {fill: #272822}]]> diff --git a/termtosvg/data/templates/carbon_js.svg b/termtosvg/data/templates/carbon_js.svg new file mode 100644 index 0000000..c930ac0 --- /dev/null +++ b/termtosvg/data/templates/carbon_js.svg @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + termtosvg is awesome! + + + + + + + + + + + + + + + + + + + + 0:00/0:00 + + + + + + + + + + + diff --git a/termtosvg/data/templates/plain.svg b/termtosvg/data/templates/plain.svg index 611cbea..f9a0723 100644 --- a/termtosvg/data/templates/plain.svg +++ b/termtosvg/data/templates/plain.svg @@ -13,7 +13,7 @@ must be specified in user units (e.g width="123") --> - + @@ -67,5 +68,5 @@ must be specified in user units (e.g width="123") --> - + \ No newline at end of file diff --git a/termtosvg/term.py b/termtosvg/term.py index 8dd9018..3479ee9 100644 --- a/termtosvg/term.py +++ b/termtosvg/term.py @@ -235,7 +235,8 @@ def sort_by_time(d, row): config = CharacterCellConfig(width=header.width, height=header.height, text_color=header.theme.fg, - background_color=header.theme.bg) + background_color=header.theme.bg, + palette=header.theme.palette.split(':')) yield config palette = { diff --git a/tests/test_anim.py b/tests/test_anim.py index 5b6516c..39fe3b8 100644 --- a/tests/test_anim.py +++ b/tests/test_anim.py @@ -204,7 +204,7 @@ def line(i): return dict(enumerate(chars)) records = [ - anim.CharacterCellConfig(80, 24, 'black', 'black'), + anim.CharacterCellConfig(80, 24, 'black', 'black', ''), anim.CharacterCellLineEvent(1, line(1), 0, 60), anim.CharacterCellLineEvent(2, line(2), 60, 60), anim.CharacterCellLineEvent(3, line(3), 120, 60), @@ -226,7 +226,7 @@ def test_add_css_variables(self): tree = etree.parse(io.BytesIO(data)) root = tree.getroot() - anim.add_css_variables(root, 'aa', 'bb', 42) + anim.add_css_variables(root, 'aa', 'bb', 42, ['#000000', '#111111']) def test_validate_svg(self): failure_test_cases = [ diff --git a/tests/test_main.py b/tests/test_main.py index fc996a4..52448d1 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -56,7 +56,7 @@ def test_parse(self): } for args in test_cases: with self.subTest(case=args): - termtosvg.main.parse(args, ['solarized-light', 'solarized-dark'], ['carbon'], defaults) + cmd, parsed_args = termtosvg.main.parse(args, ['solarized-light', 'solarized-dark'], ['carbon'], defaults) @staticmethod def run_main(shell_commands, args): From 8540e7b68527a55f85d8791f34836573aaf4a819 Mon Sep 17 00:00:00 2001 From: nbedos Date: Thu, 2 Aug 2018 14:08:55 +0200 Subject: [PATCH 14/16] Fix according to review by @styfle --- examples/awesome_js.svg | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/examples/awesome_js.svg b/examples/awesome_js.svg index ec69633..7967fff 100644 --- a/examples/awesome_js.svg +++ b/examples/awesome_js.svg @@ -73,8 +73,8 @@ var terminal = document.getElementById('terminal'); var screen = terminal.getElementById('screen'); var slider_1 = terminal.getElementById('slider_1'); var anim_slider_button = document.getElementById('anim_slider_button'); -var style = getComputedStyle(terminal); -var animation_duration = parseInt(style.getPropertyValue('--animation-duration')) / 1000; +var dur = window.getComputedStyle(terminal).getPropertyValue('--animation-duration'); +var animation_duration = parseInt(dur) / 1000; function getTranslateX(elem) { var style = window.getComputedStyle(elem); @@ -82,7 +82,7 @@ function getTranslateX(elem) { return parseInt(matrix.m41) } -track_begin = getTranslateX(terminal.getElementById('track')) +var track_begin = getTranslateX(terminal.getElementById('track')) anim_slider_button.setAttribute('from', track_begin); var track_width = terminal.getElementById('track').getBoundingClientRect().width; @@ -92,22 +92,22 @@ var play_button = terminal.getElementById('play-button'); var pause_button = terminal.getElementById('pause-button'); // Set slider button animation duration -anim_slider_button.setAttribute('dur', style.getPropertyValue('--animation-duration')); +anim_slider_button.setAttribute('dur', dur); -play_button.setAttribute('display', 'none'); -pause_button.setAttribute('display', 'inline'); +play_button.style.display = 'none'; +pause_button.style.display = 'inline'; function togglePlayPause() { if (terminal.animationsPaused() || screen.animationsPaused()) { terminal.unpauseAnimations() screen.unpauseAnimations() - play_button.setAttribute('display', 'none') - pause_button.setAttribute('display', 'inline') + play_button.style.display = 'none'; + pause_button.style.display = 'inline'; } else { terminal.pauseAnimations() screen.pauseAnimations() - play_button.setAttribute('display', 'inline') - pause_button.setAttribute('display', 'none') + play_button.style.display = 'inline'; + pause_button.style.display = 'none'; } }; @@ -122,8 +122,8 @@ var limitUpper = parseInt(anim_slider_button.getAttribute('to')) - 8; var timer = terminal.getElementById('timer') function timer_from_ms(t) { - minutes = Math.floor(t / 60); - seconds = Math.floor(t % 60); + var minutes = Math.floor(t / 60); + var seconds = Math.floor(t % 60); return minutes + ':' + ("0" + seconds).slice(-2) } @@ -132,7 +132,7 @@ function update_timer(){ timer.textContent = timer_from_ms(current_time) + "/" + timer_from_ms(animation_duration) } -setInterval(update_timer, "100ms") +setInterval(update_timer, 100) // Return X position for an event function mx(evt){ From 9106d41a83db12fba5f5acad79bd804e97640c24 Mon Sep 17 00:00:00 2001 From: nbedos Date: Thu, 2 Aug 2018 15:49:15 +0200 Subject: [PATCH 15/16] Replace harcoded colors by CSS classes --- examples/awesome.svg | 1360 +-------------------- examples/colors.svg | 31 +- examples/htop.svg | 31 +- examples/ipython.svg | 31 +- examples/unittest.svg | 31 +- fiddle/fiddle.css | 2 - fiddle/fiddle.js | 44 - fiddle/fiddle.svg | 27 - termtosvg/anim.py | 66 +- termtosvg/data/templates/carbon.svg | 69 +- termtosvg/data/templates/carbon_js.svg | 79 +- termtosvg/data/templates/plain.svg | 30 +- termtosvg/data/templates/progress_bar.svg | 31 +- termtosvg/term.py | 8 +- tests/test_anim.py | 69 +- tests/test_term.py | 15 +- 16 files changed, 280 insertions(+), 1644 deletions(-) delete mode 100644 fiddle/fiddle.css delete mode 100644 fiddle/fiddle.js delete mode 100644 fiddle/fiddle.svg diff --git a/examples/awesome.svg b/examples/awesome.svg index 43614dc..1efcc69 100644 --- a/examples/awesome.svg +++ b/examples/awesome.svg @@ -1,1339 +1,29 @@ - - - minimal - - - Minimal template - + - - + + - - - - nico  - ~ -  $  -   - - - - nico  - ~ -  $  - t -   - - - - nico  - ~ -  $  - te - -   - - - - nico  - ~ -  $  - ter - -   - - - - nico  - ~ -  $  - term - -   - - - - nico  - ~ -  $  - termt - -   - - - - nico  - ~ -  $  - termto - -   - - - - nico  - ~ -  $  - - termtos - -   - - - - nico  - ~ -  $  - - termtosv - -   - - - - nico  - ~ -  $  - - termtosvg - -   - - - -   - - - - nico  - ~ -  $  - f -   - - - - nico  - ~ -  $  - fo - -   - - - - nico  - ~ -  $  - for - -   - - - - nico  - ~ -  $  - for  -   - - - - nico  - ~ -  $  - for i -   - - - - nico  - ~ -  $  - for i  -   - - - - nico  - ~ -  $  - for i i -   - - - - nico  - ~ -  $  - for i in -   - - - - nico  - ~ -  $  - for i in  -   - - - - nico  - ~ -  $  - for i in { -   - - - - nico  - ~ -  $  - for i in {0 -   - - - - nico  - ~ -  $  - for i in {0. -   - - - - nico  - ~ -  $  - for i in {0.. -   - - - - nico  - ~ -  $  - for i in {0..1 -   - - - - nico  - ~ -  $  - for i in {0..10 -   - - - - nico  - ~ -  $  - for i in {0..10} -   - - - - nico  - ~ -  $  - for i in {0..10}; -   - - - - nico  - ~ -  $  - for i in {0..10};  -   - - - - nico  - ~ -  $  - for i in {0..10}; d -   - - - - nico  - ~ -  $  - for i in {0..10}; do -   - - - - -   - - - - > e -   - - - - > ec -   - - - - > ech -   - - - - > echo -   - - - - > echo  -   - - - - > echo " -   - - - - > echo "t -   - - - - > echo "te -   - - - - > echo "ter -   - - - - > echo "term -   - - - - > echo "termt -   - - - - > echo "termto -   - - - - > echo "termtos -   - - - - > echo "termtosv -   - - - - > echo "termtosvg -   - - - - > echo "termtosvg  -   - - - - > echo "termtosvg i -   - - - - > echo "termtosvg is -   - - - - > echo "termtosvg is  -   - - - - > echo "termtosvg is a -   - - - - > echo "termtosvg is aw -   - - - - > echo "termtosvg is awe -   - - - - > echo "termtosvg is awes -   - - - - > echo "termtosvg is aweso -   - - - - > echo "termtosvg is awesom -   - - - - > echo "termtosvg is awesome -   - - - - > echo "termtosvg is awesome! -   - - - - > echo "termtosvg is awesome!" -   - - - - > d -   - - - - > do -   - - - - > don -   - - - - > done -   - - - - > done  -   - - - - > done | -   - - - - > done |  -   - - - - > done | l -   - - - - > done | lo -   - - - - > done | lol -   - - - - > done | lolc -   - - - - > done | lolca -   - - - - > done | lolcat -   - - - - term - -   - - - - termt - - osvg is a - we - - s -   - - - - termt - - osvg is a - we - - so - -   - - - - termt - - os - - vg is awe -   - - - - nico  - ~ -  $  - - termtosvg - - - - - Recording started, enter "exit" command or Control-D to end - - - - nico  - ~ -  $  - for i in {0..10}; do - - - > echo "termtosvg is awesome!" - - - > done | lolcat - - - term - - t - osvg is a - - wesome! - - - - t - e - rmtosvg i - s awesome - ! - - - - termtosv - - g is awes - om - - e! - - - - termt - - osvg is a - we - - some! - - - - te - rmtosvg i - - s  - - - awesome! - - - - - termtosv - - - g  - - is awesome - ! - - - termt - - os - - vg is awes - o - me! - - - - te - rm - - tosvg is a - w - - esome! - - - - t - ermtosvg i - s -  awesome! - - - - termtosv - - g -  is  -   - - - - nico  - ~ -  $  - e -   - - - - nico  - ~ -  $  - ex - -   - - - - nico  - ~ -  $  - exi - -   - - - - nico  - ~ -  $  - exit - -   - - - - - termtosv - - g -  is awesom - e! - - - - termt - - o - svg is awe - some! - - - - nico  - ~ -  $  - exit - - - - exit - - - - - Recording ended, SVG animation is /tmp/termtosvg__20rwx67.svg - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + nico ~ $  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termt nico ~ $ termto nico ~ $ termtos nico ~ $ termtosv nico ~ $ termtosvg  nico ~ $ f nico ~ $ fo nico ~ $ for nico ~ $ for  nico ~ $ for i nico ~ $ for i  nico ~ $ for i i nico ~ $ for i in nico ~ $ for i in  nico ~ $ for i in { nico ~ $ for i in {0 nico ~ $ for i in {0. nico ~ $ for i in {0.. nico ~ $ for i in {0..1 nico ~ $ for i in {0..10 nico ~ $ for i in {0..10} nico ~ $ for i in {0..10}; nico ~ $ for i in {0..10};  nico ~ $ for i in {0..10}; d nico ~ $ for i in {0..10}; do  > e > ec > ech > echo > echo  > echo " > echo "t > echo "te > echo "ter > echo "term > echo "termt > echo "termto > echo "termtos > echo "termtosv > echo "termtosvg > echo "termtosvg  > echo "termtosvg i > echo "termtosvg is > echo "termtosvg is  > echo "termtosvg is a > echo "termtosvg is aw > echo "termtosvg is awe > echo "termtosvg is awes > echo "termtosvg is aweso > echo "termtosvg is awesom > echo "termtosvg is awesome > echo "termtosvg is awesome! > echo "termtosvg is awesome!" > d > do > don > done > done  > done | > done |  > done | l > done | lo > done | lol > done | lolc > done | lolca > done | lolcat term termtosvg is awes termtosvg is aweso termtosvg is awe nico ~ $ termtosvgRecording started, enter "exit" command or Control-D to endnico ~ $ for i in {0..10}; do> echo "termtosvg is awesome!"> done | lolcattermtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg iawesome!termtosvis awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is awesome!termtosvg is  nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit termtosvg is awesome!termtosvg is awesome!nico ~ $ exitexitRecording ended, SVG animation is /tmp/termtosvg__20rwx67.svg \ No newline at end of file diff --git a/examples/colors.svg b/examples/colors.svg index 077cfff..6ba84d7 100644 --- a/examples/colors.svg +++ b/examples/colors.svg @@ -1,16 +1,29 @@ - - minimal - - - Minimal template - - + nico ~ $  nico ~ $ ~ nico ~ $ ~/ nico ~ $ ~/s nico ~ $ ~/sc nico ~ $ ~/scr nico ~ $ ~/scri nico ~ $ ~/scrip nico ~ $ ~/scripts/ nico ~ $ ~/scripts/c nico ~ $ ~/scripts/co nico ~ $ ~/scripts/col nico ~ $ ~/scripts/colo nico ~ $ ~/scripts/colors nico ~ $ ~/scripts/colors_ nico ~ $ ~/scripts/colors_2 nico ~ $ ~/scripts/colors_25 nico ~ $ ~/scripts/colors_256 nico ~ $ ~/scripts/colors_256.sh                                                                                                                                                                nico ~ $ ~/scripts/t nico ~ $ ~/scripts/tr nico ~ $ ~/scripts/tru nico ~ $ ~/scripts/true_colors. nico ~ $ ~/scripts/true_colors.s nico ~ $ ~/scripts/true_colors.sh nico ~ $ ~/scripts/true_colors.sh  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termm nico ~ $ termmt nico ~ $ termm                                                                    nico ~ $ term                                                                     nico ~ $ termt                                                                    nico ~ $ termtosvg                                                                nico ~ $ termtosvg                                                                nico ~ $ termtosvg -                                                              nico ~ $ termtosvg --                                                             nico ~ $ termtosvg --h                                                            nico ~ $ termtosvg --he                                                           nico ~ $ termtosvg --hel                                                          nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help | l                                                     nico ~ $ termtosvg --help | lo                                                    nico ~ $ termtosvg --help | loc                                                   nico ~ $ termtosvg --help | locl                                                  nico ~ $ termtosvg --help | lol                                                   nico ~ $ termtosvg --help | lolc                                                  nico ~ $ termtosvg --help | lolca                                                 nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [-- nico ~ $ ~/scripts/colors_256.sh                                                                 nico ~ $ ~/scripts/true_colors.sh                                                                              nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [--theme THEME] [--help Record a ter usage: termtosvg [output_file] [--theme THEME] [--help] [--verbose]Record a terminal session and render an SVG anim Record a terminal session and render an SVG animation on the flypositional    output_file    optiona positional arguments:  output_file    optional filename of the SVG animation; if missi                    output_file    optional filename of the SVG animation; if missing, a random                 filename will be automatically gene                    filename will be automatically generatedoptional arguments:  -h, --help     show this help    -h, --help     show this help message and exit  --theme THEME  color theme used to render the te                            classic-dark, clas   --theme THEME  color theme used to render the terminal session (circus,                 classic-dark, classic-light, dracula,                                 material, monokai, solari                  classic-dark, classic-light, dracula, isotope, marrakesh,                 material, monokai, solarized-dark, solarized-light, zenburn)                  material, monokai, solarized-dark, solarized-light, zenburn)  -v, --verbose  increase log mess See also 'termtosvg re   -v, --verbose  increase log messages verbositySee also 'termtosvg record --help' and 'termtosvg See also 'termtosvg record --help' and 'termtosvg render --help'nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit nico ~ $ exitexit +text {dominant-baseline: text-before-edge}]]>nico ~ $  nico ~ $ ~ nico ~ $ ~/ nico ~ $ ~/s nico ~ $ ~/sc nico ~ $ ~/scr nico ~ $ ~/scri nico ~ $ ~/scrip nico ~ $ ~/scripts/ nico ~ $ ~/scripts/c nico ~ $ ~/scripts/co nico ~ $ ~/scripts/col nico ~ $ ~/scripts/colo nico ~ $ ~/scripts/colors nico ~ $ ~/scripts/colors_ nico ~ $ ~/scripts/colors_2 nico ~ $ ~/scripts/colors_25 nico ~ $ ~/scripts/colors_256 nico ~ $ ~/scripts/colors_256.sh                                                                                                                                                                nico ~ $ ~/scripts/t nico ~ $ ~/scripts/tr nico ~ $ ~/scripts/tru nico ~ $ ~/scripts/true_colors. nico ~ $ ~/scripts/true_colors.s nico ~ $ ~/scripts/true_colors.sh nico ~ $ ~/scripts/true_colors.sh  nico ~ $ t nico ~ $ te nico ~ $ ter nico ~ $ term nico ~ $ termm nico ~ $ termmt nico ~ $ termm                                                                    nico ~ $ term                                                                     nico ~ $ termt                                                                    nico ~ $ termtosvg                                                                nico ~ $ termtosvg                                                                nico ~ $ termtosvg -                                                              nico ~ $ termtosvg --                                                             nico ~ $ termtosvg --h                                                            nico ~ $ termtosvg --he                                                           nico ~ $ termtosvg --hel                                                          nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help                                                         nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help |                                                       nico ~ $ termtosvg --help | l                                                     nico ~ $ termtosvg --help | lo                                                    nico ~ $ termtosvg --help | loc                                                   nico ~ $ termtosvg --help | locl                                                  nico ~ $ termtosvg --help | lol                                                   nico ~ $ termtosvg --help | lolc                                                  nico ~ $ termtosvg --help | lolca                                                 nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [-- nico ~ $ ~/scripts/colors_256.sh                                                                 nico ~ $ ~/scripts/true_colors.sh                                                                              nico ~ $ termtosvg --help | lolcat                                                usage: termtosvg [output_file] [--theme THEME] [--help Record a ter usage: termtosvg [output_file] [--theme THEME] [--help] [--verbose]Record a terminal session and render an SVG anim Record a terminal session and render an SVG animation on the flypositional    output_file    optiona positional arguments:  output_file    optional filename of the SVG animation; if missi                    output_file    optional filename of the SVG animation; if missing, a random                 filename will be automatically gene                    filename will be automatically generatedoptional arguments:  -h, --help     show this help    -h, --help     show this help message and exit  --theme THEME  color theme used to render the te                            classic-dark, clas   --theme THEME  color theme used to render the terminal session (circus,                 classic-dark, classic-light, dracula,                                 material, monokai, solari                  classic-dark, classic-light, dracula, isotope, marrakesh,                 material, monokai, solarized-dark, solarized-light, zenburn)                  material, monokai, solarized-dark, solarized-light, zenburn)  -v, --verbose  increase log mess See also 'termtosvg re   -v, --verbose  increase log messages verbositySee also 'termtosvg record --help' and 'termtosvg See also 'termtosvg record --help' and 'termtosvg render --help'nico ~ $ e nico ~ $ ex nico ~ $ exi nico ~ $ exit nico ~ $ exitexit \ No newline at end of file diff --git a/examples/htop.svg b/examples/htop.svg index 71fd5a0..87f8ef4 100644 --- a/examples/htop.svg +++ b/examples/htop.svg @@ -1,16 +1,29 @@ - - minimal - - - Minimal template - - + nico ~ $  nico ~ $ h nico ~ $ ht nico ~ $ hto nico ~ $ htop  nico ~ $ htop  1  [|||||||||||||||||||||||||100.0%]   Tasks: 391 running2  [0.0%]   Load average: 0.33 0.32 0.30 3  [0.0%]   Uptime: 09:45:004  [0.0%]29184 nico20   0 21412  4192  3420 160.  0.1  0:00.04 │  │              └    1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash3  [|||5.3%]   Uptime: 09:45:0227104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27173 nico20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash2  [|||7.4%]   Load average: 0.33 0.32 0.30 27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico20   0 21412  4192  3420  0.7  0.1  0:00.05 │  │              └  1  [||||                       6.5%]   Tasks: 391 running2  [|||7.4%]   Load average: 0.31 0.32 0.30 3  [|||5.3%]   Uptime: 09:45:034  [||5.3%]27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us29184 nico       20   0 21412  4192  3420 R  0.7  0.1  0:00.05 │  │              └23028 nico20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash                                                                                    1  [||                         6.0%]   Tasks: 391 running2  [|||6.5%]   Load average: 0.31 0.32 0.30 3  [|||8.4%]   Uptime: 09:45:034  [|||6.4%]Mem[|||||||||||||||||   2.45G/7.74G]Swp[0K/0K]  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.87 │  │  └─ python /us27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.06 │  │              └23028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        F1Help  F2Setup F3SearchF4FilterF5SortedF6CollapF7Nice -F8Nice +F9Kill  F10Quit    3  [|||8.4%]   Uptime: 09:45:0423028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto  759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user    710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user   3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service 3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la3  [|||8.4%]   Uptime: 09:45:05  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       1  [|||                        7.6%]   Tasks: 391 running2  [|||5.2%]   Load average: 0.31 0.32 0.30 3  [|||6.4%]   Uptime: 09:45:054  [|| 5.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.45 ├─ compton -b        711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s3  [|||6.4%]   Uptime: 09:45:06  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        1  [||||                       9.8%]   Tasks: 392 running2  [|||7.3%]   Load average: 0.31 0.32 0.30 3  [|||7.4%]   Uptime: 09:45:074  [|||6.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s29184 nico       20   0 21412  4192  3420 R  1.2  0.1  0:00.10 │  │              └29184 nico       20   0 21412  4192  3420  1.2  0.1  0:00.10 │  │              └3  [|||7.4%]   Uptime: 09:45:0829180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth29180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us2  [|||7.3%]   Load average: 0.28 0.31 0.30 27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us  1  [|||||                     12.7%]   Tasks: 391 running2  [|||8.2%]   Load average: 0.28 0.31 0.30 3  [||||||13.9%]   Uptime: 09:45:084  [|||||13.2%]23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.88 │  │  └─ python /us29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.11 │  │              └3  [||||||13.9%]   Uptime: 09:45:0923027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            3  [||||||13.9%]   Uptime: 09:45:1027170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us3  [|||    8.6%]   Uptime: 09:45:10  1  [||||                       8.8%]   Tasks: 391 running2  [||||9.6%]   Load average: 0.28 0.31 0.30 3  [|||    8.6%]   Uptime: 09:45:114  [|||   7.5%]29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.12 │  │              └nico ~ $                                                                           nico ~ $ e                                                                         nico ~ $ ex                                                                        nico ~ $ exi                                                                         1  [|||                        5.0%]   Tasks: 392 running2  [||  5.4%]   Load average: 0.28 0.31 0.30 3  [||||  10.8%]   Uptime: 09:45:124  [|||   7.0%]29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.8  0.1  0:00.14 │  │              └nico ~ $ exit                                                                      nico ~ $ exit                                                                      exit +text {dominant-baseline: text-before-edge}]]>nico ~ $  nico ~ $ h nico ~ $ ht nico ~ $ hto nico ~ $ htop  nico ~ $ htop  1  [|||||||||||||||||||||||||100.0%]   Tasks: 391 running2  [0.0%]   Load average: 0.33 0.32 0.30 3  [0.0%]   Uptime: 09:45:004  [0.0%]29184 nico20   0 21412  4192  3420 160.  0.1  0:00.04 │  │              └    1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash3  [|||5.3%]   Uptime: 09:45:0227104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us27173 nico20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash2  [|||7.4%]   Load average: 0.33 0.32 0.30 27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico20   0 21412  4192  3420  0.7  0.1  0:00.05 │  │              └  1  [||||                       6.5%]   Tasks: 391 running2  [|||7.4%]   Load average: 0.31 0.32 0.30 3  [|||5.3%]   Uptime: 09:45:034  [||5.3%]27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.86 │  │  └─ python /us29184 nico       20   0 21412  4192  3420 R  0.7  0.1  0:00.05 │  │              └23028 nico20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash                                                                                    1  [||                         6.0%]   Tasks: 391 running2  [|||6.5%]   Load average: 0.31 0.32 0.30 3  [|||8.4%]   Uptime: 09:45:034  [|||6.4%]Mem[|||||||||||||||||   2.45G/7.74G]Swp[0K/0K]  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command                1 root       20   0  229M  8792  6896 S  0.0  0.1  0:06.21 init               23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.17 ├─ tmux            27104 nico       20   0 16256  4132  3388 S  0.0  0.1  0:00.01 │  ├─ -bash        27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.87 │  │  └─ python /us27173 nico       20   0 16244  4080  3364 S  0.0  0.1  0:00.08 │  │     └─ bash   29180 nico       20   0  104M 26700  8640 S  0.0  0.3  0:00.27 │  │        └─ pyth29183 nico       20   0 16124  3740  3264 S  0.0  0.0  0:00.00 │  │           └─ b29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.06 │  │              └23028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        F1Help  F2Setup F3SearchF4FilterF5SortedF6CollapF7Nice -F8Nice +F9Kill  F10Quit    3  [|||8.4%]   Uptime: 09:45:0423028 nico       20   0 16256  4060  3308 S  0.0  0.1  0:00.24 │  └─ -bash        27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto27086 nico       20   0  180M 16268 12144 S  0.0  0.2  0:00.02 │     └─ vim termto  759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        759 nico       20   0  164M 37300 18668 S  1.2  0.5  6:56.44 ├─ compton -b        710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user    710 nico       20   0 79188  7880  6668 S  0.0  0.1  0:00.01 ├─ systemd --user   3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service 3225 nico       20   0  180M  4892  4364 S  0.0  0.1  0:00.00 │  ├─ dconf-service  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la3  [|||8.4%]   Uptime: 09:45:05  818 nico       20   0  336M  5104  4512 S  0.0  0.1  0:00.00 │  ├─ at-spi-bus-la  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  807 nico       20   0 32420  3212  2928 S  0.0  0.0  0:00.13 │  ├─ dbus-daemon -  711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       1  [|||                        7.6%]   Tasks: 391 running2  [|||5.2%]   Load average: 0.31 0.32 0.30 3  [|||6.4%]   Uptime: 09:45:054  [|| 5.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.45 ├─ compton -b        711 nico       20   0  138M  2160     4 S  0.0  0.0  0:00.00 │  └─ (sd-pam)       698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     698 root       20   0 71312  3124  2580 S  0.0  0.0  0:00.19 ├─ login -- nico     716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s3  [|||6.4%]   Uptime: 09:45:06  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        1  [||||                       9.8%]   Tasks: 392 running2  [|||7.3%]   Load average: 0.31 0.32 0.30 3  [|||7.4%]   Uptime: 09:45:074  [|||6.2%]  759 nico       20   0  164M 37300 18668 S  0.6  0.5  6:56.46 ├─ compton -b        716 nico       20   0 13872  3348  2900 S  0.0  0.0  0:00.01 │  └─ sh /usr/bin/s29184 nico       20   0 21412  4192  3420 R  1.2  0.1  0:00.10 │  │              └29184 nico       20   0 21412  4192  3420  1.2  0.1  0:00.10 │  │              └3  [|||7.4%]   Uptime: 09:45:0829180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth29180 nico       20   0  104M 26716  8640 S  0.6  0.3  0:00.28 │  │        └─ pyth27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us2  [|||7.3%]   Load average: 0.28 0.31 0.30 27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.87 │  │  └─ python /us  1  [|||||                     12.7%]   Tasks: 391 running2  [|||8.2%]   Load average: 0.28 0.31 0.30 3  [||||||13.9%]   Uptime: 09:45:084  [|||||13.2%]23027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            27170 nico       20   0  104M 26948  8816 S  0.6  0.3  0:00.88 │  │  └─ python /us29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.11 │  │              └3  [||||||13.9%]   Uptime: 09:45:0923027 nico       20   0 30252  5040  3096 S  0.0  0.1  0:02.18 ├─ tmux            3  [||||||13.9%]   Uptime: 09:45:1027170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us27170 nico       20   0  104M 26948  8816 S  0.0  0.3  0:00.88 │  │  └─ python /us3  [|||    8.6%]   Uptime: 09:45:10  1  [||||                       8.8%]   Tasks: 391 running2  [||||9.6%]   Load average: 0.28 0.31 0.30 3  [|||    8.6%]   Uptime: 09:45:114  [|||   7.5%]29184 nico       20   0 21412  4192  3420  0.6  0.1  0:00.12 │  │              └nico ~ $                                                                           nico ~ $ e                                                                         nico ~ $ ex                                                                        nico ~ $ exi                                                                         1  [|||                        5.0%]   Tasks: 392 running2  [||  5.4%]   Load average: 0.28 0.31 0.30 3  [||||  10.8%]   Uptime: 09:45:124  [|||   7.0%]29180 nico       20   0  104M 26720  8640 S  0.0  0.3  0:00.28 │  │        └─ pyth29184 nico       20   0 21412  4192  3420  0.8  0.1  0:00.14 │  │              └nico ~ $ exit                                                                      nico ~ $ exit                                                                      exit \ No newline at end of file diff --git a/examples/ipython.svg b/examples/ipython.svg index 6d9eb63..d4688ef 100644 --- a/examples/ipython.svg +++ b/examples/ipython.svg @@ -1,16 +1,29 @@ - - minimal - - - Minimal template - - + nico ~ $  nico ~ $ i nico ~ $ ip nico ~ $ ipy nico ~ $ ipyt nico ~ $ ipyth nico ~ $ ipytho nico ~ $ ipython  In [1]:                                                                           In [1]: i                                                                         In [1]: im                                                                        In [1]: imp                                                                       In [1]: impo                                                                      In [1]: impor                                                                     In [1]: import                                                                    In [1]: import                                                                    In [1]: import t                                                                  In [1]: import ti                                                                 In [1]: import tim                                                                In [1]: import time                                                               In [2]:                                                                           In [2]: f                                                                         In [2]: fo                                                                        In [2]: for                                                                       In [2]: for                                                                       In [2]: for i                                                                     In [2]: for i                                                                     In [2]: for i i                                                                   In [2]: for i in                                                                  In [2]: for i in                                                                  In [2]: for i in r                                                                In [2]: for i in ra                                                               In [2]: for i in ran                                                              In [2]: for i in rang                                                             In [2]: for i in range                                                            In [2]: for i in range(                                                           In [2]: for i in range(4                                                          In [2]: for i in range(40                                                         In [2]: for i in range(40                                                       In [2]: for i in range(40):                                                          ...:         ...:     p    ...:     pr    ...:     pri    ...:     prin    ...:     print    ...:     print(    ...:     print('    ...:     print('=    ...:     print('='    ...:     print('='     ...:     print('=' *    ...:     print('=' *     ...:     print('=' * i    ...:     print('=' * i     ...:     print('=' * i +    ...:     print('=' * i +     ...:     print('=' * i + '    ...:     print('=' * i + '+    ...:     print('=' * i + '+'    ...:     print('=' * i + '+'     ...:     print('=' * i + '+'      ...:     print('=' * i + '+' +    ...:     print('=' * i + '+' +     ...:     print('=' * i + '+' + '    ...:     print('=' * i + '+' + '=    ...:     print('=' * i + '+' + '='    ...:     print('=' * i + '+' + '='     ...:     print('=' * i + '+' + '=' *    ...:     print('=' * i + '+' + '=' *     ...:     print('=' * i + '+' + '=' * (    ...:     print('=' * i + '+' + '=' * (4    ...:     print('=' * i + '+' + '=' * (40    ...:     print('=' * i + '+' + '=' * (40     ...:     print('=' * i + '+' + '=' * (40-    ...:     print('=' * i + '+' + '=' * (40-i    ...:     print('=' * i + '+' + '=' * (40-i   ...:     print('=' * i + '+' + '=' * (40-i)   ...:     t    ...:     ti    ...:     tim    ...:     time    ...:     time.    ...:     time.s  time.sleep       time.strptime       ...:     time.sleep  time.sleep       time.strptime     time.strftime    time.struct_time  <unknown>    ...:     time.sleep(    ...:     time.sleep(0    ...:     time.sleep(0.    ...:     time.sleep(0.1    ...:     time.sleep(0.1                                   In [2]: for i in range(40):                                                          ...:     print('=' * i + '+' + '=' * (40-i))   ...:     time.sleep(0.1)   ...:                                                                                                                                                  nico ~ $ ipythonPython 3.6.5 (default, May 11 2018, 04:00:52) Type 'copyright', 'credits' or 'license' for more informationIPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.In [1]: import time                                                                                                                                                    ...:                                        +========================================                                         =+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=In [3]:                                                                           In [3]: e                                                                         In [3]: ex                                                                        In [3]: exi                                                                       In [3]: exit                                                                      nico ~ $                                                                          nico ~ $ e                                                                        nico ~ $ ex                                                                       nico ~ $ exi                                                                      In [3]: exit                                                                      nico ~ $ exit                                                                     nico ~ $ exit                                                                     exit +text {dominant-baseline: text-before-edge}]]>nico ~ $  nico ~ $ i nico ~ $ ip nico ~ $ ipy nico ~ $ ipyt nico ~ $ ipyth nico ~ $ ipytho nico ~ $ ipython  In [1]:                                                                           In [1]: i                                                                         In [1]: im                                                                        In [1]: imp                                                                       In [1]: impo                                                                      In [1]: impor                                                                     In [1]: import                                                                    In [1]: import                                                                    In [1]: import t                                                                  In [1]: import ti                                                                 In [1]: import tim                                                                In [1]: import time                                                               In [2]:                                                                           In [2]: f                                                                         In [2]: fo                                                                        In [2]: for                                                                       In [2]: for                                                                       In [2]: for i                                                                     In [2]: for i                                                                     In [2]: for i i                                                                   In [2]: for i in                                                                  In [2]: for i in                                                                  In [2]: for i in r                                                                In [2]: for i in ra                                                               In [2]: for i in ran                                                              In [2]: for i in rang                                                             In [2]: for i in range                                                            In [2]: for i in range(                                                           In [2]: for i in range(4                                                          In [2]: for i in range(40                                                         In [2]: for i in range(40)                                                        In [2]: for i in range(40):                                                          ...:         ...:     p    ...:     pr    ...:     pri    ...:     prin    ...:     print    ...:     print(    ...:     print('    ...:     print('=    ...:     print('='    ...:     print('='     ...:     print('=' *    ...:     print('=' *     ...:     print('=' * i    ...:     print('=' * i     ...:     print('=' * i +    ...:     print('=' * i +     ...:     print('=' * i + '    ...:     print('=' * i + '+    ...:     print('=' * i + '+'    ...:     print('=' * i + '+'     ...:     print('=' * i + '+'      ...:     print('=' * i + '+' +    ...:     print('=' * i + '+' +     ...:     print('=' * i + '+' + '    ...:     print('=' * i + '+' + '=    ...:     print('=' * i + '+' + '='    ...:     print('=' * i + '+' + '='     ...:     print('=' * i + '+' + '=' *    ...:     print('=' * i + '+' + '=' *     ...:     print('=' * i + '+' + '=' * (    ...:     print('=' * i + '+' + '=' * (4    ...:     print('=' * i + '+' + '=' * (40    ...:     print('=' * i + '+' + '=' * (40     ...:     print('=' * i + '+' + '=' * (40-    ...:     print('=' * i + '+' + '=' * (40-i    ...:     print('=' * i + '+' + '=' * (40-i)    ...:     print('=' * i + '+' + '=' * (40-i))    ...:     t    ...:     ti    ...:     tim    ...:     time    ...:     time.    ...:     time.s  time.sleep       time.strptime       ...:     time.sleep  time.sleep       time.strptime     time.strftime    time.struct_time  <unknown>    ...:     time.sleep(    ...:     time.sleep(0    ...:     time.sleep(0.    ...:     time.sleep(0.1    ...:     time.sleep(0.1)                                    In [2]: for i in range(40):                                                          ...:     print('=' * i + '+' + '=' * (40-i))   ...:     time.sleep(0.1)   ...:                                                                                                                                                  nico ~ $ ipythonPython 3.6.5 (default, May 11 2018, 04:00:52) Type 'copyright', 'credits' or 'license' for more informationIPython 6.3.1 -- An enhanced Interactive Python. Type '?' for help.In [1]: import time                                                                                                                                                    ...:                                        +========================================                                         =+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=========================================+=In [3]:                                                                           In [3]: e                                                                         In [3]: ex                                                                        In [3]: exi                                                                       In [3]: exit                                                                      nico ~ $                                                                          nico ~ $ e                                                                        nico ~ $ ex                                                                       nico ~ $ exi                                                                      In [3]: exit                                                                      nico ~ $ exit                                                                     nico ~ $ exit                                                                     exit \ No newline at end of file diff --git a/examples/unittest.svg b/examples/unittest.svg index 55c4990..00cb1bf 100644 --- a/examples/unittest.svg +++ b/examples/unittest.svg @@ -1,16 +1,29 @@ - - minimal - - - Minimal template - - + nico ~/termtosvg $  nico ~/termtosvg $ m nico ~/termtosvg $ ma nico ~/termtosvg $ mak nico ~/termtosvg $ make nico ~/termtosvg $ make  nico ~/termtosvg $ make t nico ~/termtosvg $ make te nico ~/termtosvg $ make tes nico ~/termtosvg $ make test nico ~/termtosvg $ make tests  nico ~/termtosvg $ make tests(test -d .venv || python -m venv .venv). .venv/bin/activate && \    pip install -U -e .[dev]Obtaining file:///home/nico/termtosvgRequirement already up-to-date: setuptools in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: pyte in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: python-xlib in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: svgwrite in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: coverage in ./.venv/lib/python3.6/site-packages (fRequirement already up-to-date: twine in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: wheel in ./.venv/lib/python3.6/site-packages (fromRequirement already up-to-date: wcwidth in ./.venv/lib/python3.6/site-packages (from pyte->termtosvg==0.1.0)Requirement already up-to-date: six>=1.10.0 in ./.venv/lib/python3.6/site-packages (from python-xlib->termtosvg==0.1.0)Requirement already up-to-date: pyparsing>=2.0.1 in ./.venv/lib/python3.6/site-packages (from svgwrite->termtosvg==0.1.0)Requirement already up-to-date: requests!=2.15,!=2.16,>=2.5.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: requests-toolbelt>=0.8.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: tqdm>=4.14 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: pkginfo>=1.4.2 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: certifi>=2017.4.17 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: idna<2.8,>=2.5 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: urllib3<1.24,>=1.21.1 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: chardet<3.1.0,>=3.0.2 in ./.venv/lib/python3.6/sitInstalling collected packages: termtosvg  Found existing installation: termtosvg 0.1.0    Uninstalling termtosvg-0.1.0:      Successfully uninstalled termtosvg-0.1.0  Running setup.py develop for termtosvgSuccessfully installed termtosvgYou are using pip version 9.0.3, however version 10.0.1 is available.You should consider upgrading via the 'pip install --upgrade pip' command.    pip freeze && \    coverage run --branch --source termtosvg -m unittest -v && \    coverage report && \    coverage htmlpython-xlib==0.23pytz==2018.4requests==2.19.1requests-toolbelt==0.8.0rsa==3.4.2six==1.11.0svgwrite==1.1.12-e git+git@github.com:nbedos/termtosvg.git@dab7f522c126e9938e896d023d8be453f0dcf1b9#egg=termtosvgtinydb==3.9.0.post1tinyrecord==0.1.5tox==3.0.0tqdm==4.23.4twine==1.11.0urllib3==1.23virtualenv==16.0.0wcwidth==0.1.7wrapt==1.10.11test_main (tests.test___main__.TestMain) ...  test_main (tests.test___main__.TestMain) ... Recording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_3vqhnplh.castRecording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_s7tgsv75.castRendering startedRendering ended, SVG animation is /tmp/termtosvg_wts11qev.svgRendering ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgRendering ended, SVG animation is /tmp/termtosvg_i8zp1z7w.svgLogging to /tmp/termtosvg.logRecording ended, SVG animation is /tmp/termtosvg_fkz0r2vk.svgRecording ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgoktest_parse (tests.test___main__.TestMain) ...  test_parse (tests.test___main__.TestMain) ... oktest__render_characters (tests.test_anim.TestAnim) ... oktest__render_line_bg_colors (tests.test_anim.TestAnim) ...  test__render_line_bg_colors (tests.test_anim.TestAnim) ... oktest_from_pyte (tests.test_anim.TestAnim) ... oktest_render_animation (tests.test_anim.TestAnim) ...  test_render_animation (tests.test_anim.TestAnim) ... oktest_serialize_css_dict (tests.test_anim.TestAnim) ... oktest_AsciiCastEvent (tests.test_asciicast.TestAsciicast) ... oktest_AsciiCastHeader (tests.test_asciicast.TestAsciicast) ... oktest_from_json (tests.test_asciicast.TestAsciicast) ...  test_from_json (tests.test_asciicast.TestAsciicast) ... oktest_from_xresources (tests.test_asciicast.TestAsciicast) ...  test_from_xresources (tests.test_asciicast.TestAsciicast) ... oktest_to_json (tests.test_asciicast.TestAsciicast) ... oktest__group_by_time (tests.test_term.TestTerm) ... oktest__record (tests.test_term.TestTerm) ...  test__record (tests.test_term.TestTerm) ... oktest_default_themes (tests.test_term.TestTerm) ...  test_default_themes (tests.test_term.TestTerm) ... oktest_get_configuration (tests.test_term.TestTerm) ...  test_get_configuration (tests.test_term.TestTerm) ... oktest_record (tests.test_term.TestTerm) ...  test_record (tests.test_term.TestTerm) ... oktest_replay (tests.test_term.TestTerm) ...  test_replay (tests.test_term.TestTerm) ... ok----------------------------------------------------------------------Ran 18 tests in 5.164sOKnico ~/termtosvg $ e nico ~/termtosvg $ ex nico ~/termtosvg $ exi Name                     Stmts   Miss Branch BrPart  Cover----------------------------------------------------------termtosvg/__init__.py        0      0      0      0   100%termtosvg/__main__.py      106      4     38      4    94%termtosvg/anim.py          146      3     60      3    97%termtosvg/asciicast.py      93      6     38      3    93%termtosvg/term.py          192     13     66      8    91%TOTAL                      537     26    202     18    94%nico ~/termtosvg $ exit nico ~/termtosvg $ exitexit +text {dominant-baseline: text-before-edge}]]>nico ~/termtosvg $  nico ~/termtosvg $ m nico ~/termtosvg $ ma nico ~/termtosvg $ mak nico ~/termtosvg $ make nico ~/termtosvg $ make  nico ~/termtosvg $ make t nico ~/termtosvg $ make te nico ~/termtosvg $ make tes nico ~/termtosvg $ make test nico ~/termtosvg $ make tests  nico ~/termtosvg $ make tests(test -d .venv || python -m venv .venv). .venv/bin/activate && \    pip install -U -e .[dev]Obtaining file:///home/nico/termtosvgRequirement already up-to-date: setuptools in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: pyte in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: python-xlib in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: svgwrite in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: coverage in ./.venv/lib/python3.6/site-packages (fRequirement already up-to-date: twine in ./.venv/lib/python3.6/site-packages (from termtosvg==0.1.0)Requirement already up-to-date: wheel in ./.venv/lib/python3.6/site-packages (fromRequirement already up-to-date: wcwidth in ./.venv/lib/python3.6/site-packages (from pyte->termtosvg==0.1.0)Requirement already up-to-date: six>=1.10.0 in ./.venv/lib/python3.6/site-packages (from python-xlib->termtosvg==0.1.0)Requirement already up-to-date: pyparsing>=2.0.1 in ./.venv/lib/python3.6/site-packages (from svgwrite->termtosvg==0.1.0)Requirement already up-to-date: requests!=2.15,!=2.16,>=2.5.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: requests-toolbelt>=0.8.0 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: tqdm>=4.14 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: pkginfo>=1.4.2 in ./.venv/lib/python3.6/site-packages (from twine->termtosvg==0.1.0)Requirement already up-to-date: certifi>=2017.4.17 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: idna<2.8,>=2.5 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: urllib3<1.24,>=1.21.1 in ./.venv/lib/python3.6/site-packages (from requests!=2.15,!=2.16,>=2.5.0->twine->termtosvg==0.1.0)Requirement already up-to-date: chardet<3.1.0,>=3.0.2 in ./.venv/lib/python3.6/sitInstalling collected packages: termtosvg  Found existing installation: termtosvg 0.1.0    Uninstalling termtosvg-0.1.0:      Successfully uninstalled termtosvg-0.1.0  Running setup.py develop for termtosvgSuccessfully installed termtosvgYou are using pip version 9.0.3, however version 10.0.1 is available.You should consider upgrading via the 'pip install --upgrade pip' command.    pip freeze && \    coverage run --branch --source termtosvg -m unittest -v && \    coverage report && \    coverage htmlpython-xlib==0.23pytz==2018.4requests==2.19.1requests-toolbelt==0.8.0rsa==3.4.2six==1.11.0svgwrite==1.1.12-e git+git@github.com:nbedos/termtosvg.git@dab7f522c126e9938e896d023d8be453f0dcf1b9#egg=termtosvgtinydb==3.9.0.post1tinyrecord==0.1.5tox==3.0.0tqdm==4.23.4twine==1.11.0urllib3==1.23virtualenv==16.0.0wcwidth==0.1.7wrapt==1.10.11test_main (tests.test___main__.TestMain) ...  test_main (tests.test___main__.TestMain) ... Recording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_3vqhnplh.castRecording started, enter "exit" command or Control-D to endRecording ended, cast file is /tmp/termtosvg_s7tgsv75.castRendering startedRendering ended, SVG animation is /tmp/termtosvg_wts11qev.svgRendering ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgRendering ended, SVG animation is /tmp/termtosvg_i8zp1z7w.svgLogging to /tmp/termtosvg.logRecording ended, SVG animation is /tmp/termtosvg_fkz0r2vk.svgRecording ended, SVG animation is /tmp/termtosvg_s7tgsv75.svgoktest_parse (tests.test___main__.TestMain) ...  test_parse (tests.test___main__.TestMain) ... oktest__render_characters (tests.test_anim.TestAnim) ... oktest__render_line_bg_colors (tests.test_anim.TestAnim) ...  test__render_line_bg_colors (tests.test_anim.TestAnim) ... oktest_from_pyte (tests.test_anim.TestAnim) ... oktest_render_animation (tests.test_anim.TestAnim) ...  test_render_animation (tests.test_anim.TestAnim) ... oktest_serialize_css_dict (tests.test_anim.TestAnim) ... oktest_AsciiCastEvent (tests.test_asciicast.TestAsciicast) ... oktest_AsciiCastHeader (tests.test_asciicast.TestAsciicast) ... oktest_from_json (tests.test_asciicast.TestAsciicast) ...  test_from_json (tests.test_asciicast.TestAsciicast) ... oktest_from_xresources (tests.test_asciicast.TestAsciicast) ...  test_from_xresources (tests.test_asciicast.TestAsciicast) ... oktest_to_json (tests.test_asciicast.TestAsciicast) ... oktest__group_by_time (tests.test_term.TestTerm) ... oktest__record (tests.test_term.TestTerm) ...  test__record (tests.test_term.TestTerm) ... oktest_default_themes (tests.test_term.TestTerm) ...  test_default_themes (tests.test_term.TestTerm) ... oktest_get_configuration (tests.test_term.TestTerm) ...  test_get_configuration (tests.test_term.TestTerm) ... oktest_record (tests.test_term.TestTerm) ...  test_record (tests.test_term.TestTerm) ... oktest_replay (tests.test_term.TestTerm) ...  test_replay (tests.test_term.TestTerm) ... ok----------------------------------------------------------------------Ran 18 tests in 5.164sOKnico ~/termtosvg $ e nico ~/termtosvg $ ex nico ~/termtosvg $ exi Name                     Stmts   Miss Branch BrPart  Cover----------------------------------------------------------termtosvg/__init__.py        0      0      0      0   100%termtosvg/__main__.py      106      4     38      4    94%termtosvg/anim.py          146      3     60      3    97%termtosvg/asciicast.py      93      6     38      3    93%termtosvg/term.py          192     13     66      8    91%TOTAL                      537     26    202     18    94%nico ~/termtosvg $ exit nico ~/termtosvg $ exitexit \ No newline at end of file diff --git a/fiddle/fiddle.css b/fiddle/fiddle.css deleted file mode 100644 index d2a1ff4..0000000 --- a/fiddle/fiddle.css +++ /dev/null @@ -1,2 +0,0 @@ -svg { border: 1px solid #000; margin: 1.5em; } -.slidable { cursor: w-resize; } diff --git a/fiddle/fiddle.js b/fiddle/fiddle.js deleted file mode 100644 index cdf3466..0000000 --- a/fiddle/fiddle.js +++ /dev/null @@ -1,44 +0,0 @@ -var price_chart = document.getElementsByTagName('svg')[0]; -var screen = price_chart.getElementsByTagName('svg')[0]; -var pt = price_chart.createSVGPoint(); - -console.log(price_chart) -console.log(screen) - -function mx(evt){ - pt.x = evt.clientX; - return pt.matrixTransform(price_chart.getScreenCTM().inverse()); -} - -// HTML elements -var slider_1 = document.querySelector('#slider_1'); -console.log(slider_1) - -var dragging = false; -slider_1.addEventListener('mousedown',function(evt){ - price_chart.pauseAnimations() - var offset = mx(evt); - dragging = true; - offset.x = slider_1.x.baseVal.value - offset.x; - var move = function(evt){ - var now = mx(evt); - //var x = offset.x + now.x; - var x = now.x; - var limitLower = 0; - var limitUpper = 300; - console.log(evt) - if ( x < limitLower || x > limitUpper ) { - return; - } - //slider_1.x.baseVal.value = x; - //x = Math.abs(x)*scale; - price_chart.setCurrentTime(10.0 * x / 300.0) - }; - - price_chart.addEventListener('mousemove',move,false); - document.documentElement.addEventListener('mouseup',function(){ - dragging = false; - price_chart.unpauseAnimations() - price_chart.removeEventListener('mousemove',move,false); - },false); -},false); diff --git a/fiddle/fiddle.svg b/fiddle/fiddle.svg deleted file mode 100644 index 0839ab5..0000000 --- a/fiddle/fiddle.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/termtosvg/anim.py b/termtosvg/anim.py index 165af97..04f4090 100644 --- a/termtosvg/anim.py +++ b/termtosvg/anim.py @@ -4,7 +4,7 @@ import pkgutil from collections import namedtuple from itertools import groupby -from typing import Dict, List, Iterable, Iterator, Union, Tuple, Any +from typing import Dict, List, Iterable, Iterator, Union, Tuple import pyte.graphics import pyte.screens @@ -15,8 +15,8 @@ # from FG_BG_256[16] (which is also black #000000 but should be displayed as is). _COLORS = ['black', 'red', 'green', 'brown', 'blue', 'magenta', 'cyan', 'white'] _BRIGHTCOLORS = ['bright{}'.format(color) for color in _COLORS] -ALL_COLORS = _COLORS + _BRIGHTCOLORS -pyte.graphics.FG_BG_256 = ALL_COLORS + pyte.graphics.FG_BG_256[16:] +NAMED_COLORS = _COLORS + _BRIGHTCOLORS +pyte.graphics.FG_BG_256 = NAMED_COLORS + pyte.graphics.FG_BG_256[16:] logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) @@ -45,29 +45,19 @@ class TemplateError(Exception): class CharacterCell(_CharacterCell): @classmethod - def from_pyte(cls, char, palette): - # type: (pyte.screens.Char, Dict[Any, str]) -> CharacterCell + def from_pyte(cls, char): + # type: (pyte.screens.Char) -> CharacterCell """Create a CharacterCell from a pyte character""" - # Map named colors to their respective number - color_numbers = dict(zip(ALL_COLORS, range(len(ALL_COLORS)))) if char.fg == 'default': - text_color = palette['foreground'] + text_color = 'foreground' else: if char.bold and not str(char.fg).startswith('bright'): - search_color = 'bright{}'.format(char.fg) + named_color = 'bright{}'.format(char.fg) else: - search_color = char.fg - - if search_color in color_numbers: - # NAMED COLORS - if color_numbers[search_color] in palette: - # Case for color numbers < 8 (since the palette has at least the first 8 colors) - # or for 16-color palette (all named colors in the palette) - color_number = color_numbers[search_color] - else: - # Case for color numbers >= 8 and 8-color palette: fallback to non bright color - color_number = color_numbers[search_color] % 8 - text_color = palette[color_number] + named_color = char.fg + + if named_color in NAMED_COLORS: + text_color = 'color{}'.format(NAMED_COLORS.index(named_color)) elif len(char.fg) == 6: # HEXADECIMAL COLORS # raise ValueError if char.fg is not an hexadecimal number @@ -77,10 +67,9 @@ def from_pyte(cls, char, palette): raise ValueError('Invalid foreground color: {}'.format(char.fg)) if char.bg == 'default': - background_color = palette['background'] - elif char.bg in color_numbers: - # Named colors - background_color = palette[color_numbers[char.bg]] + background_color = 'background' + elif char.bg in NAMED_COLORS: + background_color = 'color{}'.format(NAMED_COLORS.index(char.bg)) elif len(char.bg) == 6: # Hexadecimal colors # raise ValueError if char.bg is not an hexadecimal number @@ -126,9 +115,13 @@ def make_rect_tag(column, length, height, cell_width, cell_height, background_co 'x': str(column * cell_width), 'y': str(height), 'width': str(length * cell_width), - 'height': str(cell_height), - 'fill': background_color + 'height': str(cell_height) } + + if background_color.startswith('#'): + attributes['fill'] = background_color + else: + attributes['class'] = background_color rect_tag = etree.Element('rect', attributes) return rect_tag @@ -164,12 +157,16 @@ def make_text_tag(column, attributes, text, cell_width): text_tag_attributes = { 'x': str(column * cell_width), 'textLength': str(len(text) * cell_width), - 'lengthAdjust': 'spacingAndGlyphs', - 'fill': attributes['color'] + 'lengthAdjust': 'spacingAndGlyphs' } if attributes['bold']: text_tag_attributes['font-weight'] = 'bold' + if attributes['color'].startswith('#'): + text_tag_attributes['fill'] = attributes['color'] + else: + text_tag_attributes['class'] = attributes['color'] + text_tag = etree.Element('text', text_tag_attributes) # Replace usual spaces with unbreakable spaces so that indenting the SVG does not mess up # the whole animation; this is somewhat better than the 'white-space: pre' CSS option @@ -195,8 +192,8 @@ def _render_characters(screen_line, cell_width): return text_tags -def build_style_tag(font, font_size, background_color): - # type: (str, int, str) -> etree.ElementBase +def build_style_tag(font, font_size): + # type: (str, int) -> etree.ElementBase css = { # Apply this style to each and every element since we are using coordinates that # depend on the size of the font @@ -207,10 +204,7 @@ def build_style_tag(font, font_size, background_color): }, 'text': { 'dominant-baseline': 'text-before-edge', - }, - '.background': { - 'fill': background_color, - }, + } } style_attributes = { @@ -413,7 +407,7 @@ def _render_animation(records, template, font, font_size, cell_width, cell_heigh svg_screen_tag.remove(child) def_tag = etree.SubElement(svg_screen_tag, 'defs') - style_tag = build_style_tag(font, font_size, header.background_color) + style_tag = build_style_tag(font, font_size) def_tag.append(style_tag) svg_screen_tag.append(BG_RECT_TAG) diff --git a/termtosvg/data/templates/carbon.svg b/termtosvg/data/templates/carbon.svg index 85be44f..4ee46a6 100644 --- a/termtosvg/data/templates/carbon.svg +++ b/termtosvg/data/templates/carbon.svg @@ -3,12 +3,6 @@ must be specified in user units (e.g width="123") --> - - carbon - - - carbon - @@ -16,55 +10,44 @@ must be specified in user units (e.g width="123") --> - - - - + + + + - + termtosvg is awesome! + text {dominant-baseline: text-before-edge}]]> diff --git a/termtosvg/data/templates/carbon_js.svg b/termtosvg/data/templates/carbon_js.svg index c930ac0..489ba38 100644 --- a/termtosvg/data/templates/carbon_js.svg +++ b/termtosvg/data/templates/carbon_js.svg @@ -9,65 +9,50 @@ :root { --animation-duration: 10000ms; --foreground-color: #f8f8f2; - --background-color: #272822; - --color0: #272822; - --color1: #f92672; - --color2: #a6e22e; - --color3: #f4bf75; - --color4: #66d9ef; - --color5: #ae81ff; - --color6: #a1efe4; - --color7: #f8f8f2; - --color8: #75715e; - --color9: #fd971f; - --color10: #383830; - --color11: #49483e; - --color12: #a59f85; - --color13: #f5f4f1; - --color14: #cc6633; - --color15: #f9f8f5}]]> + --background-color: #272822;}]]> - + @@ -76,21 +61,21 @@ - - - - + + + + - + termtosvg is awesome! + ]]> @@ -109,17 +94,17 @@ from="88" to="588" id="anim"/> - 0:00/0:00 + 0:00/0:00 - + - + - - + +