{"id":26601372,"url":"https://github.com/calebwin/stdg","last_synced_at":"2025-08-11T00:35:22.088Z","repository":{"id":45438314,"uuid":"178799519","full_name":"calebwin/stdg","owner":"calebwin","description":"2D graphics in any programming language with just print statements","archived":false,"fork":false,"pushed_at":"2021-02-24T18:10:26.000Z","size":119,"stargazers_count":126,"open_issues_count":4,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-23T18:50:53.211Z","etag":null,"topics":["stdg"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/calebwin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-01T06:29:03.000Z","updated_at":"2024-12-27T08:25:28.000Z","dependencies_parsed_at":"2022-07-14T21:16:54.138Z","dependency_job_id":null,"html_url":"https://github.com/calebwin/stdg","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebwin%2Fstdg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebwin%2Fstdg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebwin%2Fstdg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/calebwin%2Fstdg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/calebwin","download_url":"https://codeload.github.com/calebwin/stdg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248067776,"owners_count":21042354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["stdg"],"created_at":"2025-03-23T18:39:35.963Z","updated_at":"2025-04-09T16:34:11.290Z","avatar_url":"https://github.com/calebwin.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003c!--   \u003cimg height=\"90px\" src=\"https://i.imgur.com/7650OtP.png\"/\u003e --\u003e\n\u003c!--   \u003cimg height=\"90px\" src=\"https://i.imgur.com/tpdsIFX.png\"/\u003e --\u003e\n  \u003cimg height=\"45px\" src=\"https://i.imgur.com/wxTHOMd.png\"/\u003e \n  \u003cbr\u003e\n  \u003cimg height=\"90px\" src=\"https://i.imgur.com/VuokGxr.png\"/\u003e\n\u003c!--   \u003cbr\u003e --\u003e\n\u003c!--   \u003cimg height=\"45px\" src=\"https://i.imgur.com/DpjP4aH.png\"/\u003e --\u003e\n  \u003cbr\u003e\n  \u003cimg height=\"45px\" src=\"https://i.imgur.com/wxTHOMd.png\"/\u003e \n\u003c/p\u003e\n\nStandard Graphics (abbreviated as `stdg`) is a command-line tool for printing 2D graphics from any language to any screen. It uses `stdin` and `stdout` to make 2D graphics as simple as printing commands with Python's `print()` or Java's `System.out.println()` for example. You can even write plain text and handle user interaction.\n\nYou only need to learn `stdg` once. Then it will no longer matter what language or frameworks you happen to be using. You will always be able to easily print 2D graphics using the same easy-to-remember commands.\n\n# Features\n\n- **Learn once** - `stdg` provides a minimal set of commands for 2D graphics. These commands are designed to be intuitive, easy-to-learn, and easy-to-remember. They are mostly inspired by Khan Academy's computer programming environment and Processing.\n- **Use anywhere** - `stdg` is both cross-language and cross-platform. This means that you can freely switch between programming languages and operating systems without having to learn a totally new 2D graphics library for the language/OS.\n- **Get fast, performant graphics** - `stdg` is an abstraction over MiniFB and Raqote which are both implemented entirely in Rust (except for MacOS which uses *some* Objective-C). Therefore, your graphics will be rendered at effectively native speed. There is no use of an Electron-like framework or \"dynamic\" languages in the rendering, event-handling.\n\n# Example\n\nStandard Graphics can be used with plain text. As an example, you could save the following to a text file, `rectangle.txt`.\n\n```txt\nstart 400 400 Untitled\n\nbackground 255 255 255\nfill 255 0 0\nrect 50 50 100 100\n\npresent forever\n```\n\nIf you have `stdg` and `python` correctly installed, you can open a terminal (command line/prompt), navigate to the folder containing `rectangle.txt` by using `cd`, type out the following, and press enter.\n\n```cmd\nrectangle.txt | stdg\n```\n\nThis is what you should see.\n\n![An example output through standard graphics](https://i.imgur.com/bPnUYoJ.png)\n\nStandard Graphics enables you to do even more complex things. This next example is taken from Khan Academy's \"Making animations\" lesson. Since this program is written in Python, you will have to use the Python interpreter to run it.\n\n```python\nprint(\"start 400 400 Untitled\")\n\n\n# position of the car\nx = 10\n\nwhile True:\n  print(\"background 151 244 247\")\n\n  # draw the car body\n  print(\"fill 255 0 115\")\n  print(\"nostroke\")\n  print(\"rect \" + str(x) + \" 200 100 20\")\n  print(\"rect \" + str(x + 15) + \" 178 70 40\")\n\n  # draw the wheels\n  print(\"fill 77 66 66\")\n  print(\"circle \" + str(x + 25) + \" 221 12\")\n  print(\"circle \" + str(x + 75) + \" 221 12\")\n\n  print(\"present\") # this is what actually says to draw, must be in an infinite loop\n\n  x = x + 1\n```\n\nEnter the following in a terminal.\n\n```cmd\npython moving_car.py | stdg\n```\n\nYou should see the following pop up as a window.\n\n![An example output through standard graphics](https://i.imgur.com/aRbhapW.png)\n\nRead on the see how you can use `stdg` for not only simple graphics and animations but also interactive user interfaces.\n\n# Built with Standard Graphics\n\nStandard Graphics has been used by open-source projects.\n\n- [Testing experimental programming languages](https://github.com/mkhan45/slang-v2/blob/master/test_files/pong_stdg.slang)\n\n# Usage\n\nThere are 2 ways of using Standard Graphics.\n\nThe first, and simplest, is by simply piping your program's output to `stdg`. All of your program's output (stuff that would normally be printed) will be sent to `stdg`. You can open a terminal and type in something like the following, provided `stdg` is installed.\n\n```cmd\nmy_data.csv | ruby my_program.rb | stdg\n```\nFor each line of input that `stdg` recieves, it will check if the first word (first token in line split by whitespace) matches a command. If the word matches, it will look at the rest of the line and execute the command by printing a rectangle, or setting color, etc.. If the word doesn't match, it will just print the line out.\n\nThe second way is by giving `stdg` a process to run.\n\n```cmd\nstdg node my_thing.js | settings.csv\n```\n\nIn this case, `stdg` doesn't accept any input. You can't pipe anything to it. You can't interactively type stuff in the terminal. You can, however, give it a process to run.\n\nYou give it a process by providing arguments to `stdg`. These arguments get parsed into a single command that can be executed as a process. Basically you can write `stdg python options.py` or `stdg ./menu` but you can't do `stdg python options.py \u0026\u0026 ./menu`.\n\nThen, `stdg` will run your process and read its output in exactly the same way the first usage has `stdg` reading. Commands get interpreted. Everything else gets printed as output. But now in addition to that, `stdg` will also sometimes print input to the process itself. This input will be information regarding things like mouse position, mouse click, etc.. The process can read this input one line at a time to get the mouse/key/etc. information.\n\nThis second way of using `stdg` allows for interactivity. You can do things like this-\n\n```python\nprint(\"start 400 400 A Rectangle\")\n\nwhile True:\n  print(\"background 255 255 255\")\n  print(\"fill 255 0 0\")\n  \n  print(\"get mousex\")\n  print(\"get mousey\")\n  print(\"rect \" + str(float(input()) - 25.0) + \" \" + str(float(input()) - 25.0) + \" 50.0 50.0\")\n  print(\"present\")\n```\n\n# Cheat Sheet\n\nThe following is a cheat sheet/reference for using `stdg`.\n\nThe following are commands for the most basic usage of `stdg`. Note that all whitespace in text like in `start` and `text` commands are converted to single spaces.\n\n| Command                   | Example                     | Note                                 |\n| ------------------------- | --------------------------- | ------------------------------------ |\n| Start everything          | `start 400 400 A rectangle` | Must be first line printed           |\n| Present stuff to be drawn | `present`                   | Must be in an infinite loop          |\n| Present forever           | `present forever`           | Useful in `.txt` files               |\n| Get position of mouse     | `get mousex`, `get mousey`  | Sends back line containing position  |\n| Get \"is mouse pressed?\"   | `get mouseispressed left`   | Must be `left`, `center`, or `right` |\n| Get \"is key pressed?\"     | `get keyispressed space`    | Valid keys listed below              |\n| Get all keys pressed      | `get keys`                  | Sends space-seperated valid keys           |\n\nThe following are useful for styling.\n\n| Command                    | Example                    | Note                                              |\n| -------------------------- | -------------------------- | ------------------------------------------------- |\n| Set background color       | `background 220 220 220`   |                                                   |\n| Set fill color             | `fill 255 0 0 240`         | All values of red-green-blue-alpha are 0-255      |\n| Set stroke color           | `stroke 20 20 20`          | Stroke is also called outline                     |\n| Don't fill or don't stroke | `nostroke`, `nofill`       | Default color is `nofill`, `stroke 0 0 0`         |\n| Set stroke weight          | `strokeweight 5`           | Default is 1                                      |\n| Set stroke cap             | `strokecap round`          | Must be `square`, `project`, or `round` (default) |\n| Set stroke join            | `strokejoin bevel`         | Must be `miter` (default), `bevel`, or  `round`   |\n\nWe can do transformations.\n\n| Command               | Example          | Note                                       |\n| --------------------- | ---------------- | ------------------------------------------ |\n| Push a transformation | `push`           | This lets us begin a new transformation    |\n| Pop top               | `pop`            | This will revert to the old transformation |\n| Translate top         | `translate 50 0` |                                            |\n| Scale top             | `scale 0.5 1.0`  |                                            |\n| Rotate top            | `rotate 180`     | Degrees are in degrees                     |\n\nThere are the common 2D primitives.\n\n| Command        | Example                  | Note                          |\n| -------------- | ------------------------ | ----------------------------- |\n| Draw rectangle | `rect 50 50 300 300`     | Must be x, y coordinates, width, height                              |\n| Draw ellipse   | `ellipse 200 200 50 40`  | Centered at given coordinates |\n| Draw circle    | `circle 200 200 50`      | All coordinates in 4th quadrant                              |\n| Draw line      | `line 300 100 100 300`   |                               |\n| Draw arc       | `arc 200 200 50 40 0 90` | Degrees are in degrees        |\n| Draw polygon   | `poly 130 70 180 20 340 100 360 200 270 250 130 70` | Arbitrary number of points allowed |\n\nLast but not least, we have text and images.\n\n| Command       | Example                                   | Note                                    |\n| ------------- | ----------------------------------------- | --------------------------------------- |\n| Set text font | `textfont C:\\Windows\\Fonts\\Arial.ttf`     | `\\` might have to be `\\\\`               |\n| Set text size | `textsize 20`                             |                                         |\n| Draw text     | `text 30 30`                              | Must be followed by line with text      |\n| Load image    | `open character.png as char`              | Should be called only once, if possible |\n| Draw image    | `image char 30 70`, `image char 5 5 50 1` | Should be a loaded image                |\n\nAnd here are the keys supported by `stdg`-\n\n- All numeric characters\n- All lower-case alphabetic characters (use `leftshift` or `rightshift` to check for upper-case)\n- `up`, `down`, `left`, `right`\n- `space`, `tab`, `enter`\n- `leftshift`, `rightshift`\n- `escape`, `backspace`, `delete`\n\n# About\n\nStandard Graphics is designed to be useful for many sorts of things-\n\n- User interfaces for Bash scripts\n- Visualization of Python-scripted simulations\n- Visualization of data\n- Desktop games written in JavaScript\n- Simple vector graphics with plain text\n- Simple animations with C\n- *and much more...*\n\nThe software itself is written entirely in pure Rust with the only exception being the MacOS back-end. It uses [Raquote](https://github.com/jrmuizel/raqote) and [MiniFB](https://github.com/emoon/rust_minifb) behind the scenes for drawing stuff.\n\n# Getting Started\n\nThere are two ways to install Standard Graphics.\n\nThe first way is to download the binaries from [here](https://github.com/calebwin/stdg/releases/tag/v0.2.0). Once downloaded, make sure that the folder location where the binaries are stored is added to `PATH` (look that up on the Internet if you aren't sure \"how to add folder location to PATH\". So basically what you would need to do is...\n\n1. Download binary file (`stdg.exe` or `stdg`)\n2. Move binary to desired folder (maybe `Program Files\\stdg\\stdg.exe` for example)\n3. Add the desired folder to `PATH`.\n\nThe second way is to install Standard Graphics with `cargo`. Make sure you have [installed Rust](https://www.rust-lang.org/tools/install). Then, simply install as follows.\n```cmd\ncargo install stdg\n```\n\nDuring installation, you may have to install a bunch of packages. On Windows, I was personally able to simply install and run. However, on Linux, I had to install at least `libfontconfig1-dev`, `xcursor`.\n\nOnce installed, you can take a look at the cheat sheet for more information on the various commands you can print.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcalebwin%2Fstdg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcalebwin%2Fstdg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcalebwin%2Fstdg/lists"}