{"id":15014614,"url":"https://github.com/sysl-dev/sysl-text","last_synced_at":"2025-06-22T06:37:11.619Z","repository":{"id":47589674,"uuid":"246699228","full_name":"sysl-dev/SYSL-Text","owner":"sysl-dev","description":"Text rendering with tag support.","archived":false,"fork":false,"pushed_at":"2024-08-03T19:09:19.000Z","size":9518,"stargazers_count":103,"open_issues_count":0,"forks_count":8,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-06-17T16:03:14.834Z","etag":null,"topics":["draw","love2d","sprite-text","text","textboxes"],"latest_commit_sha":null,"homepage":"","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sysl-dev.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-03-11T23:17:43.000Z","updated_at":"2025-04-25T18:15:46.000Z","dependencies_parsed_at":"2025-04-12T08:13:15.631Z","dependency_job_id":"55a289e6-32e5-4d83-b448-fa3a87fd65e4","html_url":"https://github.com/sysl-dev/SYSL-Text","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/sysl-dev/SYSL-Text","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysl-dev%2FSYSL-Text","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysl-dev%2FSYSL-Text/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysl-dev%2FSYSL-Text/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysl-dev%2FSYSL-Text/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sysl-dev","download_url":"https://codeload.github.com/sysl-dev/SYSL-Text/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sysl-dev%2FSYSL-Text/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261249783,"owners_count":23130494,"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":["draw","love2d","sprite-text","text","textboxes"],"created_at":"2024-09-24T19:45:51.074Z","updated_at":"2025-06-22T06:37:06.585Z","avatar_url":"https://github.com/sysl-dev.png","language":"Lua","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SYSL-Text\n**Please see the \"main.lua\" for samples, please review the library for all the possible tags.**\n\n![Quick Demo of Examples](/screenshots/ex.gif?raw=true \"Quick Demo of Examples\")\n\n# Update Notes\n* New: You can now pass a table to modify character widths, in case your font does something like move the j or q in one pixel. (See example 10)\n* New: You can now pass tables to the Audio/Font/Image/Etc commands if you don't keep resources global\n* New ```[scroll]``` command, will scroll the text up by line-height or a set value. Works well with ```love.graphics.setScissor```.\n* You have access to the basic calculated width, height and linecount for each textbox. Access is under the ```get``` table.\n    - ```my_cool_textbox.get.width, my_cool_textbox.get.height, my_cool_textbox.get.lines ```\n    - If you are using autowrap, the width calculation is more accurate.\n* Text animation commands now allow you to change the speed, or even reverse it.\n* It is no longer required to wrap UTF8 characters. You can send them without the wrapping and the library will scan and wrap extended characters without any manual input. \n\n# Setup\n## Adding the library to your project\n```lua\n-- Require the library in your project\nText = require(text.lua)\n```\n## Create your first textbox\n```lua\n-- Require the library in your project\nmy_cool_textbox = Text.new()\n```\n## Apply text to your textbox\n```lua\n-- Require the library in your project\nmy_cool_textbox:send(\"Oh, gee, I hope this print out one by one!\")\n```\n## Let love2d know to draw your textbox\n```lua\n-- in love.draw()\n-- my_cool_textbox:draw(x,y)\nmy_cool_textbox:draw(0,0)\n```\n## Let love2d know to update your textbox\n```lua\n-- in love.update(dt)\nmy_cool_textbox:update(dt)\n```\n\n# Tags\nSYSL-Text supports tags in ```[these brackets]``` and will use them to apply effects to your rendered text. SYSL-Text also supports defining default styles per textbox. Please take a look at the examples below. **Please note that effects and style are only examples, the library does not provide backgrounds or textboxes.**\n\n## Tags with Screenshot Examples\n![Example 1](/screenshots/01.gif?raw=true \"Example of Library\")\n```lua\nexample2box = Text.new(\"left\", \n{ \n    color = {1,1,1,1},\n    shadow_color = {0.5,0.5,1,0.4},\n    font = Fonts.golden_apple,\n    character_sound = true,\n    adjust_line_height = -3\n})\nexample2box:send(\"• Do you like eggs?[newline]• I think they are [pad=6]eggzelent![audio=sfx=laugh]\", 100, false)\n```\n![Example 2](/screenshots/02.gif?raw=true \"Example of Library\")\n```lua\nexample3box = Text.new(\"left\", \n{ \n    color = {1,1,1,1}, \n    shadow_color = {0.5,0.5,1,0.4}, \n    font = Fonts.golden_apple, \n    character_sound = false, \n    print_speed = 0.02,\n    adjust_line_height = -3\n    })\nexample3box:send(\"I am a very cute [color=#00ff00]green frog[/color]. Would you like to eat dinner with me? It's [rainbow][bounce]fresh[/bounce] [u]fly[/u] [shake]soup[/shake]![/rainbow]\", 316, false)\n```\n![Example 3](/screenshots/3.png?raw=true \"Example of Library\")\n```lua\nexample4box = Text.new(\"left\", \n{ \n    color = {0,0,0,0.95}, \n    shadow_color = {0.5,0.5,1,0.4}, \n    font = Fonts.earth_illusion,\n    adjust_line_height = -2\n    })\nexample4box:send(\"[dropshadow=2][b]Old Man:[/b][newline]Hello young man. How are you?\", 74, true)\n```\n![Example 4](/screenshots/4.png?raw=true \"Example of Library\")\n```lua\nexample6box = Text.new(\"left\", \n{ \n    color = {0.9,0.9,0.9,0.95}, \n    shadow_color = {0.5,0.5,1,0.4}, \n    font = Fonts.comic_neue, character_sound = true, \n    sound_every = 5, \n    sound_number = 2\n    })\nexample6box:send(\"Oh wow, you found the [bounce][rainbow]high-res[/rainbow][/bounce] text! [icon=1][icon=2][icon=3][icon=4] [icon=5][icon=6][icon=7][icon=8] [icon=9][icon=10][icon=11][icon=12][/]\", 320*4-16, true)\n```\n![Example 5](/screenshots/5.gif?raw=true \"Example of Library\")\n```lua\nexample7box = Text.new(\"left\", \n{ \n    color = {0.9,0.9,0.9,0.95}, \n    shadow_color = {0.5,0.5,1,0.4}, \n    font = Fonts.comic_neue_big, \n    character_sound = true, \n    sound_every = 3, \n    sound_number = 3\n    })\nexample7box:send(\"[warble=-5][textspeed=0.02][image=witch][pad=32]There's something I have to say,[pause=0.7] [warble=5]this witch will save the day!\", 320*4-16, false)\n```\n![Example 6](/screenshots/6.gif?raw=true \"Example of Library\")\n```lua\nexample8box = Text.new(\"left\", \n{ \n    color = {0.9,0.9,0.9,0.95}, \n    shadow_color = {0.5,0.5,1,0.4}, \n    font = Fonts.comic_neue_small, \n    character_sound = true, \n    print_speed = 0.04, \n    sound_every = 2, \n    sound_number = 4\n    })\nexample8box:send(\"[function=example.bop=true]Did you hear about the [color=#FF0000]bad puns?[/color][pause=0.5] You did?![pause=0.5] That's [color=#FFFF00]great[/color]![pause=0.8]  [shake]Now I don't have to tell you about them![/shake][pause=1][function=example.bop=false][audio=sfx=laugh]\", 320-80, false)\n```\n![Example 7](/screenshots/7.gif?raw=true \"Example of Library\")\n```lua\nexample5box = Text.new(\"left\", \n{ \n    color = {0.9,0.9,0.9,0.95}, \n    shadow_color = {0.5,0.5,1,0.4}, \n    font = Fonts.earth_illusion, \n    character_sound = true, \n    sound_every = 5, \n    sound_number = 2,\n    adjust_line_height = -2,\n    })\nexample5box:send(\"[dropshadow=3][function=example.ex5_textboxsize=64][textspeed=0.02]With the Power of Queens, they challenged the Snakes. Garry's mighty waves peeled apart their diamond scales. The Wizards woke[waitforinput][audio=sfx=ui] [function=example.ex5_textboxsize=example.ex5_textboxsize+16]mighty windstorms. Niza brought the deadly wine[waitforinput][audio=sfx=ui] [function=example.ex5_textboxsize=example.ex5_textboxsize+16]and cheese. [audio=sfx=ui]\", 320-16, false)\n\n```\n![Example 8](/screenshots/8.gif?raw=true \"Example of Library\")\n```lua\nexample9box = Text.new(\"left\", \n{ \n    color = {0.9,0.9,0.9,0.95}, \n    shadow_color = {0.5,0.5,1,0.4}, \n    font = Fonts.comic_neue_small, \n    character_sound = true, \n    print_speed = 0.04, \n    sound_every = 2, \n    sound_number = 4\n    })\nexample9box:send(\"Hello! Welcome to the world of Pocket Creatures![waitforinput][scroll][newline]My name is Professor Tree![newline][waitforinput][scroll][scroll]And you are?\", 150, false)\n\n\n```\n# Default Textbox Settings \n```lua \nlocal default_settings = {\n    autotags = \"[tab]\", -- This string is added at the start of every textbox, can include tags.\n    font = font.default, -- Default font for the textbox, love font object.\n    color = {1,1,1,1}, -- Default text color.\n    shadow_color = {1,1,1,1}, -- Default Drop Shadow Color.\n    print_speed = 0.2, -- How fast text prints.\n    adjust_line_height = 0, -- Adjust the default line spacing.\n    default_strikethrough_position = 0, -- Adjust the position of the strikethough line.\n    default_underline_position = 0, -- Adjust the position of the underline line.\n    character_sound = false, -- Use a voice when printing characters? True or false.\n    sound_number = 0, -- What voice to use when printing characters.\n    sound_every = 2, -- How many characters to wait before making another noise when printing text.\n    default_warble = 0 -- How much to adjust the voice when printing each character. \n}\n-- You can set some defaults for each textbox object to make things easier.\ntextbox = Text.new(\"left\", default_settings)\n```\n# Textbox Information \n## Width, Height, Lines\nYou can get the width, height and the number of lines after sending text to a textbox.\n```lua \nmy_cool_textbox = Text.new()\n\nmy_cool_textbox:send(\"Oh, gee, I hope this print out one by one!\")\nlocal textbox_x = 0\nlocal textbox_y = 0\nlocal textbox_w = my_cool_textbox.get.width\nlocal textbox_h = my_cool_textbox.get.height\nlocal textbox_l = my_cool_textbox.get.lines\n-- in love.draw()\nlove.graphics.rectangle(\"fill\", textbox_x, textbox_y, textbox_w, textbox_h)\nmy_cool_textbox:draw(textbox_x, textbox_y)\n```\n# is_finished()\nReturns ```true``` if the textbox is done printing, or ```false``` if the textbox is still printing. \n\nIt will also return as ```true``` if ```[waitforinput]``` is in the text string.\n```lua \nare_you_done = my_cool_textbox:is_finished()\n```\n\n# continue()\nContinue will continue printing after ```[waitforinput]``` pauses it.\n\n```lua \n-- You only need to send this once.\nmy_cool_textbox:continue()\n```\n\n# Tag Notes \nSome tags will not work until you let the library know something about your game.\n\n# 1.9 Update - Tags\nYou can now pass a table instead of a string, this will allow you to use a table of assets without using global assets.\n\n## Audio\n```lua\n--Text.configure.audio_table(table_string)\nText.configure.audio_table(\"Audio\")\n```\nThis configuration item will pass along the Lua table you are using to store audio sources. It currently can search down one level from that base table.\n```lua\nEnables \"[audio]\": Starts playing an audio source.\nUsed like: \"[audio=guy-laughing]\" or \"[audio=music=level1]\"\n\nEnables \"[/audio]\": Stops playing an audio source.\nUsed like: \"[/audio=guy-laughing]\" or \"[/audio=music=level1]\"\n```\n\n## Audio-Sound per character\n```lua\n--Text.configure.add_text_sound(sound, volume) \nText.configure.add_text_sound(Audio.text.default, 0.2) \n```\nThis will allow you to add voices so textboxes will jabber at you as they print characters. Note that the following commands will not work until you set up this configuration.\n```lua\nEnables: \n\"[voice=#]\": Set the speaking voice, 0 will turn it off.\n\"[warble=#]\": Set the pitch varience, +/- on the voice.\n\"[/warble]\": Stops the pitch varience.\n\"[soundevery=#]\": How often does a sound play per character.\n\"[/soundevery]\": Reset the sound per character.\n\nUsed like: \"[voice=2][warble=3][soundevery=1]I'm talking really fast and making a lot of noise![voice=0][/warble][/soundevery]\"\n```\n\n## Fonts\n```lua\n--Text.configure.font_table(table_string)\nText.configure.font_table(\"Font\")\n```\nThis configuration item will pass along the Lua table you are using to store your Font sources.\n```lua\nEnables \"[font=Font.name]\": Set the font.\nUsed like: \"[font=Font.ComicSansMs]\" or \"[font=Font.default]\"\n\nEnables \"[/font]\": Set the font back to the textbox default.\nUsed like: \"[/font]\"\n```\n## Images\n```lua\n--Text.configure.image_table(table_string)\nText.configure.image_table(\"img\")\n```\nThis configuration item will pass along the Lua table you are using to store image sources. It currently can search down one level from that base table.\n```lua\nEnables \"[image=name]\": Draw an image inline with the text.\nUsed like: \"[image=skull]\" or \"[image=ui=skull]\n```\n## Icons\n```lua\n--Text.configure.icon_table(table_string)\nText.configure.icon_table(\"Icon\")\n```\nThis configuration item will pass along the Lua table you are using to hold an icon drawing library. Note that this function assumes your library has a .draw() and .count() available. .draw() would work similar to how love.graphics.draw() works, with the source being replaced by a number. .count() would just return the number of available icons. If you would prefer to just use images, you can leave this configuration out and use the \"[image]\" tag.\n```lua\nEnables \"[icon=#]\": Draw an icon inline with the text.\nUsed like: \"[icon=1]\n```\n\n## Palettes\n```lua\n--Text.configure.palette_table(table_string)\nText.configure.palette_table(\"Palettes\")\n```\nThis configuration item will pass along the Lua table you are using to hold an indexed list of palettes. You can then use this prebuilt index instead of \"[color=#hexval]\".\n```lua\nEnables \"[color=#]\": Changed the color of the text based on a palette list.\nUsed like: \"[color=1]\n```\n\n## Shader Effects\n```lua\n--Text.configure.shader_table(table_string)\nText.configure.shader_table(\"Shaders\")\n```\nThis configuration item will pass along the Lua table you are using to hold shader functions you have created. These shader functions can be then applied directly to the text.\n```lua\nEnables \"[shader=name]\": Apply effects on text from a shader.\nUsed like: \"[shader=blur]\n```\n\n## Scripting Commands\n```lua\n--Text.configure.function_command_enable(enable_bool)\nText.configure.function_command_enable(enable_bool)\n```\nThis nightmare will allow you to write direct lua code into a string to execute. It's off by default. Please be careful when using. **Do not use unless you sandbox your text.**\n\n# Standard Tags\n## Not Animated\n### end\n```lua \n\"[end]\" -- System tag, added to the end of every string.\n```\n### waitforinput\n```lua \n\"[waitforinput]\" -- Pauses printing characters until the\n-- Text:continue() command is sent from somewhere in your code.\n```\n### newline\n```lua \n\"[newline]\" -- Start printing on a new line, added automatically when autowrap is on.\n```\n### cursorsave\n```lua \n\"[cursorsave]\" -- Save the current location of where we are typing to in the textbox.\n```\n### cursorload\n```lua \n\"[cursorload]\" -- Restore the current location of where we are typing to in the textbox from when we last saved with [cursorsave].\n```\n### cursorx\n```lua \n\"[cursorx=number]\" -- Set the cursor position as Textbox X position + x\n```\n### cursory\n```lua \n\"[cursory=number]\" -- Set the cursor position as Textbox Y position + y\n```\n### tab\n```lua \n\"[tab]\" -- Pad 4 spaces. Same as \"    \".\n```\n### pad\n```lua \n\"[pad=number]\" -- Pad this many pixels.\n```\n### lineheight\n```lua \n\"[lineheight=number]\" -- Set the height for each line to this many pixels.\n```\n### skip\n```lua \n\"[skip]\" -- Skip rendering the remaining characters character by character, draw the full text.\n```\n### pause\n```lua \n\"[pause]\" -- Wait this many seconds (can use 0. for less than one second). Does not do anything if textbox is set to show everything. May interact badly with skip.\n```\n### backspace\n```lua \n\"[backspace=number]\" -- Erase this many printed characters and start printing from that point. Very fragile, do not backspace over commands.\n```\n### textspeed\n```lua \n\"[textspeed=number]\" -- Change how fast text is printed, wait this long in seconds before printing the next character. 0.2 is the default.\n```\n### /textspeed\n```lua \n\"[/textspeed]\" -- Reset textspeed to the default\n```\n### color\n```lua \n\"[color=#BEEEEF]\" -- Set color to the hex color.\n```\n### /color\n```lua \n\"[/color]\" -- Reset to the default color.\n```\n### shadowcolor\n```lua \n\"[shadowcolor=#BEEEEF]\" -- Set shadow color to the hex color.\n```\n### /shadowcolor\n```lua \n\"[/shadowcolor]\" -- Reset to the default shadow color.\n```\n### dropshadow\n![Example 8](/screenshots/dropshadow.png?raw=true \"Example of Dropshadow\")\n```lua \n\"[dropshadow=number]\" -- Draw a dropshadow behind the text\n-- 1 - Lower Left\n-- 2 - Below\n-- 3 - Lower Right\n-- 4 - Left \n-- 5 - Thin Outline \n-- 6 - Right \n-- 7 - Upper Left \n-- 8 - Above \n-- 9 - Upper Right \n-- 10 - Thick Outline\n```\n### /dropshadow\n```lua \n\"[/dropshadow]\" -- Turn off dropshadow.\n```\n### scale\n```lua \n\"[scale=number]\" -- Scale the text.\n```\n### /scale\n```lua \n\"[/scale]\" -- Reset the scale.\n```\n### rotate\n![Example 9](/screenshots/rotate.png?raw=true \"Example of Rotate\")\n```lua \n\"[rotate=number]\" -- Rotate the text characters.\n```\n### /rotate\n```lua \n\"[/rotate]\" -- Reset the rotation.\n```\n### b, i, u, s\n![Example 11](/screenshots/bius.png?raw=true \"Example of bius\")\n```lua \n\"[b]BOLD[/b]\" -- Fake Bold.\n\"[i]ITALICS[/i]\" -- Fake Italics.\n\"[u]UNDERLINE[/u]\" -- Underline.\n\"[s]STRIKETHROUGH[/s]\" -- Strikethrough.\n-- Note, you can adjust the position of the line of underline and strikethough by doing [u=number]/[s=number] positive or negative. \n-- Some fonts do not report height as nice as it could. \n-- You can also set the default for the new textbox so you do not have to do this for each underline and strikethrough.\n```\n### mirror\n![Example 10](/screenshots/mirror.png?raw=true \"Example of Mirror\")\n```lua \n\"[mirror=number]\" -- Print text reversed.\n```\n### /mirror\n```lua \n\"[/mirror]\" -- Stop the reverse.\n```\n## Animated Tags\nNote, all numbers are optional. You can use the ```[tag]``` without them, it will use the default speed.\n\n![Example 10](/screenshots/effects.gif?raw=true \"Example of Rotate\")\n### shake \n```lua \n\"[shake=number]Shake[/shake]\"\n```\n### spin \n```lua \n\"[spin=number]spin[/spin]\"\n```\n### swing \n```lua \n\"[swing=number]swing[/swing]\"\n```\n### raindrop \n```lua \n\"[raindrop=number]raindrop[/raindrop]\"\n```\n### bounce \n```lua \n\"[bounce=number]bounce[/bounce]\"\n```\n### blink \n```lua \n\"[blink=number]blink[/blink]\"\n```\n### rainbow \n```lua \n\"[rainbow=number(speed)=number(brightness of color)]rainbow[/rainbow]\"\n```\n### scroll\n```lua \n\"[scroll] or [scroll=-int]\" -- Scrolls the text in the textbox.\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsysl-dev%2Fsysl-text","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsysl-dev%2Fsysl-text","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsysl-dev%2Fsysl-text/lists"}