We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
NotMarkup
NotMarkup is an esoteric programming language created by User:Cordership based on HTML.
Syntax
Variables
Declaring and assigning variables:
<var>x = y</var>
Shorthand assignments are supported, as is assigning in commands. Assigning in commands works just like a walrus operator.
Operators
| Operator | Name |
|---|---|
| () | Parentheses |
| ** | Exponentiation |
| +x -x ~x | Unary plus, unary minus, and bitwise NOT |
| * / // % | Multiplication, division, floor division, and modulus |
| + - | Addition and subtraction |
| << >> | Bitwise left and right shifts |
| & | Bitwise AND |
| ^ | Bitwise XOR |
| &124; | Bitwise OR |
| == != > >= < <= is is not in not in | Comparisons, identity, and membership operators |
| not | Logical NOT |
| and | AND |
| or | OR |
I/O
Input:
<var>n = <input>Enter string: </input></var>
Output:
<print>"Hello, World!"</print>
Output with no newline:
<print>"Hello", end = ""</print>
Control flow
If-else
1-branch:
<if>condition:
# code
</if>
<if>condition: code</if>
2-branch:
<if>condition:
# code
</if><if>elif condition:
# code
…
</if><if>else:
# code
</if>
Logical operators are supported: and, or, not
Loops
For loops:
<loop>for a in b:
# code
</loop>
While loops:
<loop>while condition:
# code
</loop>
Lists
There are lists in this language. They can be nested.
<var>a = <list>0, 2, 3, 6</list></var>
There exists ranges. range(a, b) enumerates a list of integers n where a<=n<b. range(n) = range(0, n)
Dicts
Dicts:
<dict>keyname1 : value1, keyname2 : value2, ...</dict>
To get a keyname's value:
dict[keyname]
Note that the keyname must be a string, if it's an integer then it would return a key pair at the given index. To get a keyname's value but return a number:
dict.get(keyname, value)
Working with iterables
Iterables: lists, strings and dictionaries.
To access an element of an iterable:
<var>n = <list>1, 2, 6, 4</list> n[3] # Returns 4 <var>t = <dict>"Foo" : 1, "Bar" : 2, "Baz" : 0</dict> t[2] # Returns <dict>"Baz" : 0</dict>
Uses 0-indexing. Double indexing, slicing, and steps still work. To change an element:
n[1] = "Foo" # n is now <list>1, 1, 6, 4</list> t[1] = <dict>"Hello" : 128</dict> # t is now <dict>"Foo" : 1, "Hello" : 128, "Baz" : 0</dict>
Special methods that work for arrays and strings:
<replace str = string>substring 1, substring 2</replace> # Replace all occurrences of a substring with another string. <replace str = string>substring 1, substring 2, n</replace> # Replace first n occurrences of a substring with another string. <isupper>string</isupper> # If a string is uppercase only... <islower>string</islower> # If a string is lowercase only... <isspace>string</isspace> # If a string is whitespace only... <isdigit>string</isdigit> # If a string is digits only... <len>string</len> # Length of a string. iterable1 in iterable2 # Returns True if iterable 1 is in iterable 2.
Self-interpreter
There is a self-interpreter: <exec></exec>.
File manipulation
<read type = "full;">filename</read> # Reads the full file. <read type = "line;">filename</read> # Reads the first line of the file. A second copy of this command reads the second line, and so on... <append file = "myfile.txt">"example"</append> # Append to a file. <remove>filename</remove> # Delete a file.
Note that __file__ is the current file's name.
Datatypes
Base types: integers, floats, strings, booleans. Conversion:
<int>…</int> <float>…</float> <str>…</str> <bool>…</bool>
Note: NotMarkup treats True as 1 and False as 0.
- Truthy values: nonzero integers/floats, nonempty iterables.
- Falsy values: 0, 0.0, "", <list></list>
Functions
<def>functionname(**args, **kwargs):
# return something using <return></return> or do code
</def>
Convert to ASCII and back
<ord>char</ord> # ASCII value of a character. <char>num</char> # ASCII character of a number.
Programs
Hello, World!
<print>"Hello, World!"</print>
Cat program
<print><input></input></print>
Truth-machine
<var>n = <int><input></input></int>
<if>n == 0:
<print>n</print>
</if><if>else:
<loop>while 1:
<print>n</print>
</loop>
</if>
A+B problem
<print><int><input></input></int> + <int><input></input></int></print>
FizzBuzz
<loop>for i in range(1, 101):
<if>i % 3 == 0 and i % 5 == 0:
<print>"FizzBuzz"</print>
</if><if>elif i % 3 == 0 and i % 5 != 0:
<print>"Fizz"</print>
</if><if>elif i % 3 != 0 and i % 5 == 0:
<print>"Buzz"</print>
</if><if>else:
<print>i</print>
</if>
</loop>
Disan count
<loop>for i in range(<int><input></input></int>):
<if>i % 2 == 0:
<print>i, end = ""</print>
<print>" is even</print>
</if>
</loop>
4-function calculator
<var>a = <int><input></input></int></var>
<var>b = <input></input></var>
<var>c = <int><input></input></int></var>
<if>b == "+":
<print>a + c</print>
</if><if>elif b == "-":
<print>a - c</print>
</if><if>elif b == "*":
<print>a * c</print>
</if><if>elif b == "/":
<print>a / c</print>
</if>
The Exasperation Machine interpreter
<var>src = <input></input>
<var>tape = <dict></dict>
<var>ptr = 0</var>
<var>ip = 0</var>
<loop>while True:
<var>c = src[ip]</var>
<if>c in '/\\' and tape.get(ptr, 0) or c in '><':
<var>ptr = <dict>'>': 1, '<': -1, '/': 1, '\\': -1</dict>[c]
</if><if>elif c in '10':
<var>tape[ptr] = <int>c</int>
<var>ip = (ip + 1) % <len>src</len>
CT interpreter
<def>firstdigit(x):
<loop>for p in x:
<if><isdigit>p</isdigit>:
<return>p</return>
</if>
</loop>
</def>
<def> ct(d, cmd):
<if>cmd == ";":
<return><replace str = "d">firstdigit(d), " "</replace>
</if><if>elif <isdigit>cmd</isdigit> and firstdigit(d) == 1:
<return>d + cmd</return>
</if><if>else:
<return>d</return>
</if>
</def>
<var>p = <input>Program: </input></var>
<var>d = <input>Data-string: </input></var>
<loop>while not <isspace>d</isspace>:
<print><var>d = ct(d, p[t % <len>p</len>])</var></print>
<var>t += 1</var>
Quine
<var>inp = "<print>'<var>inp = ' + <char>34</char> + inp + <char>34</char> + '</var>' + <char>10</char> + inp</print>"</var> <print>'<var>inp = ' + <char>34</char> + inp + <char>34</char> + '</var>' + <char>10</char> + inp</print>