@@ -24,6 +24,7 @@ type CodeHighlightInfo struct {
24
24
Language string
25
25
Ranges []LineRange
26
26
ShowLineNumbers bool
27
+ StartLine int
27
28
}
28
29
29
30
func parseHighlightSyntax (syntax string ) []LineRange {
@@ -92,7 +93,8 @@ func renderWithStyle(content string, info CodeHighlightInfo, lexer chroma.Lexer,
92
93
93
94
lineNumberWidth := 0
94
95
if info .ShowLineNumbers {
95
- lineNumberWidth = len (strconv .Itoa (len (lines ))) + 2
96
+ maxLineNum := info .StartLine + len (lines ) - 1
97
+ lineNumberWidth = len (strconv .Itoa (maxLineNum )) + 2
96
98
}
97
99
98
100
lineNumberStyle := lipgloss .NewStyle ().
@@ -101,19 +103,19 @@ func renderWithStyle(content string, info CodeHighlightInfo, lexer chroma.Lexer,
101
103
102
104
var result strings.Builder
103
105
for lineNum , line := range lines {
104
- lineNumDisplay := lineNum + 1
106
+ displayLineNum := info .StartLine + lineNum
107
+ relativeLineNum := lineNum + 1
105
108
106
109
// Add line number if requested
107
110
if info .ShowLineNumbers {
108
- lineNumStr := strconv .Itoa (lineNumDisplay )
111
+ lineNumStr := strconv .Itoa (displayLineNum )
109
112
paddedLineNum := fmt .Sprintf ("%*s" , lineNumberWidth - 1 , lineNumStr )
110
113
result .WriteString (lineNumberStyle .Render (paddedLineNum ))
111
114
}
112
115
113
- shouldHighlight := len (info .Ranges ) == 0 || shouldHighlightLine (lineNumDisplay , info .Ranges )
116
+ shouldHighlight := len (info .Ranges ) == 0 || shouldHighlightLine (relativeLineNum , info .Ranges )
114
117
115
118
if ! shouldHighlight {
116
- // No syntax highlighting for this line
117
119
result .WriteString (line )
118
120
if lineNum < len (lines )- 1 {
119
121
result .WriteString ("\n " )
@@ -159,7 +161,7 @@ func renderWithStyle(content string, info CodeHighlightInfo, lexer chroma.Lexer,
159
161
}
160
162
161
163
func processMarkdownWithHighlighting (markdown string , themeName string ) (string , error ) {
162
- re := regexp .MustCompile ("(?s)```([a-zA-Z0-9_+-]*)({[^}]*})?(\\ s+--numbered)?\\ s*\n (.*?)\n ```" )
164
+ re := regexp .MustCompile ("(?s)```([a-zA-Z0-9_+-]*)({[^}]*})?(\\ s+--numbered)?( \\ s+--start-at-line \\ s+( \\ d+))? \\ s*\n (.*?)\n ```" )
163
165
164
166
matches := re .FindAllStringSubmatch (markdown , - 1 )
165
167
if len (matches ) == 0 {
@@ -172,7 +174,7 @@ func processMarkdownWithHighlighting(markdown string, themeName string) (string,
172
174
indices := re .FindAllStringIndex (markdown , - 1 )
173
175
174
176
for i , match := range matches {
175
- if len (match ) < 5 {
177
+ if len (match ) < 7 {
176
178
continue
177
179
}
178
180
@@ -200,12 +202,21 @@ func processMarkdownWithHighlighting(markdown string, themeName string) (string,
200
202
highlightSyntax = match [2 ] // e.g., "{1-2}"
201
203
}
202
204
numberedFlag := strings .TrimSpace (match [3 ]) // " --numbered"
203
- content := match [4 ] // The actual code content
205
+ startLineStr := match [5 ] // The line number from --start-at-line
206
+ content := match [6 ] // The actual code content
207
+
208
+ startLine := 1
209
+ if startLineStr != "" {
210
+ if parsed , err := strconv .Atoi (startLineStr ); err == nil && parsed > 0 {
211
+ startLine = parsed
212
+ }
213
+ }
204
214
205
215
info := CodeHighlightInfo {
206
216
Language : language ,
207
217
Ranges : parseHighlightSyntax (highlightSyntax ),
208
218
ShowLineNumbers : strings .Contains (numberedFlag , "--numbered" ),
219
+ StartLine : startLine ,
209
220
}
210
221
211
222
if language != "" || info .ShowLineNumbers {
0 commit comments