{"id":16694432,"url":"https://github.com/foxfriends/htms","last_synced_at":"2025-03-13T23:23:16.833Z","repository":{"id":57268098,"uuid":"87650284","full_name":"foxfriends/htms","owner":"foxfriends","description":"Full scripting abilities using the super simple syntax of HTML","archived":false,"fork":false,"pushed_at":"2018-06-24T16:39:39.000Z","size":9,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-05T11:06:52.166Z","etag":null,"topics":["esoteric","html","language","xml"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/foxfriends.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":"2017-04-08T17:08:00.000Z","updated_at":"2018-06-24T16:39:40.000Z","dependencies_parsed_at":"2022-09-02T02:50:10.664Z","dependency_job_id":null,"html_url":"https://github.com/foxfriends/htms","commit_stats":null,"previous_names":["oinkiguana/htms"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fhtms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fhtms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fhtms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/foxfriends%2Fhtms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/foxfriends","download_url":"https://codeload.github.com/foxfriends/htms/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243495762,"owners_count":20299982,"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":["esoteric","html","language","xml"],"created_at":"2024-10-12T16:45:50.872Z","updated_at":"2025-03-13T23:23:16.813Z","avatar_url":"https://github.com/foxfriends.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# HTMS\n\nEveryone knows HTML, but new programmers are often intimidated by JavaScript and\nits code-looking syntax. Unfortunately, HTML does not have scripting abilities\nof its own. Until now!\n\nHyperText Markup Script provides a way to express computations using just HTML.\nIt even provides full interoperability with JavaScript code for a smooth\ntransition when you feel ready to use a \"real\" language.\n\n## How to use HTMS:\n\n1.  Include the `htms.min.js` script on the page\n2.  Create your root `\u003chtms\u003e\u003c/htms\u003e` element\n3.  Write your code!\n\n## Syntax\n\nThe formal syntax of the language is exactly the same as HTML, though the tags\nhave slightly different meanings.\n\n## Nodes (Tags)\n\n#### `\u003chtms name=\"some_name\"\u003e`\n\nThe root HTMS node defines where to start running your HTMS code. All exported\nvalues will be placed in a global JavaScript object with the name given by the\n`name` attribute. (i.e. `some_name`, or `window.some_name`).\n\nThe final value of the `\u003chtms\u003e` node is automatically exported with the name\n`default`.\n\n```html\n\u003cHTMS\u003e\n  \u003c!-- your program here --\u003e\n\u003c/HTMS\u003e\n```\n\n#### `\u003cspan\u003e`\n\nProvides no special purpose other than to execute its children in order. It can\nbe used to turn variables into strings and numbers (see `\u003cq\u003e` and `\u003ci\u003e`).\n```html\n\u003cspan\u003e\n  \u003c!-- some block of code --\u003e\n\u003c/span\u003e\n```\n\n#### `\u003cvar name=\"some_name\"\u003e`\n\nAssigns the final value of its children to the variable given by the name\nattribute. This variable can then be referenced later by its name.\n\nNote that there are a few built in identifiers which cannot be used as variable\nnames, namely `true`, `false`, and `$_`. These correspond to the Boolean true\nand false values, and the \"previous value\".\n\n`$_` is often used internally, and so you should not need to reference it, but\nyou can. `$_` always holds the value of the previously executed node in the\ncurrent block. When no nodes have yet been run in the current block, the value\nof `$_` is `null`. This is the only way to obtain the `null` value, which may be\nuseful at times.\n\n```html\n\u003c!-- string = \"Hello world\" --\u003e\n\u003cvar name=\"string\"\u003e\u003cq\u003eHello world\u003c/q\u003e\u003c/var\u003e\n\n\u003cspan\u003e\n  \u003c!-- some code --\u003e\n  string\n\u003c/span\u003e \u003c!-- evaluates to \"Hello world\" --\u003e\n```\n\n#### `\u003cq\u003e`\n\nTurns its final value into a string. If it is a text node, the text is used\nliterally. Otherwise, it is the return value of evaluating the final element.\n\n```html\n\u003cvar name=\"x\"\u003e\u003ci\u003e3\u003c/i\u003e\u003c/var\u003e\n\u003cq\u003eHello world\u003c/q\u003e \u003c!-- String: \"Hello world\" --\u003e\n\u003cq\u003ex\u003c/q\u003e \u003c!-- String: \"x\" --\u003e\n\u003cq\u003e\u003cspan\u003ex\u003c/span\u003e\u003c/q\u003e \u003c!-- String: \"3\" --\u003e\n```\n\n#### `\u003ci\u003e`\n\nSimilar to `\u003cq\u003e` but for numbers.\n\n```html\n\u003cvar name=\"x\"\u003e\u003cq\u003e5\u003c/q\u003e\u003c/var\u003e\n\u003ci\u003e3\u003c/i\u003e \u003c!-- Number: 3 --\u003e\n\u003ci\u003ex\u003c/i\u003e \u003c!-- Number: NaN --\u003e\n\u003ci\u003e\u003cspan\u003ex\u003c/span\u003e\u003c/i\u003e \u003c!-- Number: 5 --\u003e\n```\n\n#### `\u003cb\u003e`\n\nSimilar to `\u003cq\u003e` but for Booleans.\n\n```html\n\u003cvar name=\"x\"\u003e\u003cq\u003e0\u003c/q\u003e\u003c/var\u003e\n\u003cb\u003e3\u003c/b\u003e \u003c!-- Boolean: true --\u003e\n\u003cb\u003e0\u003c/b\u003e \u003c!-- Boolean: false --\u003e\n\u003cb\u003efalse\u003c/b\u003e \u003c!-- Boolean: false --\u003e\n\u003cb\u003etrue\u003c/b\u003e \u003c!-- Boolean: true --\u003e\n\u003cb\u003e\u003cq\u003efalse\u003c/q\u003e\u003c/b\u003e \u003c!-- Boolean: true --\u003e\n\u003cb\u003ex\u003c/b\u003e \u003c!-- Boolean: true --\u003e\n\u003cb\u003e\u003cspan\u003ex\u003c/span\u003e\u003c/b\u003e \u003c!-- Boolean: false --\u003e\n```\n\n#### `\u003cdel\u003e`\n\nNegates its final value as a Boolean. Note that this is an operator, and not a\ntype constructor, so untyped values are evaluated as variables automatically and\ndo not require being nested in a `\u003cspan\u003e`.\n\n```html\n\u003cvar name=\"x\"\u003efalse\u003c/var\u003e\n\u003cdel\u003etrue\u003c/del\u003e \u003c!-- false --\u003e\n\u003cdel\u003e3\u003c/del\u003e \u003c!-- false --\u003e\n\u003cdel\u003efalse\u003c/del\u003e \u003c!-- true --\u003e\n\u003cdel\u003ex\u003c/del\u003e \u003c!-- true --\u003e\n\u003cdel\u003e\u003cspan\u003ex\u003c/span\u003e\u003c/del\u003e \u003c!-- true --\u003e\n```\n\n#### `\u003ca\u003e`\n\nProduces the sum of all the elements in its final value, which must be an array\nof numbers or strings. With strings, it performs concatenation.\n\n```html\n\u003c!-- 12 --\u003e\n\u003ca\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ci\u003e3\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e4\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e5\u003c/i\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/a\u003e\n\u003c!-- \"345\" --\u003e\n\u003ca\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003cq\u003e3\u003c/q\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cq\u003e4\u003c/q\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cq\u003e5\u003c/q\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/a\u003e\n```\n\n#### `\u003cs\u003e`\n\nSimilar to `\u003ca\u003e`, but performs subtraction. Does not work on strings.\n```html\n\u003c!-- -6 --\u003e\n\u003cs\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ci\u003e3\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e4\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e5\u003c/i\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/s\u003e\n```\n\n#### `\u003cdiv\u003e`\n\nSimilar to `\u003cs\u003e`, but performs division.\n```html\n\u003c!-- 1 --\u003e\n\u003cdiv\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ci\u003e10\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e2\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e5\u003c/i\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/div\u003e\n```\n\n#### `\u003cem\u003e`\n\nSimilar to `\u003cdiv\u003e`, but performs multiplication.\n```html\n\u003c!-- 100 --\u003e\n\u003cem\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ci\u003e10\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e2\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ci\u003e5\u003c/i\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/em\u003e\n```\n\n#### `\u003csup\u003e`\n\nRaises `$_` to the power of its final value. Both must be numbers.\n\n```html\n\u003c!-- 9 --\u003e\n\u003ci\u003e3\u003c/i\u003e\u003csup\u003e\u003ci\u003e2\u003c/i\u003e\u003c/sup\u003e\n```\n\n#### `\u003csmall\u003e`\n\nPerforms a less than comparison between `$_` and its final value.\n\n```html\n\u003c!-- true --\u003e\n\u003ci\u003e3\u003c/i\u003e\u003csmall\u003e\u003ci\u003e5\u003c/i\u003e\u003c/small\u003e\n\u003c!-- false --\u003e\n\u003ci\u003e5\u003c/i\u003e\u003csmall\u003e\u003ci\u003e3\u003c/i\u003e\u003c/small\u003e\n```\n\n#### `\u003csamp\u003e`\n\nPerforms an equality comparison between `$_` and its final value. Types of both\narguments must be the same for this to evaluate to true.\n\n```html\n\u003c!-- true --\u003e\n\u003ci\u003e3\u003c/i\u003e\u003csamp\u003e\u003ci\u003e3\u003c/i\u003e\u003c/samp\u003e\n\u003c!-- false --\u003e\n\u003ci\u003e5\u003c/i\u003e\u003csamp\u003e\u003ci\u003e3\u003c/i\u003e\u003c/samp\u003e\n```\n\n#### `\u003col\u003e ... \u003cli\u003e`\n\nCreates an array, where each array element is the final value of each `\u003cli\u003e`\n\n```html\n\u003c!-- [3, \"Hi\", [ 5 ]] --\u003e\n\u003col\u003e\n  \u003cli\u003e\u003ci\u003e3\u003c/i\u003e\u003c/li\u003e\n  \u003cli\u003e\u003cq\u003eHi\u003c/q\u003e\u003c/li\u003e\n  \u003cli\u003e\n    \u003col\u003e\n      \u003cli\u003e\u003ci\u003e5\u003c/i\u003e\u003c/li\u003e\n    \u003c/ol\u003e\n  \u003c/li\u003e\n\u003c/ol\u003e\n```\n\n#### `\u003cdl\u003e ... \u003cdd\u003e ... \u003cdt\u003e`\n\nCreates a dictionary where each key, denoted by `\u003cdd\u003e`, corresponds to the value\nof the following `\u003cdt\u003e`. The children of `\u003cdl\u003e` must start with `\u003cdd\u003e` and then\nalternate `\u003cdd\u003e\u003cdt\u003e\u003cdd\u003e\u003cdt\u003e`\n\n```html\n\u003c!--\n{\n  first_name: \"John\",\n  last_name: \"Smith\",\n  age: 15\n}\n--\u003e\n\u003cdl\u003e\n  \u003cdd\u003e\u003cq\u003efirst_name\u003c/q\u003e\u003c/dd\u003e\n  \u003cdt\u003e\u003cq\u003eJohn\u003c/q\u003e\u003c/dt\u003e\n  \u003cdd\u003e\u003cq\u003elast_name\u003c/q\u003e\u003c/dd\u003e\n  \u003cdt\u003e\u003cq\u003eSmith\u003c/q\u003e\u003c/dt\u003e\n  \u003cdd\u003e\u003cq\u003eage\u003c/q\u003e\u003c/dd\u003e\n  \u003cdt\u003e\u003ci\u003e15\u003c/i\u003e\u003c/dt\u003e\n\u003c/dl\u003e\n```\n\n#### `\u003csub\u003e`\n\nPerform the subscript operation to extract the values of an array or object. The\nfinal value of the `\u003csub\u003e` is the key to extract.\n\n```html\n\u003cvar name=\"obj\"\u003e\n  \u003cdl\u003e\n    \u003cdd\u003e\u003cq\u003efirst_name\u003c/q\u003e\u003c/dd\u003e\n    \u003cdt\u003e\u003cq\u003eJohn\u003c/q\u003e\u003c/dt\u003e\n    \u003cdd\u003e\u003cq\u003elast_name\u003c/q\u003e\u003c/dd\u003e\n    \u003cdt\u003e\u003cq\u003eSmith\u003c/q\u003e\u003c/dt\u003e\n    \u003cdd\u003e\u003cq\u003eage\u003c/q\u003e\u003c/dd\u003e\n    \u003cdt\u003e\u003ci\u003e15\u003c/i\u003e\u003c/dt\u003e\n  \u003c/dl\u003e\n\u003c/var\u003e\nobj\u003csub\u003e\u003cq\u003efirst_name\u003c/q\u003e\u003c/sub\u003e \u003c!-- \"John\" --\u003e\n\u003cvar name=\"arr\"\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ci\u003e3\u003c/i\u003e\u003c/li\u003e\n    \u003cli\u003e\u003cq\u003eHi\u003c/q\u003e\u003c/li\u003e\n    \u003cli\u003e\n      \u003col\u003e\n        \u003cli\u003e\u003ci\u003e5\u003c/i\u003e\u003c/li\u003e\n      \u003c/ol\u003e\n    \u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/var\u003e\narr\u003csub\u003e\u003ci\u003e1\u003c/i\u003e\u003c/sub\u003e \u003c!-- \"Hi\" --\u003e\n```\n\n#### `\u003ctemplate name=\"some_name\"\u003e`\n\nDefines a function. User-defined functions can take only one argument. If you\nneed more arguments, consider currying or passing an array or dictionary\ninstead.\n\nThe contents of the `\u003ctemplate\u003e` tag define the body of the function. To\nreference the argument, use the variable `argument`. The final value is used as\nthe return value.\n\nThe function can be later referenced by its name, given by the name attribute.\n\n```html\n\u003ctemplate name=\"fn\"\u003e\n  \u003c!-- ... some function body --\u003e\n\u003c/template\u003e\n```\n\n#### `\u003cins\u003e`\n\nPerforms a function call, passing its final value to the function referred to\nby the previous value (`$_`). This node evaluates to the return value of the\nfunction.\n\n```html\n\u003ctemplate name=\"fn\"\u003e\n  \u003c!-- ... some function body --\u003e\n\u003c/template\u003e\u003cins\u003e\u003cq\u003ehello world\u003c/q\u003e\u003c/ins\u003e  \u003c!-- $_ is the template[name=\"fn\"] --\u003e\n\u003c!-- or make $_ fn, then call it --\u003e\nfn\u003cins\u003e\u003cq\u003ehello world\u003c/q\u003e\u003c/ins\u003e\n```\n\n#### `\u003carticle\u003e ... \u003cheader\u003e ... \u003cmain\u003e ... \u003caside\u003e`\n\nThe if-else block. If the final value of the (required) `\u003cheader\u003e` tag is\n`true`, the (optional) `\u003cmain\u003e` block is run. If it is false, the (optional)\n`\u003caside\u003e` block is run. The return value of the `\u003carticle\u003e` is the final value\nof whichever block was run. If the block to run did not exist, the previous\nvalue of `$_` is returned instead.\n\nFor those experienced with programming who are used to the `else if` clause,\nthere is none, and you must instead nest `\u003carticles\u003e` to achieve this effect.\n\n#### `\u003ccode\u003e`\n\nObtains the native, global, JavaScript object `window[identifier]`, where the\nidentifier is the final value of its children. Notice that the types of native\nobjects are not the same as HTMS types, so if you wish to use it as a HTMS\nnumber or string, you must use the respective `\u003ci\u003e` or `\u003cq\u003e` to perform the\nconversion. You can, however, pass HTMS values to these functions as they will\nbe converted automatically.\n\n```html\n\u003c!-- Produces the number 3 --\u003e\n\u003ci\u003e\n  \u003ccode\u003e\u003cq\u003eMath\u003c/q\u003e\u003c/code\u003e\u003csub\u003e\u003cq\u003emin\u003c/q\u003e\u003c/sub\u003e\n  \u003cfieldset\u003e\n    \u003col\u003e\n      \u003cli\u003e\u003ci\u003e3\u003c/i\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ci\u003e7\u003c/i\u003e\u003c/li\u003e\n    \u003c/ol\u003e\n  \u003c/fieldset\u003e\n\u003ci\u003e\n```\n\n#### `\u003cfieldset\u003e`\n\nPerforms a function call, but instead of passing its final value as the\nargument, its final value must be an array whose elements are passed as multiple\narguments to the function. This is most useful for interacting with native\nJavaScript code, as user-defined functions can only have one argument.\n\n```html\n\u003c!-- Produces the number 3 --\u003e\n\u003ci\u003e\n  \u003ccode\u003e\u003cq\u003eMath\u003c/q\u003e\u003c/code\u003e\u003csub\u003e\u003cq\u003emin\u003c/q\u003e\u003c/sub\u003e\n  \u003cfieldset\u003e\n    \u003col\u003e\n      \u003cli\u003e\u003ci\u003e3\u003c/i\u003e\u003c/li\u003e\n      \u003cli\u003e\u003ci\u003e7\u003c/i\u003e\u003c/li\u003e\n    \u003c/ol\u003e\n  \u003c/fieldset\u003e\n\u003ci\u003e\n```\n\n#### `\u003coutput name\"some_name\"\u003e`\n\nExports a HTMS value to the host program with the name given by the name\nattribute.\n\n```html\n\u003cHTMS name=\"program\"\u003e\n  \u003coutput name=\"x\"\u003e\u003ci\u003e3\u003c/i\u003e\u003c/output\u003e\n\u003c/HTMS\u003e\n\u003c!-- Now in the native JS: window.program.x === 3 --\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoxfriends%2Fhtms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffoxfriends%2Fhtms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffoxfriends%2Fhtms/lists"}