Skip to content

Instantly share code, notes, and snippets.

@i-am-unknown-81514525
Last active April 20, 2025 01:57
Show Gist options
  • Select an option

  • Save i-am-unknown-81514525/9699e9889a38978f807218afd4594f8d to your computer and use it in GitHub Desktop.

Select an option

Save i-am-unknown-81514525/9699e9889a38978f807218afd4594f8d to your computer and use it in GitHub Desktop.
annotate.py
{
"latest-preset": {
"theme": "seti",
"backgroundColor": "#ADB7C1",
"windowTheme": "none",
"windowControls": true,
"fontFamily": "Hack",
"fontSize": "11px",
"lineNumbers": true,
"firstLineNumber": 1,
"dropShadow": false,
"dropShadowOffsetY": "5px",
"dropShadowBlurRadius": "17px",
"selectedLines": "*",
"widthAdjustment": false,
"width": "200000px",
"lineHeight": "133%",
"paddingVertical": "12px",
"paddingHorizontal": "8px",
"squaredImage": false,
"watermark": false,
"exportSize": "4x",
"type": "png"
}
}
"""
Copyright (C) 2025 i-am-unknown-81514525
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
def findall(txt: str, target: str) -> list[int]:
if target == "":
return []
out = []
curr = 0
while (result:=txt.find(target, curr)) != -1:
out.append(result)
curr = result + 1
return out
def display(code: str, anno: list[tuple[int, str]]) -> str:
ordered = list(sorted(anno, key=lambda x: x[0], reverse=True))
mapped = list(map(lambda x:x[0], ordered))
buffer = code + "\n" # + "".join("│" if i in mapped else " " for i in range(max(len(code), *mapped))) + "\n" # ↑
buffer_list = []
for i, e in enumerate(ordered):
buffer_list.append("".join("│" if j in mapped else " " for j in range(e[0])) + "╰──" + e[1])
return buffer + "\n".join(buffer_list)
def get_input(code: str, anno: list[tuple[int, str]], index: int) -> str:
ordered = list(sorted(anno, key=lambda x: x[0], reverse=True))
mapped = list(map(lambda x:x[0], ordered))
print(code)
# print("".join("│" if i in mapped else " " for i in range(max(len(code), *mapped))))
for i, e in enumerate(ordered):
if e[0] != index:
print("".join("│" if j in mapped else " " for j in range(e[0])) + "╰──" + e[1])
else:
return input("".join("│" if j in mapped else " " for j in range(e[0])) + "╰──" + e[1])
def generate(code: str, anno: list[tuple[int, str]], pre_target: str | None = None) -> tuple[int, str] | None:
if pre_target:
target = pre_target
else:
target = input("Search: ")
indexs = findall(code, target)
for i in indexs:
if i in anno:
continue
l = anno.copy() + [(i, "Annotate Here[j]")]
ret = get_input(code, l, i)
if ret == "":
m = anno.copy() + [(i, "")]
this_anno = get_input(code, m, i)
return (i, this_anno)
elif ret != "j":
return (i, ret)
def main():
dis: list[tuple[str, list[tuple[int, str]]]] = []
j=""
while j != "d":
if j:
this_code = j
else:
this_code = input(">>> ")
this_anno = []
k=""
while k!="e":
if (curr:=generate(this_code, this_anno, k)) is not None:
this_anno.append(curr)
else:
print("Failed to generate annotation, search not found")
k=input("Finish this annotation?[e]")
dis.append((this_code, this_anno))
print("Current: ")
print("\n".join(display(r[0], r[1]) for r in dis))
j=input("Display output?[d]")
img = input("Include image?[y]").lower().startswith("y")
print("\n"*50)
print("Display: ")
print("\n".join(display(r[0], r[1]) for r in dis))
if img:
# dep: https://github.com/mixn/carbon-now-cli
# .carbon-now.json included for the current configuration I used
# Using image options with cli installed accordingly would send the annotation to https://carbon.now.sh/
# It is possible to self-host such service via https://github.com/carbon-app/carbon (the offical source code)
# and edit the cli to use your self-hosted service according, if necessary
print("\n"*10)
import os
import pathlib
import random
id = "".join(random.choices("0123456789abcdef", k=32))
with (pathlib.Path() / "anno_tmp" / f"{id}.anno.py").open("w") as fp:
fp.write("\n".join(display(r[0], r[1]) for r in dis))
settings = '{"titleBar": "anno.txt"}'
os.system(f'carbon-now --skip-display --save-to ~/anno_tmp --save-as {id}.anno --settings \'{settings}\' ~/anno_tmp/{id}.anno.py')
return
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment