hyperlist 1.4.1 → 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/CHANGELOG.md +14 -0
- data/hyperlist +160 -101
- 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/CHANGELOG.md
CHANGED
@@ -2,6 +2,20 @@
|
|
2
2
|
|
3
3
|
All notable changes to the HyperList Ruby TUI will be documented in this file.
|
4
4
|
|
5
|
+
## [1.4.2] - 2025-08-29
|
6
|
+
|
7
|
+
### Fixed
|
8
|
+
- **Help screen improvements**
|
9
|
+
- Fixed help screen crash issue with CONFIGURATION section
|
10
|
+
- Improved alignment of :set commands in help
|
11
|
+
- Added working CONFIGURATION section with proper formatting
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
- **Code cleanup**
|
15
|
+
- Removed debug logging code
|
16
|
+
- Cleaned up unused variables
|
17
|
+
- Improved code consistency
|
18
|
+
|
5
19
|
## [1.4.1] - 2025-08-29
|
6
20
|
|
7
21
|
### Fixed
|
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
|
@@ -2794,13 +2853,8 @@ class HyperListApp
|
|
2794
2853
|
end
|
2795
2854
|
|
2796
2855
|
def show_help
|
2797
|
-
|
2798
|
-
|
2799
|
-
help_lines = []
|
2800
|
-
|
2801
|
-
# Debug logging
|
2802
|
-
debug_log = File.open("/tmp/hyperlist_help_debug.log", "w") rescue nil
|
2803
|
-
debug_log.puts "show_help called at #{Time.now}" if debug_log
|
2856
|
+
# Build help text using consistent formatting
|
2857
|
+
help_lines = []
|
2804
2858
|
help_lines << " Press #{"?".fg("10")} for full documentation, #{"UP/DOWN".fg("10")} to scroll, or any other key to return"
|
2805
2859
|
help_lines << ""
|
2806
2860
|
help_lines << "#{"HYPERLIST KEY BINDINGS".b}"
|
@@ -2859,27 +2913,13 @@ class HyperListApp
|
|
2859
2913
|
help_lines << help_line("#{":dt".fg("10")}", "Delete template", "#{":lt".fg("10")}", "List user templates")
|
2860
2914
|
help_lines << ""
|
2861
2915
|
|
2862
|
-
|
2863
|
-
|
2864
|
-
|
2865
|
-
|
2866
|
-
|
2867
|
-
|
2868
|
-
|
2869
|
-
debug_log.puts "Line1: #{line1.inspect}" if debug_log
|
2870
|
-
help_lines << line1
|
2871
|
-
|
2872
|
-
line2 = help_line("#{":set option=val".fg("10")}", "Set option")
|
2873
|
-
debug_log.puts "Line2: #{line2.inspect}" if debug_log
|
2874
|
-
help_lines << line2
|
2875
|
-
|
2876
|
-
help_lines << ""
|
2877
|
-
debug_log.puts "CONFIGURATION section complete" if debug_log
|
2878
|
-
rescue => e
|
2879
|
-
debug_log.puts "Error in CONFIGURATION: #{e.message}" if debug_log
|
2880
|
-
debug_log.puts e.backtrace.join("\n") if debug_log
|
2881
|
-
# Fall through and continue without config section
|
2882
|
-
end
|
2916
|
+
help_lines << "#{"CONFIGURATION".fg("14")}"
|
2917
|
+
help_lines << help_line("#{":set".fg("10")}", "Show all settings")
|
2918
|
+
help_lines << help_line("#{":set o".fg("10")}", "Show option value")
|
2919
|
+
help_lines << help_line("#{":set o=val".fg("10")}", "Set option value")
|
2920
|
+
help_lines << help_line("#{"Options:".fg("245")}", "theme, wrap, fold_level")
|
2921
|
+
help_lines << help_line("#{"".fg("245")}", "show_numbers, tab_width")
|
2922
|
+
help_lines << ""
|
2883
2923
|
|
2884
2924
|
help_lines << "#{"HELP & QUIT".fg("14")}"
|
2885
2925
|
help_lines << help_line("#{"?".fg("10")}", "This help", "#{"??".fg("10")}", "Full documentation")
|
@@ -2895,9 +2935,6 @@ class HyperListApp
|
|
2895
2935
|
|
2896
2936
|
help = help_lines.join("\n")
|
2897
2937
|
|
2898
|
-
debug_log.puts "Help generation complete, #{help_lines.length} lines" if debug_log
|
2899
|
-
debug_log.close if debug_log
|
2900
|
-
|
2901
2938
|
# Store current state
|
2902
2939
|
saved_items = @items.dup
|
2903
2940
|
saved_current = @current
|
@@ -2951,18 +2988,6 @@ class HyperListApp
|
|
2951
2988
|
@current = saved_current
|
2952
2989
|
@offset = saved_offset
|
2953
2990
|
@modified = saved_modified
|
2954
|
-
|
2955
|
-
rescue => e
|
2956
|
-
# Log the error and show a simple message
|
2957
|
-
File.open("/tmp/hyperlist_help_crash.log", "w") do |f|
|
2958
|
-
f.puts "Help crashed at #{Time.now}"
|
2959
|
-
f.puts "Error: #{e.message}"
|
2960
|
-
f.puts "Backtrace:"
|
2961
|
-
f.puts e.backtrace.join("\n")
|
2962
|
-
end rescue nil
|
2963
|
-
|
2964
|
-
@message = "Help error logged to /tmp/hyperlist_help_crash.log"
|
2965
|
-
end
|
2966
2991
|
end
|
2967
2992
|
|
2968
2993
|
def show_documentation
|
@@ -4908,46 +4933,77 @@ class HyperListApp
|
|
4908
4933
|
|
4909
4934
|
# Build ALL lines for the pane (like we do for main pane)
|
4910
4935
|
lines = []
|
4936
|
+
|
4937
|
+
# Track which line number each item starts at (for scroll calculation)
|
4938
|
+
item_line_starts = {}
|
4939
|
+
|
4911
4940
|
visible_items.each_with_index do |item, idx|
|
4912
4941
|
next unless item
|
4913
4942
|
|
4943
|
+
# Record where this item starts in the display
|
4944
|
+
item_line_starts[idx] = lines.length
|
4945
|
+
|
4914
4946
|
# Find the item's position in the original split_items array
|
4915
4947
|
real_idx = @split_items.index(item)
|
4916
4948
|
|
4917
|
-
#
|
4918
|
-
|
4919
|
-
|
4920
|
-
actual_line_number = real_idx ? real_idx + 1 : 0 # +1 for 1-based line numbers
|
4921
|
-
line = "#{actual_line_number.to_s.rjust(4)} "
|
4922
|
-
end
|
4949
|
+
# Handle multi-line items (split by embedded newlines)
|
4950
|
+
embedded_lines = item["text"].split("\n")
|
4951
|
+
text_lines = []
|
4923
4952
|
|
4924
|
-
|
4925
|
-
|
4926
|
-
|
4927
|
-
|
4928
|
-
|
4929
|
-
line += "▶".fg("245") + " "
|
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)
|
4930
4958
|
else
|
4931
|
-
|
4959
|
+
text_lines << embedded_line
|
4932
4960
|
end
|
4933
|
-
else
|
4934
|
-
line += " "
|
4935
4961
|
end
|
4936
4962
|
|
4937
|
-
|
4938
|
-
|
4939
|
-
|
4940
|
-
|
4941
|
-
|
4942
|
-
|
4943
|
-
|
4944
|
-
|
4945
|
-
|
4946
|
-
|
4947
|
-
|
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
|
4948
5006
|
end
|
4949
|
-
|
4950
|
-
lines << line
|
4951
5007
|
end
|
4952
5008
|
|
4953
5009
|
# Add a blank line at the bottom to show end of document
|
@@ -4968,22 +5024,25 @@ class HyperListApp
|
|
4968
5024
|
end
|
4969
5025
|
end
|
4970
5026
|
|
4971
|
-
# Calculate scroll position
|
5027
|
+
# Calculate scroll position based on actual line positions, not item indices
|
4972
5028
|
scrolloff = 3
|
4973
|
-
|
4974
|
-
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
|
4975
5034
|
|
4976
|
-
if
|
5035
|
+
if total_lines <= page
|
4977
5036
|
# If everything fits, always start from the very top
|
4978
5037
|
@split_pane.ix = 0
|
4979
|
-
elsif
|
5038
|
+
elsif current_line - @split_pane.ix < scrolloff
|
4980
5039
|
# If we're too close to the top of the pane, scroll up
|
4981
|
-
@split_pane.ix = [
|
4982
|
-
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
|
4983
5042
|
# If we're too close to the bottom of the pane, scroll down
|
4984
|
-
#
|
4985
|
-
|
4986
|
-
@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
|
4987
5046
|
end
|
4988
5047
|
|
4989
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
|