Coder Social home page Coder Social logo

jtdaugherty / tart Goto Github PK

View Code? Open in Web Editor NEW
380.0 11.0 19.0 520 KB

Tart - draw ASCII art in the terminal with your mouse!

License: BSD 3-Clause "New" or "Revised" License

Haskell 100.00%
terminal ascii art brick vty haskell tui mouse drawing ascii-art

tart's Introduction

tart - terminal art program

 _____  _    ____ _____  _
(_   _)/ \  |    (_   _)| |
  | | / ^ \ |  O  || |  |_|
  | |/ ___ \|  _ < | |   _
  |_|_/   \_|_| \_\|_|  |_|

Tart is a program that provides an image-editor-like interface to creating ASCII art - in the terminal, with your mouse! This program is written using my purely-functional terminal user interface toolkit, Brick.

Status

Expectation management: This is a fun hobby project that I spent time on when I first created it many years ago. Since then, I have only done a little bit to keep it working. Since it was (and still is) mostly intended as a proof of concept, and since I do not use the tool actively, I have not been putting much energy into maintaining it beyond keeping it building. While that isn't likely to change, I am happy to support people who want to contribute to the tool and I may have energy to fix small things as they are reported. Use at your own risk. If other tools are more mature or perform better, you are probably better off using them!

Building

tart is a Haskell project. You'll need GHC (preferably at least 8.2) and cabal-install (preferably at least 2.0). Then:

$ git clone https://github.com/jtdaugherty/tart.git
$ cd tart
$ cabal new-build
$ $(find . -name tart -type f)

By default, tart is built as both a library and a command-line tool. But if you want to use tart only for its Haskell library and avoid the additional executable dependencies, you can build with the libonly cabal build flag.

Features

  • Drawing tools: freehand, line, box, flood fill, text string
  • Utility tools: repaint, restyle, eyedropper, eraser
  • Multiple graphical styles for boxes
  • Named image layers with reordering, visibility toggling
  • Character selection for freehand and flood fill tools
  • Set foreground color, background color, and text style independently
  • Full mouse interaction and keyboard shortcuts
  • Paste text from clipboard into canvas
  • Undo and redo
  • Text styles: bold, blink, underline, reverse video
  • Load and save ASCII art files (binary)
  • Save plain versions of ASCII art for embedding in documents
  • Save color versions of ASCII art with terminal escape sequences for printing to terminals
  • Import existing plaintext files as the basis for new ASCII art files
  • Set arbitrary canvas size

Terminal Emulator Support

tart has been tested extensively with the following terminal emulators and is known to work well with them:

  • OS X: iTerm2
  • OS X: Terminal.app

Please let me know if you use tart with another emulator and let me know how well it works!

Keybindings

Tools / styles:

  • 0..9: select tool
  • y: open the attribute style selector
  • !/@/#/$: select attribute style
  • f/b: open foreground / background palette selectors
  • c: set tool drawing character (where applicable)
  • </>: decrease / increase tool size (where applicable)
  • Esc: cancel tool drag (e.g. box)

Canvas:

  • w/a/s/d: move canvas
  • C: re-center canvas
  • v: set canvas size
  • -/+: decrease / increase canvas size

Layers:

  • C-a: add new layer
  • C-r: rename current layer
  • C-n/C-p: select next/previous layer
  • C-x: delete selected layer
  • C-u/C-d: move current layer up / down
  • C-v: toggle selected layer's visibility
  • C-l: toggle visibility of layer list

General:

  • q: quit (and optionally save)
  • C-s: save
  • u: undo
  • r: redo
  • OS paste: paste text into canvas

How It Works

Tart requires a terminal with mouse support. You use various tools (such as freehand drawing, boxes, etc.) to draw ASCII pictures. You can set a current foreground and background color. You can also resize the drawing canvas to get the desired output size. When you're finished, you can save to disk, at which point Tart creates three files:

  • A binary file (say foo.tart) suitable for reloading with Tart for further editing later
  • A text file foo.color.txt containing the ASCII art with terminal color escape sequences, suitable for emitting to terminals
  • A text file foo.plain.txt containing the ASCII art without terminal color escape sequences, suitable for embedding in documentation

Contributing

If you decide to contribute, that's great! Here are some guidelines you should consider to make submitting patches easier for all concerned:

  • If you want to take on big things, talk to me first; let's have a design/vision discussion before you start coding. Create a GitHub issue and we can use that as the place to hash things out.
  • Please make changes consistent with the conventions I've used in the codebase.
  • Please adjust or provide Haddock and/or user guide documentation relevant to any changes you make.

tart's People

Contributors

cj-bc avatar jtdaugherty avatar juhp avatar kostmo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tart's Issues

customMain errors

I just tried to cabal install tart:

programs/Main.hs:112:13: error:
    • Couldn't match type ‘s0 -> IO s0’ with ‘IO a0’
      Expected type: App s0 e0 n0 -> IO a0
        Actual type: App s0 e0 n0 -> s0 -> IO s0
    • Probable cause: ‘customMain’ is applied to too few arguments
      In the second argument of ‘(.)’, namely
        ‘customMain mkVty (Just chan) application’
      In the first argument of ‘(=<<)’, namely
        ‘(void . customMain mkVty (Just chan) application)’
      In a stmt of a 'do' block:
        (void . customMain mkVty (Just chan) application)
          =<< mkInitialState chan c
    |
112 |     (void . customMain mkVty (Just chan) application) =<< mkInitialState chan c
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

programs/Main.hs:112:24: error:
    • Couldn't match expected type ‘V.Vty’ with actual type ‘IO V.Vty’
    • In the first argument of ‘customMain’, namely ‘mkVty’
      In the second argument of ‘(.)’, namely
        ‘customMain mkVty (Just chan) application’
      In the first argument of ‘(=<<)’, namely
        ‘(void . customMain mkVty (Just chan) application)’
    |
112 |     (void . customMain mkVty (Just chan) application) =<< mkInitialState chan c
    |                        ^^^^^

programs/Main.hs:112:31: error:
    • Couldn't match expected type ‘IO V.Vty’
                  with actual type ‘Maybe (Brick.BChan.BChan Types.AppEvent)’
    • In the second argument of ‘customMain’, namely ‘(Just chan)’
      In the second argument of ‘(.)’, namely
        ‘customMain mkVty (Just chan) application’
      In the first argument of ‘(=<<)’, namely
        ‘(void . customMain mkVty (Just chan) application)’
    |
112 |     (void . customMain mkVty (Just chan) application) =<< mkInitialState chan c
    |                               ^^^^^^^^^

programs/Main.hs:112:42: error:
    • Couldn't match expected type ‘Maybe (Brick.BChan.BChan e0)’
                  with actual type ‘App Types.AppState Types.AppEvent Types.Name’
    • In the third argument of ‘customMain’, namely ‘application’
      In the second argument of ‘(.)’, namely
        ‘customMain mkVty (Just chan) application’
      In the first argument of ‘(=<<)’, namely
        ‘(void . customMain mkVty (Just chan) application)’
    |
112 |     (void . customMain mkVty (Just chan) application) =<< mkInitialState chan c
    |                                          ^^^^^^^^^^^

programs/Main.hs:112:59: error:
    • Couldn't match type ‘Types.AppState’ with ‘App s0 e0 n0’
      Expected type: IO (App s0 e0 n0)
        Actual type: IO Types.AppState
    • In the second argument of ‘(=<<)’, namely ‘mkInitialState chan c’
      In a stmt of a 'do' block:
        (void . customMain mkVty (Just chan) application)
          =<< mkInitialState chan c
      In the expression:
        do checkForMouseSupport
           args <- getArgs
           let (os, rest, errs) = getOpt Permute opts args
           when (not $ null errs) $ showHelp >> exitFailure
           ....
    |
112 |     (void . customMain mkVty (Just chan) application) =<< mkInitialState chan c
    |                                                           ^^^^^^^^^^^^^^^^^^^^^

Canvas hit detection is... clamped? / not behaving properly? when using WASD to navigate

While trying to edit relatively large canvases, the tools aren't drawing where I'm clicking if I move too far in any direction using WASD.

It's relatively OK but offset from my cursor by a constant amount. This amount changes depending on where I move the canvas using WASD. It reaches a certain point where it's impossible to draw too far to the right/etc because no matter how far I move the canvas it's still somehow limited by the physical edge of my terminal.

New release

Hi! Tart does not build on NixOS because of vty upperbound, but I see you removed it 10 days ago, so can you please make a new Hackage release?

support lts-20

I am trying to build tart with roughly lts-20: actually for Fedora 38.
One problem is likely that lts now has brick-1.4,
however even before hitting that I get:

programs/Theme.hs:30:13: error:
    • No instance for (Data.String.IsString AttrName)
        arising from the literal ‘"error"’
    • In the expression: "error"
      In an equation for ‘errorAttr’: errorAttr = "error"
   |
30 | errorAttr = "error"
   |             ^^^^^^^

Maybe some upperbound missing?

The library builds just fine.

Include a `stack.yaml` for easier compiling with known working versions

Would there be any objection to having a stack.yaml file to make it simpler to compile this project with stack install?

This worked for me:

resolver: lts-9.0
packages:
- .
extra-deps:
- brick-0.23
- vty-5.17
- word-wrap-0.4.1

I generated the above with stack init --solver --resolver=lts-9.0 since using --resolver=nightly is crashing right now with:

$ stack init --solver --resolver=nightly
Looking for .cabal or package.yaml files to use to init the project.
Using cabal packages:
- tart.cabal

Selected resolver: nightly-2017-08-14
Selected resolver: nightly-2017-08-14
Downloaded nightly-2017-08-14 build plan.
AesonException "Error in $.packages.cassava.constraints.flags['bytestring--lt-0_10_4']: Invalid flag name: \"bytestring--lt-0_10_4\""

Option to output simple codes rather than 256-color

The .color.txts outputted by tart are filled with <ESC>[38;5;<index>m codes, even when I choose simple colors like red or blue (the non-bright versions). Is there an option to output simple codes instead (30-37 rather than 38)?

Module 'Graphics.Vty' does not export 'mkVty'

Compiling on Ubuntu 22.04 on the latest master:

logandark@LoganDark-HP ~/tart (master)> cabal new-build
Build profile: -w ghc-8.8.4 -O1
In order, the following will be built (use -v for more details):
 - brick-0.69.1 (lib) (requires build)
 - tart-0.3 (exe:tart) (first run)
Starting     brick-0.69.1 (lib)
Building     brick-0.69.1 (lib)

Failed to build brick-0.69.1.
Build log (
/home/logandark/.cabal/logs/ghc-8.8.4/brick-0.69.1-0e0fda1e99d5552325b32d44e750e28f4175d5e2b6ed0dccc7d252e4f7b7e89f.log
):
Configuring library for brick-0.69.1..
Preprocessing library for brick-0.69.1..
Building library for brick-0.69.1..
[ 1 of 25] Compiling Brick.AttrMap    ( src/Brick/AttrMap.hs, dist/build/Brick/AttrMap.o )
[ 2 of 25] Compiling Brick.BChan      ( src/Brick/BChan.hs, dist/build/Brick/BChan.o )
[ 3 of 25] Compiling Brick.Types.TH   ( src/Brick/Types/TH.hs, dist/build/Brick/Types/TH.o )
[ 4 of 25] Compiling Brick.Types.Common ( src/Brick/Types/Common.hs, dist/build/Brick/Types/Common.o )
[ 5 of 25] Compiling Brick.Themes     ( src/Brick/Themes.hs, dist/build/Brick/Themes.o )
[ 6 of 25] Compiling Brick.Widgets.Border.Style ( src/Brick/Widgets/Border/Style.hs, dist/build/Brick/Widgets/Border/Style.o )
[ 7 of 25] Compiling Data.IMap        ( src/Data/IMap.hs, dist/build/Data/IMap.o )
[ 8 of 25] Compiling Brick.BorderMap  ( src/Brick/BorderMap.hs, dist/build/Brick/BorderMap.o )
[ 9 of 25] Compiling Brick.Types.Internal ( src/Brick/Types/Internal.hs, dist/build/Brick/Types/Internal.o )
[10 of 25] Compiling Brick.Util       ( src/Brick/Util.hs, dist/build/Brick/Util.o )
[11 of 25] Compiling Brick.Types      ( src/Brick/Types.hs, dist/build/Brick/Types.o )
[12 of 25] Compiling Brick.Widgets.Internal ( src/Brick/Widgets/Internal.hs, dist/build/Brick/Widgets/Internal.o )
[13 of 25] Compiling Brick.Widgets.Core ( src/Brick/Widgets/Core.hs, dist/build/Brick/Widgets/Core.o )
[14 of 25] Compiling Brick.Widgets.ProgressBar ( src/Brick/Widgets/ProgressBar.hs, dist/build/Brick/Widgets/ProgressBar.o )
[15 of 25] Compiling Brick.Widgets.Edit ( src/Brick/Widgets/Edit.hs, dist/build/Brick/Widgets/Edit.o )
[16 of 25] Compiling Brick.Widgets.Center ( src/Brick/Widgets/Center.hs, dist/build/Brick/Widgets/Center.o )
[17 of 25] Compiling Brick.Widgets.Border ( src/Brick/Widgets/Border.hs, dist/build/Brick/Widgets/Border.o )
[18 of 25] Compiling Brick.Widgets.Table ( src/Brick/Widgets/Table.hs, dist/build/Brick/Widgets/Table.o )
[19 of 25] Compiling Brick.Widgets.Dialog ( src/Brick/Widgets/Dialog.hs, dist/build/Brick/Widgets/Dialog.o )
[20 of 25] Compiling Brick.Focus      ( src/Brick/Focus.hs, dist/build/Brick/Focus.o )
[21 of 25] Compiling Brick.Main       ( src/Brick/Main.hs, dist/build/Brick/Main.o )

src/Brick/Main.hs:74:5: error:
    Module ‘Graphics.Vty’ does not export ‘mkVty’
   |
74 |   , mkVty
   |     ^^^^^
cabal: Failed to build brick-0.69.1 (which is required by exe:tart from
tart-0.3). See the build log above for details.

I've successfully compiled on Ubuntu before, so I'm not sure what could be the issue. Perhaps standard library changes, or third-party dependency changes?

I can't just update brick, as the 0.70 update presumably introduced breaking changes, judging by the latest master commit.

logandark@LoganDark-HP ~/tart (master)> ghc -V
The Glorious Glasgow Haskell Compilation System, version 8.8.4
logandark@LoganDark-HP ~/tart (master)> cabal -V
cabal-install version 3.0.0.0
compiled using version 3.0.1.0 of the Cabal library

Keyboard support for moving cursor

I've experienced lack of keyboard support for moving cursor on canvas, for example with arrow keys. There is text string drawing tool, but it only allows for inserting text in one line, beginning from clicked spot - which limits movement.

Feature allowing to draw characters while typing (as in text string) and moving cursor with arrow keys could enhance efficiency of drawing with keyboard. Similar feature exists in Texel, which also supports mouse input in terminal.

On the other hand I am not sure if it wouldn't be against Tart's philosophy of drawing ASCII art in the terminal with your mouse.

New release?

The tart package doesn't build on some distributions like Nix/NixOS because of some dependency incompatibility, resolved in issues #8 and #9. A new Hackage release would help.

support vty >= 5.25

Currently tart has an upper-bound on vty which prevents it building with recent vty.
It would be nice to be able to build with recent version, eg Fedora ships 5.25.1 currently.

build error on 7473d5c

$ cabal new-build
Build profile: -w ghc-8.6.5 -O1
In order, the following will be built (use -v for more details):
 - tart-0.1.2 (exe:tart) (file programs/App.hs changed)
Preprocessing executable 'tart' for tart-0.1.2..
Building executable 'tart' for tart-0.1.2..
[32 of 33] Compiling App              ( programs/App.hs, /home/jon/fs/git/tart/dist-newstyle/build/x86_64-linux/ghc-8.6.5/tart-0.1.2/x/tart/build/tart/tart-tmp/App.o )

programs/App.hs:127:13: error:
    • Couldn't match type ‘IO’ with ‘EventM Name’
      Expected type: EventM Name ()
        Actual type: IO ()
    • In a stmt of a 'do' block:
        V.setMode (V.outputIface vty) V.Mouse True
      In the expression:
        do vty <- getVtyHandle
           V.setMode (V.outputIface vty) V.Mouse True
           V.setMode (V.outputIface vty) V.BracketedPaste True
           return s
      In the ‘appStartEvent’ field of a record
    |
127 |             V.setMode (V.outputIface vty) V.Mouse True
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

programs/App.hs:128:13: error:
    • Couldn't match type ‘IO’ with ‘EventM Name’
      Expected type: EventM Name ()
        Actual type: IO ()
    • In a stmt of a 'do' block:
        V.setMode (V.outputIface vty) V.BracketedPaste True
      In the expression:
        do vty <- getVtyHandle
           V.setMode (V.outputIface vty) V.Mouse True
           V.setMode (V.outputIface vty) V.BracketedPaste True
           return s
      In the ‘appStartEvent’ field of a record
    |
128 |             V.setMode (V.outputIface vty) V.BracketedPaste True
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

looks like it just needs the IO lifted here

support brick-0.50

No rush but it would be nice to allow building tart with newer versions of vty and brick.
Actually I would like to build it for distribution in Fedora.

Resize canvas dialog interface issue

Took me a second to realize I had to use tab to access the different text boxes of the dialogs. Clicking with the mouse doesn't work for some reason. Also, it would be nice if you could "click out" of a dialog by clicking on the outer screen, essentially a close-on-defocus thing.

This isn't really a bug, more of an interface preference

README uses the 'legacy v1 style' of cabal usage

I'm not sure if this is a cabal issue or a readme issue, but running cabal new-build gave me this error:

Warning: The package list for 'hackage.haskell.org' does not exist. Run 'cabal update' to download it.
Resolving dependencies...
cabal: Could not resolve dependencies:

So I tried running cabal update and got this warning:

Warning: The update command is a part of the legacy v1 style of cabal usage.

Please switch to using either the new project style and the new-update command or the legacy v1-update alias as new-style projects will become the default in the next version of cabal-install. Please file a bug if you cannot replicate a working v1- use case with the new-style commands.

For more information, see: https://wiki.haskell.org/Cabal/NewBuild

Cannot install with haskell-platform 8.2.1

When trying to install, I get this error:

# In file data-clist-0.1.2.0-GRWlwOEuIsQA9GA7i2yMwp.log
cabal: Entering directory '/tmp/cabal-tmp-30586/data-clist-0.1.2.0'
Configuring data-clist-0.1.2.0...
Preprocessing library for data-clist-0.1.2.0..
Building library for data-clist-0.1.2.0..
<command line>: cannot satisfy -package-id QuickCheck-2.10.0.1-DTIBC3CyU6p3h4xSnOjkg1: 
    QuickCheck-2.10.0.1-DTIBC3CyU6p3h4xSnOjkg1 is unusable due to shadowed dependencies:
      random-1.1-DtLcP2Z2iOOC0RwcSmXjBK tf-random-0.5-ABDhxe3mXYlHUEE5hzgewx
    (use -v for more information)
cabal: Leaving directory '/tmp/cabal-tmp-30586/data-clist-0.1.2.0'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.