hyperlist 1.4.2 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/hyperlist +151 -58
- data/hyperlist.gemspec +1 -1
- data/img/hyperlist_logo.svg +395 -71
- data/sample.hl +24 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 735c8dad200fdf5f2ac019def34b0b9f11eed7df0c49f962385bc723b0263cf4
|
4
|
+
data.tar.gz: db4f459832acaa5d04509d070797aae448062cd507810666a743c1194e61fd32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb8aa40308aad944488acfcaf2c1319fa65dfed27ce2135d74384b240deb8b2f3fd327def196206f501f134995dd17affae874e6800bb42a440789b9610bc588
|
7
|
+
data.tar.gz: 88e64082e113bdb8f38ae69f6579fdb4711a62c6699bd7f58ded56a08d32e52367e00062e41b1ecf0d6c80742d2467f833ef05d42fe476f816e1aaa83d8a697b
|
data/hyperlist
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
# Check for help/version BEFORE loading any libraries
|
8
8
|
if ARGV[0] == '-h' || ARGV[0] == '--help'
|
9
9
|
puts <<~HELP
|
10
|
-
HyperList v1.4.
|
10
|
+
HyperList v1.4.3 - Terminal User Interface for HyperList files
|
11
11
|
|
12
12
|
USAGE
|
13
13
|
hyperlist [OPTIONS] [FILE]
|
@@ -72,7 +72,7 @@ class HyperListApp
|
|
72
72
|
include Rcurses::Input
|
73
73
|
include Rcurses::Cursor
|
74
74
|
|
75
|
-
VERSION = "1.4.
|
75
|
+
VERSION = "1.4.3"
|
76
76
|
|
77
77
|
def initialize(filename = nil)
|
78
78
|
@filename = filename ? File.expand_path(filename) : nil
|
@@ -253,6 +253,28 @@ class HyperListApp
|
|
253
253
|
next
|
254
254
|
end
|
255
255
|
|
256
|
+
# Check if this is a continuation line for a multi-line item
|
257
|
+
# According to HyperList spec: continuation lines start with space after the indent
|
258
|
+
is_continuation = false
|
259
|
+
if @items.length > 0
|
260
|
+
last_item = @items.last
|
261
|
+
# Check if previous item started with + (multi-line indicator)
|
262
|
+
if last_item["text"].strip.start_with?("+")
|
263
|
+
# For continuation lines, we expect: same indent level + one space prefix
|
264
|
+
# Calculate the expected spaces for a continuation line
|
265
|
+
expected_spaces = last_item["level"] * @indent_size + 1
|
266
|
+
actual_spaces = line[/^ */].length
|
267
|
+
|
268
|
+
# Check if this matches the continuation pattern
|
269
|
+
if actual_spaces == expected_spaces
|
270
|
+
# This is a continuation line - append it to the previous item
|
271
|
+
continuation_text = line[expected_spaces..-1] || ""
|
272
|
+
last_item["text"] += "\n " + continuation_text
|
273
|
+
next # Skip adding as a new item
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
256
278
|
# Detect level based on leading whitespace
|
257
279
|
if line.start_with?("\t")
|
258
280
|
# Tab-based indentation
|
@@ -589,7 +611,18 @@ class HyperListApp
|
|
589
611
|
|
590
612
|
# Prepare content
|
591
613
|
content = @items.map do |item|
|
592
|
-
|
614
|
+
# Handle multi-line items (those with embedded newlines)
|
615
|
+
if item["text"].include?("\n")
|
616
|
+
lines = item["text"].split("\n")
|
617
|
+
first_line = (' ' * @indent_size) * item["level"] + lines[0]
|
618
|
+
# Continuation lines get the same indent + space prefix
|
619
|
+
continuation_lines = lines[1..-1].map do |line|
|
620
|
+
(' ' * @indent_size) * item["level"] + line
|
621
|
+
end
|
622
|
+
[first_line, *continuation_lines].join("\n")
|
623
|
+
else
|
624
|
+
(' ' * @indent_size) * item["level"] + item["text"]
|
625
|
+
end
|
593
626
|
end.join("\n")
|
594
627
|
|
595
628
|
# Append config line if present
|
@@ -935,7 +968,16 @@ class HyperListApp
|
|
935
968
|
if first_line
|
936
969
|
# First line gets the multi-line indicator if needed
|
937
970
|
if remaining.length <= effective_width
|
938
|
-
|
971
|
+
# If line already had +, it was removed earlier, so we add it back
|
972
|
+
# If line didn't have + but needs wrapping (wrapped.any?), add +
|
973
|
+
# Otherwise, leave as is
|
974
|
+
if has_plus
|
975
|
+
wrapped << "+ #{remaining}"
|
976
|
+
elsif wrapped.any?
|
977
|
+
wrapped << "+ #{remaining}"
|
978
|
+
else
|
979
|
+
wrapped << remaining
|
980
|
+
end
|
939
981
|
break
|
940
982
|
else
|
941
983
|
# Find a good break point (prefer spaces)
|
@@ -971,14 +1013,28 @@ class HyperListApp
|
|
971
1013
|
in_literal_block = false
|
972
1014
|
literal_start_level = -1
|
973
1015
|
|
1016
|
+
# Track which line number each item starts at (for scroll calculation)
|
1017
|
+
item_line_starts = {}
|
1018
|
+
|
974
1019
|
visible_items.each_with_index do |item, idx|
|
975
1020
|
next unless item
|
976
1021
|
|
977
|
-
#
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
1022
|
+
# Record where this item starts in the display
|
1023
|
+
item_line_starts[idx] = lines.length
|
1024
|
+
|
1025
|
+
# Handle line wrapping and multi-line items
|
1026
|
+
# First, split by embedded newlines (from multi-line items with + indicator)
|
1027
|
+
embedded_lines = item["text"].split("\n")
|
1028
|
+
text_lines = []
|
1029
|
+
|
1030
|
+
embedded_lines.each do |embedded_line|
|
1031
|
+
if @wrap
|
1032
|
+
# Wrap each embedded line separately
|
1033
|
+
wrapped = wrap_line(embedded_line, @cols, item["level"])
|
1034
|
+
text_lines.concat(wrapped)
|
1035
|
+
else
|
1036
|
+
text_lines << embedded_line
|
1037
|
+
end
|
982
1038
|
end
|
983
1039
|
|
984
1040
|
text_lines.each_with_index do |text_line, line_idx|
|
@@ -1087,23 +1143,26 @@ class HyperListApp
|
|
1087
1143
|
end
|
1088
1144
|
end
|
1089
1145
|
|
1090
|
-
# Calculate scroll position
|
1091
|
-
#
|
1146
|
+
# Calculate scroll position based on actual line positions, not item indices
|
1147
|
+
# The current item starts at line item_line_starts[@current]
|
1092
1148
|
scrolloff = 3
|
1093
|
-
|
1094
|
-
page = @main.h
|
1149
|
+
total_lines = lines.length # Total number of actual display lines
|
1150
|
+
page = @main.h # Height of the display area
|
1151
|
+
|
1152
|
+
# Get the actual line where the current item starts
|
1153
|
+
current_line = item_line_starts[@current] || 0
|
1095
1154
|
|
1096
|
-
if
|
1155
|
+
if total_lines <= page
|
1097
1156
|
# If everything fits, always start from the very top
|
1098
1157
|
@main.ix = 0
|
1099
|
-
elsif
|
1158
|
+
elsif current_line - @main.ix < scrolloff
|
1100
1159
|
# If we're too close to the top of the pane, scroll up
|
1101
|
-
@main.ix = [
|
1102
|
-
elsif (@main.ix + page - 1 -
|
1160
|
+
@main.ix = [current_line - scrolloff, 0].max
|
1161
|
+
elsif (@main.ix + page - 1 - current_line) < scrolloff
|
1103
1162
|
# If we're too close to the bottom of the pane, scroll down
|
1104
|
-
#
|
1105
|
-
|
1106
|
-
@main.ix = [
|
1163
|
+
# Make sure we don't scroll past the last line
|
1164
|
+
max_scroll = [total_lines - page, 0].max
|
1165
|
+
@main.ix = [current_line + scrolloff - page + 1, max_scroll].min
|
1107
1166
|
end
|
1108
1167
|
|
1109
1168
|
@main.refresh
|
@@ -4874,46 +4933,77 @@ class HyperListApp
|
|
4874
4933
|
|
4875
4934
|
# Build ALL lines for the pane (like we do for main pane)
|
4876
4935
|
lines = []
|
4936
|
+
|
4937
|
+
# Track which line number each item starts at (for scroll calculation)
|
4938
|
+
item_line_starts = {}
|
4939
|
+
|
4877
4940
|
visible_items.each_with_index do |item, idx|
|
4878
4941
|
next unless item
|
4879
4942
|
|
4943
|
+
# Record where this item starts in the display
|
4944
|
+
item_line_starts[idx] = lines.length
|
4945
|
+
|
4880
4946
|
# Find the item's position in the original split_items array
|
4881
4947
|
real_idx = @split_items.index(item)
|
4882
4948
|
|
4883
|
-
#
|
4884
|
-
|
4885
|
-
|
4886
|
-
actual_line_number = real_idx ? real_idx + 1 : 0 # +1 for 1-based line numbers
|
4887
|
-
line = "#{actual_line_number.to_s.rjust(4)} "
|
4888
|
-
end
|
4889
|
-
|
4890
|
-
line += " " * item["level"]
|
4949
|
+
# Handle multi-line items (split by embedded newlines)
|
4950
|
+
embedded_lines = item["text"].split("\n")
|
4951
|
+
text_lines = []
|
4891
4952
|
|
4892
|
-
|
4893
|
-
|
4894
|
-
|
4895
|
-
|
4953
|
+
embedded_lines.each do |embedded_line|
|
4954
|
+
if @wrap
|
4955
|
+
# Wrap each embedded line separately
|
4956
|
+
wrapped = wrap_line(embedded_line, @split_pane.w - 10, item["level"])
|
4957
|
+
text_lines.concat(wrapped)
|
4896
4958
|
else
|
4897
|
-
|
4959
|
+
text_lines << embedded_line
|
4898
4960
|
end
|
4899
|
-
else
|
4900
|
-
line += " "
|
4901
4961
|
end
|
4902
4962
|
|
4903
|
-
|
4904
|
-
|
4905
|
-
|
4906
|
-
|
4907
|
-
|
4908
|
-
|
4909
|
-
|
4910
|
-
|
4911
|
-
|
4912
|
-
|
4913
|
-
|
4963
|
+
text_lines.each_with_index do |text_line, line_idx|
|
4964
|
+
# Add line number if enabled (only on first line)
|
4965
|
+
line = ""
|
4966
|
+
if @show_numbers
|
4967
|
+
if line_idx == 0
|
4968
|
+
actual_line_number = real_idx ? real_idx + 1 : 0 # +1 for 1-based line numbers
|
4969
|
+
line = "#{actual_line_number.to_s.rjust(4)} "
|
4970
|
+
else
|
4971
|
+
line = " " # Empty space for continuation lines
|
4972
|
+
end
|
4973
|
+
end
|
4974
|
+
|
4975
|
+
line += " " * item["level"]
|
4976
|
+
|
4977
|
+
# Add fold indicator with colors (only on first line)
|
4978
|
+
if line_idx == 0
|
4979
|
+
if real_idx && has_children_in_array?(real_idx, @split_items)
|
4980
|
+
if item["fold"]
|
4981
|
+
line += "▶".fg("245") + " "
|
4982
|
+
else
|
4983
|
+
line += "▷".fg("245") + " "
|
4984
|
+
end
|
4985
|
+
else
|
4986
|
+
line += " "
|
4987
|
+
end
|
4988
|
+
else
|
4989
|
+
line += " " # Just spacing for continuation lines
|
4990
|
+
end
|
4991
|
+
|
4992
|
+
# Apply process_text for syntax highlighting
|
4993
|
+
processed = process_text(text_line, false)
|
4994
|
+
line += processed
|
4995
|
+
|
4996
|
+
# Apply background highlighting for current item in split pane (all lines)
|
4997
|
+
if idx == @split_current
|
4998
|
+
# Choose background color based on whether this is the active pane
|
4999
|
+
bg_color = @active_pane == :split ? "237" : "234"
|
5000
|
+
bg_code = "\e[48;5;#{bg_color}m"
|
5001
|
+
reset_bg = "\e[49m"
|
5002
|
+
line = bg_code + line.gsub(/\e\[49m/, '') + reset_bg
|
5003
|
+
end
|
5004
|
+
|
5005
|
+
lines << line
|
4914
5006
|
end
|
4915
|
-
|
4916
|
-
lines << line
|
4917
5007
|
end
|
4918
5008
|
|
4919
5009
|
# Add a blank line at the bottom to show end of document
|
@@ -4934,22 +5024,25 @@ class HyperListApp
|
|
4934
5024
|
end
|
4935
5025
|
end
|
4936
5026
|
|
4937
|
-
# Calculate scroll position
|
5027
|
+
# Calculate scroll position based on actual line positions, not item indices
|
4938
5028
|
scrolloff = 3
|
4939
|
-
|
4940
|
-
page = @split_pane.h
|
5029
|
+
total_lines = lines.length # Total number of actual display lines
|
5030
|
+
page = @split_pane.h # Height of the display area
|
5031
|
+
|
5032
|
+
# Get the actual line where the current item starts
|
5033
|
+
current_line = item_line_starts[@split_current] || 0
|
4941
5034
|
|
4942
|
-
if
|
5035
|
+
if total_lines <= page
|
4943
5036
|
# If everything fits, always start from the very top
|
4944
5037
|
@split_pane.ix = 0
|
4945
|
-
elsif
|
5038
|
+
elsif current_line - @split_pane.ix < scrolloff
|
4946
5039
|
# If we're too close to the top of the pane, scroll up
|
4947
|
-
@split_pane.ix = [
|
4948
|
-
elsif (@split_pane.ix + page - 1 -
|
5040
|
+
@split_pane.ix = [current_line - scrolloff, 0].max
|
5041
|
+
elsif (@split_pane.ix + page - 1 - current_line) < scrolloff
|
4949
5042
|
# If we're too close to the bottom of the pane, scroll down
|
4950
|
-
#
|
4951
|
-
|
4952
|
-
@split_pane.ix = [
|
5043
|
+
# Make sure we don't scroll past the last line
|
5044
|
+
max_scroll = [total_lines - page, 0].max
|
5045
|
+
@split_pane.ix = [current_line + scrolloff - page + 1, max_scroll].min
|
4953
5046
|
end
|
4954
5047
|
|
4955
5048
|
@split_pane.refresh
|
data/hyperlist.gemspec
CHANGED
data/img/hyperlist_logo.svg
CHANGED
@@ -1,77 +1,401 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
width="134.72328mm"
|
6
|
+
height="134.55478mm"
|
7
|
+
viewBox="0 0 134.72328 134.55478"
|
8
|
+
version="1.1"
|
9
|
+
id="svg1"
|
10
|
+
xml:space="preserve"
|
11
|
+
sodipodi:docname="hyperlistlogo.svg"
|
12
|
+
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
|
13
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
14
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
15
|
+
xmlns="http://www.w3.org/2000/svg"
|
16
|
+
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
17
|
+
id="namedview1"
|
18
|
+
pagecolor="#ffffff"
|
19
|
+
bordercolor="#000000"
|
20
|
+
borderopacity="0.25"
|
21
|
+
inkscape:showpageshadow="2"
|
22
|
+
inkscape:pageopacity="0.0"
|
23
|
+
inkscape:pagecheckerboard="0"
|
24
|
+
inkscape:deskcolor="#d1d1d1"
|
25
|
+
inkscape:document-units="mm"
|
26
|
+
inkscape:zoom="1.332716"
|
27
|
+
inkscape:cx="231.85734"
|
28
|
+
inkscape:cy="219.10144"
|
29
|
+
inkscape:window-width="1920"
|
30
|
+
inkscape:window-height="951"
|
31
|
+
inkscape:window-x="0"
|
32
|
+
inkscape:window-y="29"
|
33
|
+
inkscape:window-maximized="1"
|
34
|
+
inkscape:current-layer="svg1" />
|
35
|
+
<defs
|
36
|
+
id="defs1">
|
37
|
+
<linearGradient
|
38
|
+
id="linearGradient33"
|
39
|
+
x1="0"
|
40
|
+
y1="0"
|
41
|
+
x2="1"
|
42
|
+
y2="1">
|
43
|
+
<stop
|
44
|
+
offset="0"
|
45
|
+
style="stop-color:#00fa86;stop-opacity:1;"
|
46
|
+
id="stop32" />
|
47
|
+
<stop
|
48
|
+
offset="1"
|
49
|
+
style="stop-color:#00cc66;stop-opacity:1"
|
50
|
+
id="stop33" />
|
51
|
+
</linearGradient>
|
52
|
+
<filter
|
53
|
+
id="glow"
|
54
|
+
x="-1.184409"
|
55
|
+
y="-2.3688181"
|
56
|
+
width="3.3688181"
|
57
|
+
height="5.7376362">
|
58
|
+
<feGaussianBlur
|
59
|
+
stdDeviation="2.9610226"
|
60
|
+
result="coloredBlur"
|
61
|
+
id="feGaussianBlur1" />
|
62
|
+
<feMerge
|
63
|
+
id="feMerge2">
|
64
|
+
<feMergeNode
|
65
|
+
in="coloredBlur"
|
66
|
+
id="feMergeNode1" />
|
67
|
+
<feMergeNode
|
68
|
+
in="SourceGraphic"
|
69
|
+
id="feMergeNode2" />
|
10
70
|
</feMerge>
|
11
71
|
</filter>
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
72
|
+
<linearGradient
|
73
|
+
id="grad"
|
74
|
+
x1="0"
|
75
|
+
y1="0"
|
76
|
+
x2="1"
|
77
|
+
y2="1">
|
78
|
+
<stop
|
79
|
+
offset="0%"
|
80
|
+
style="stop-color:#00ff88;stop-opacity:1"
|
81
|
+
id="stop2" />
|
82
|
+
<stop
|
83
|
+
offset="100%"
|
84
|
+
style="stop-color:#00cc66;stop-opacity:1"
|
85
|
+
id="stop3" />
|
16
86
|
</linearGradient>
|
87
|
+
<filter
|
88
|
+
style="color-interpolation-filters:sRGB"
|
89
|
+
id="filter6"
|
90
|
+
x="-0.39473927"
|
91
|
+
y="-0.17425425"
|
92
|
+
width="1.7894785"
|
93
|
+
height="1.3485085">
|
94
|
+
<feGaussianBlur
|
95
|
+
stdDeviation="0.4 0.4"
|
96
|
+
result="fbSourceGraphic"
|
97
|
+
id="feGaussianBlur6" />
|
98
|
+
<feColorMatrix
|
99
|
+
result="fbSourceGraphicAlpha"
|
100
|
+
in="fbSourceGraphic"
|
101
|
+
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
102
|
+
id="feColorMatrix8" />
|
103
|
+
<feGaussianBlur
|
104
|
+
id="feGaussianBlur8"
|
105
|
+
stdDeviation="0.4 0.4"
|
106
|
+
result="blur"
|
107
|
+
in="fbSourceGraphic" />
|
108
|
+
</filter>
|
109
|
+
<filter
|
110
|
+
style="color-interpolation-filters:sRGB"
|
111
|
+
id="filter22"
|
112
|
+
x="-0.0064666744"
|
113
|
+
y="-0.45590055"
|
114
|
+
width="1.0129333"
|
115
|
+
height="1.9118011">
|
116
|
+
<feGaussianBlur
|
117
|
+
stdDeviation="0.01 0.1"
|
118
|
+
result="blur"
|
119
|
+
id="feGaussianBlur22" />
|
120
|
+
</filter>
|
121
|
+
<filter
|
122
|
+
style="color-interpolation-filters:sRGB"
|
123
|
+
id="filter23"
|
124
|
+
x="-0.00056465436"
|
125
|
+
y="-0.20969008"
|
126
|
+
width="1.0011293"
|
127
|
+
height="1.4193802">
|
128
|
+
<feGaussianBlur
|
129
|
+
stdDeviation="0.01 0.11"
|
130
|
+
result="blur"
|
131
|
+
id="feGaussianBlur23" />
|
132
|
+
</filter>
|
133
|
+
<filter
|
134
|
+
id="filter28"
|
135
|
+
x="-0.040088417"
|
136
|
+
y="-0.21380489"
|
137
|
+
width="1.0801768"
|
138
|
+
height="1.4276098">
|
139
|
+
<feGaussianBlur
|
140
|
+
stdDeviation="2.1380488"
|
141
|
+
result="coloredBlur"
|
142
|
+
id="feGaussianBlur27" />
|
143
|
+
<feMerge
|
144
|
+
id="feMerge28">
|
145
|
+
<feMergeNode
|
146
|
+
in="coloredBlur"
|
147
|
+
id="feMergeNode27" />
|
148
|
+
<feMergeNode
|
149
|
+
in="SourceGraphic"
|
150
|
+
id="feMergeNode28" />
|
151
|
+
</feMerge>
|
152
|
+
</filter>
|
153
|
+
<filter
|
154
|
+
id="filter35"
|
155
|
+
x="-0.40035462"
|
156
|
+
y="-0.048042555"
|
157
|
+
width="1.8007092"
|
158
|
+
height="1.0960851">
|
159
|
+
<feGaussianBlur
|
160
|
+
stdDeviation="4.003546"
|
161
|
+
result="coloredBlur"
|
162
|
+
id="feGaussianBlur34" />
|
163
|
+
<feMerge
|
164
|
+
id="feMerge35">
|
165
|
+
<feMergeNode
|
166
|
+
in="coloredBlur"
|
167
|
+
id="feMergeNode34" />
|
168
|
+
<feMergeNode
|
169
|
+
in="SourceGraphic"
|
170
|
+
id="feMergeNode35" />
|
171
|
+
</feMerge>
|
172
|
+
</filter>
|
173
|
+
<filter
|
174
|
+
style="color-interpolation-filters:sRGB"
|
175
|
+
id="filter36"
|
176
|
+
x="-0.092322366"
|
177
|
+
y="-0.059838278"
|
178
|
+
width="1.1846447"
|
179
|
+
height="1.1196766">
|
180
|
+
<feGaussianBlur
|
181
|
+
stdDeviation="0.25392894"
|
182
|
+
id="feGaussianBlur36" />
|
183
|
+
</filter>
|
17
184
|
</defs>
|
185
|
+
<rect
|
186
|
+
width="135.46666"
|
187
|
+
height="135.46666"
|
188
|
+
fill="#0d1117"
|
189
|
+
id="rect3"
|
190
|
+
x="-0.15747385"
|
191
|
+
y="-0.34253129"
|
192
|
+
style="stroke-width:0.264583" />
|
193
|
+
<rect
|
194
|
+
x="8.3091898"
|
195
|
+
y="8.124136"
|
196
|
+
width="118.27769"
|
197
|
+
height="10.583333"
|
198
|
+
rx="4.2242026"
|
199
|
+
ry="4.2333331"
|
200
|
+
fill="#161b22"
|
201
|
+
id="rect5"
|
202
|
+
style="stroke-width:0.264298" />
|
203
|
+
<rect
|
204
|
+
x="8.3091898"
|
205
|
+
y="8.124136"
|
206
|
+
width="118.53333"
|
207
|
+
height="118.53333"
|
208
|
+
rx="4.2333331"
|
209
|
+
ry="4.2333331"
|
210
|
+
fill="none"
|
211
|
+
stroke="#00ff88"
|
212
|
+
stroke-width="0.79375"
|
213
|
+
opacity="0.8"
|
214
|
+
id="rect4" />
|
215
|
+
<circle
|
216
|
+
cx="14.659192"
|
217
|
+
cy="13.4158"
|
218
|
+
fill="#ff5f56"
|
219
|
+
id="circle5"
|
220
|
+
style="stroke-width:0.264583"
|
221
|
+
r="1.5875" />
|
222
|
+
<circle
|
223
|
+
cx="19.950855"
|
224
|
+
cy="13.4158"
|
225
|
+
fill="#ffbd2e"
|
226
|
+
id="circle6"
|
227
|
+
style="stroke-width:0.264583"
|
228
|
+
r="1.5875" />
|
229
|
+
<circle
|
230
|
+
cx="25.242527"
|
231
|
+
cy="13.4158"
|
232
|
+
fill="#27c93f"
|
233
|
+
id="circle7"
|
234
|
+
style="stroke-width:0.264583"
|
235
|
+
r="1.5875" />
|
236
|
+
<rect
|
237
|
+
x="96"
|
238
|
+
y="120"
|
239
|
+
width="24"
|
240
|
+
height="200"
|
241
|
+
fill="url(#grad)"
|
242
|
+
id="rect7"
|
243
|
+
style="fill:#00e878;fill-opacity:1;filter:url(#glow)"
|
244
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)" />
|
245
|
+
<rect
|
246
|
+
x="200"
|
247
|
+
y="120"
|
248
|
+
width="24"
|
249
|
+
height="200"
|
250
|
+
fill="url(#grad)"
|
251
|
+
id="rect8"
|
252
|
+
style="fill:#00e979;fill-opacity:1;filter:url(#filter35)"
|
253
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)" />
|
254
|
+
<rect
|
255
|
+
x="96"
|
256
|
+
y="208"
|
257
|
+
width="128"
|
258
|
+
height="24"
|
259
|
+
fill="url(#grad)"
|
260
|
+
id="rect9"
|
261
|
+
style="mix-blend-mode:normal;fill:#00ea7a;fill-opacity:1;filter:url(#filter28)"
|
262
|
+
transform="matrix(0.26111189,0,0,0.26713774,0.40397665,-0.8584999)" />
|
263
|
+
<rect
|
264
|
+
x="260"
|
265
|
+
y="160"
|
266
|
+
width="8"
|
267
|
+
height="8"
|
268
|
+
fill="#00ff88"
|
269
|
+
id="rect11"
|
270
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
271
|
+
style="filter:url(#glow)" />
|
272
|
+
<rect
|
273
|
+
x="276"
|
274
|
+
y="162"
|
275
|
+
width="100"
|
276
|
+
height="4"
|
277
|
+
fill="#00ff88"
|
278
|
+
opacity="0.6"
|
279
|
+
id="rect12"
|
280
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
281
|
+
style="filter:url(#glow)" />
|
282
|
+
<rect
|
283
|
+
x="260"
|
284
|
+
y="190"
|
285
|
+
width="12"
|
286
|
+
height="12"
|
287
|
+
fill="none"
|
288
|
+
stroke="#00ff88"
|
289
|
+
stroke-width="2"
|
290
|
+
id="rect13"
|
291
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
292
|
+
style="filter:url(#glow)" />
|
293
|
+
<polyline
|
294
|
+
points="263,196 266,199 270,193"
|
295
|
+
stroke="#00ff88"
|
296
|
+
stroke-width="2"
|
297
|
+
fill="none"
|
298
|
+
id="polyline13"
|
299
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
300
|
+
style="filter:url(#glow)" />
|
301
|
+
<rect
|
302
|
+
x="280"
|
303
|
+
y="194"
|
304
|
+
width="96"
|
305
|
+
height="4"
|
306
|
+
fill="#00ff88"
|
307
|
+
opacity="0.6"
|
308
|
+
id="rect14"
|
309
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
310
|
+
style="filter:url(#glow)" />
|
311
|
+
<rect
|
312
|
+
x="260"
|
313
|
+
y="220"
|
314
|
+
width="8"
|
315
|
+
height="8"
|
316
|
+
fill="#00ff88"
|
317
|
+
id="rect15"
|
318
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
319
|
+
style="filter:url(#glow)" />
|
320
|
+
<rect
|
321
|
+
x="276"
|
322
|
+
y="222"
|
323
|
+
width="100"
|
324
|
+
height="4"
|
325
|
+
fill="#00ff88"
|
326
|
+
opacity="0.6"
|
327
|
+
id="rect16"
|
328
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
329
|
+
style="filter:url(#glow)" />
|
330
|
+
<rect
|
331
|
+
x="288"
|
332
|
+
y="250"
|
333
|
+
width="6"
|
334
|
+
height="6"
|
335
|
+
fill="#00cc66"
|
336
|
+
id="rect17"
|
337
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
338
|
+
style="filter:url(#glow)" />
|
339
|
+
<rect
|
340
|
+
x="300"
|
341
|
+
y="251"
|
342
|
+
width="76"
|
343
|
+
height="3"
|
344
|
+
fill="#00cc66"
|
345
|
+
opacity="0.5"
|
346
|
+
id="rect18"
|
347
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
348
|
+
style="filter:url(#glow)" />
|
349
|
+
<rect
|
350
|
+
x="260"
|
351
|
+
y="280"
|
352
|
+
width="8"
|
353
|
+
height="8"
|
354
|
+
fill="#00ff88"
|
355
|
+
id="rect19"
|
356
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
357
|
+
style="filter:url(#glow)" />
|
358
|
+
<rect
|
359
|
+
x="276"
|
360
|
+
y="282"
|
361
|
+
width="100"
|
362
|
+
height="4"
|
363
|
+
fill="#00ff88"
|
364
|
+
opacity="0.6"
|
365
|
+
id="rect20"
|
366
|
+
transform="matrix(0.26458333,0,0,0.26458333,-0.15747435,-0.3425329)"
|
367
|
+
style="filter:url(#glow)" />
|
368
|
+
<text
|
369
|
+
x="24.334553"
|
370
|
+
y="97.818535"
|
371
|
+
font-family="monospace"
|
372
|
+
font-size="4.57279px"
|
373
|
+
fill="#00ff88"
|
374
|
+
opacity="0.4"
|
375
|
+
id="text21"
|
376
|
+
style="stroke-width:0.326627">hyperlist v1.4.0 $</text>
|
377
|
+
<rect
|
378
|
+
style="fill:#00fe87;fill-opacity:1;stroke:none;stroke-width:5.98157;filter:url(#filter22)"
|
379
|
+
id="rect22"
|
380
|
+
width="3.7113357"
|
381
|
+
height="0.52643061"
|
382
|
+
x="68.35778"
|
383
|
+
y="52.855618"
|
384
|
+
ry="0" />
|
385
|
+
<rect
|
386
|
+
style="fill:#00e878;fill-opacity:1;stroke:none;stroke-width:6.174;filter:url(#filter36)"
|
387
|
+
id="rect35"
|
388
|
+
width="6.6011028"
|
389
|
+
height="10.184608"
|
390
|
+
x="101.5478"
|
391
|
+
y="73.953667"
|
392
|
+
ry="0.096021399">
|
393
|
+
<animate
|
394
|
+
attributeName="opacity"
|
395
|
+
values="1;0;1"
|
396
|
+
dur="1s"
|
397
|
+
repeatCount="indefinite" />
|
398
|
+
</rect>
|
399
|
+
</svg>
|
400
|
+
<!-- Terminal cursor blink -->
|
18
401
|
|
19
|
-
<!-- Dark terminal background -->
|
20
|
-
<rect width="512" height="512" fill="#0d1117"/>
|
21
|
-
|
22
|
-
<!-- Terminal frame with rounded corners -->
|
23
|
-
<rect x="32" y="32" width="448" height="448" rx="16" ry="16"
|
24
|
-
fill="none" stroke="#00ff88" stroke-width="3" opacity="0.8"/>
|
25
|
-
|
26
|
-
<!-- Terminal header bar -->
|
27
|
-
<rect x="32" y="32" width="448" height="40" rx="16" ry="16" fill="#161b22"/>
|
28
|
-
<circle cx="56" cy="52" r="6" fill="#ff5f56"/>
|
29
|
-
<circle cx="76" cy="52" r="6" fill="#ffbd2e"/>
|
30
|
-
<circle cx="96" cy="52" r="6" fill="#27c93f"/>
|
31
|
-
|
32
|
-
<!-- Main HyperList logo design -->
|
33
|
-
<g filter="url(#glow)">
|
34
|
-
<!-- Large H that forms into list structure -->
|
35
|
-
<!-- Left vertical of H -->
|
36
|
-
<rect x="96" y="120" width="24" height="200" fill="url(#grad)"/>
|
37
|
-
<!-- Right vertical of H -->
|
38
|
-
<rect x="200" y="120" width="24" height="200" fill="url(#grad)"/>
|
39
|
-
<!-- Horizontal crossbar of H -->
|
40
|
-
<rect x="96" y="208" width="128" height="24" fill="url(#grad)"/>
|
41
|
-
|
42
|
-
<!-- List items branching from H -->
|
43
|
-
<!-- Main branch -->
|
44
|
-
<rect x="224" y="208" width="160" height="4" fill="#00ff88" opacity="0.8"/>
|
45
|
-
|
46
|
-
<!-- List item 1 -->
|
47
|
-
<rect x="260" y="160" width="8" height="8" fill="#00ff88"/>
|
48
|
-
<rect x="276" y="162" width="100" height="4" fill="#00ff88" opacity="0.6"/>
|
49
|
-
|
50
|
-
<!-- List item 2 with checkbox -->
|
51
|
-
<rect x="260" y="190" width="12" height="12" fill="none" stroke="#00ff88" stroke-width="2"/>
|
52
|
-
<polyline points="263,196 266,199 270,193" stroke="#00ff88" stroke-width="2" fill="none"/>
|
53
|
-
<rect x="280" y="194" width="96" height="4" fill="#00ff88" opacity="0.6"/>
|
54
|
-
|
55
|
-
<!-- List item 3 -->
|
56
|
-
<rect x="260" y="220" width="8" height="8" fill="#00ff88"/>
|
57
|
-
<rect x="276" y="222" width="100" height="4" fill="#00ff88" opacity="0.6"/>
|
58
|
-
|
59
|
-
<!-- Nested item -->
|
60
|
-
<rect x="288" y="250" width="6" height="6" fill="#00cc66"/>
|
61
|
-
<rect x="300" y="251" width="76" height="3" fill="#00cc66" opacity="0.5"/>
|
62
|
-
|
63
|
-
<!-- List item 4 -->
|
64
|
-
<rect x="260" y="280" width="8" height="8" fill="#00ff88"/>
|
65
|
-
<rect x="276" y="282" width="100" height="4" fill="#00ff88" opacity="0.6"/>
|
66
|
-
|
67
|
-
<!-- Terminal cursor blink -->
|
68
|
-
<rect x="384" y="280" width="16" height="24" fill="#00ff88">
|
69
|
-
<animate attributeName="opacity" values="1;0;1" dur="1s" repeatCount="indefinite"/>
|
70
|
-
</rect>
|
71
|
-
</g>
|
72
|
-
|
73
|
-
<!-- Subtle terminal prompt at bottom -->
|
74
|
-
<text x="96" y="380" font-family="monospace" font-size="14" fill="#00ff88" opacity="0.4">
|
75
|
-
hyperlist v1.0.0 $
|
76
|
-
</text>
|
77
|
-
</svg>
|
data/sample.hl
CHANGED
@@ -81,5 +81,29 @@ HyperList Sample Document
|
|
81
81
|
_Underlined text example_
|
82
82
|
Combined: *bold and /italic/ together*
|
83
83
|
Hash tags: #important #urgent #review
|
84
|
+
Multi-line Items (HyperList spec)
|
85
|
+
+ This is a multi-line item that continues
|
86
|
+
on the next line with a space prefix
|
87
|
+
+ Items with the plus sign can span multiple lines
|
88
|
+
making it easy to write longer descriptions
|
89
|
+
without creating separate items
|
90
|
+
Consistency Rule Example
|
91
|
+
1 When one item at a level has a starter (identifier)
|
92
|
+
all items at that level need starters
|
93
|
+
2 This second item also needs an identifier
|
94
|
+
+ Or you can use a plus sign as starter
|
95
|
+
Nested Multi-line Items
|
96
|
+
+ Parent item that spans multiple lines
|
97
|
+
with detailed information on the first level
|
98
|
+
+ Child item also spanning multiple lines
|
99
|
+
providing more specific details
|
100
|
+
Regular child item after multi-line
|
101
|
+
Real-world Examples
|
102
|
+
+ Meeting notes from project kickoff: Discussed timeline,
|
103
|
+
budget constraints, resource allocation, and identified
|
104
|
+
key stakeholders who need to be involved
|
105
|
+
+ Action item: Research competitive solutions in the market,
|
106
|
+
compile findings into a report, and present recommendations
|
107
|
+
to the management team by end of month
|
84
108
|
|
85
109
|
((fold_level=3))
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hyperlist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Geir Isene
|
8
8
|
autorequire:
|
9
9
|
bindir: "."
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rcurses
|