aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/libgemini/libgemini.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/libgemini/libgemini.go')
-rw-r--r--pkg/libgemini/libgemini.go85
1 files changed, 50 insertions, 35 deletions
diff --git a/pkg/libgemini/libgemini.go b/pkg/libgemini/libgemini.go
index 71012ef..48a8ed0 100644
--- a/pkg/libgemini/libgemini.go
+++ b/pkg/libgemini/libgemini.go
@@ -6,7 +6,6 @@ import (
6 "crypto/tls" 6 "crypto/tls"
7 "errors" 7 "errors"
8 "fmt" 8 "fmt"
9 "html/template"
10 "io" 9 "io"
11 "mime" 10 "mime"
12 "net" 11 "net"
@@ -74,19 +73,19 @@ type Response struct {
74type GeminiDocSectionType byte 73type GeminiDocSectionType byte
75 74
76const ( 75const (
77 RAW_TEXT = SectionType(0) 76 RAW_TEXT = GeminiDocSectionType(0)
78 REFLOW_TEXT = SectionType(1) 77 REFLOW_TEXT = GeminiDocSectionType(1)
79 LINK = SectionType(2) 78 LINK = GeminiDocSectionType(2)
80 HEADING_1 = SectionType(3) 79 HEADING_1 = GeminiDocSectionType(3)
81 HEADING_2 = SectionType(4) 80 HEADING_2 = GeminiDocSectionType(4)
82 HEADING_3 = SectionType(5) 81 HEADING_3 = GeminiDocSectionType(5)
83 LIST = SectionType(6) 82 LIST = GeminiDocSectionType(6)
84) 83)
85 84
86type GeminiDocSection struct { 85type GeminiDocSection struct {
87 Type SectionType 86 Type GeminiDocSectionType
88 Text string 87 Text string
89 URL template.URL 88 URL string
90 Items []string 89 Items []string
91} 90}
92 91
@@ -171,13 +170,13 @@ func ParseHeader(line string) (header *Header, err error) {
171 return 170 return
172} 171}
173 172
174func ParseGeminiDocument(body *bytes.Buffer) (sections []Section) { 173func ParseGeminiDocument(body *bytes.Buffer) (sections []GeminiDocSection) {
175 scanner := bufio.NewScanner(body) 174 scanner := bufio.NewScanner(body)
176 175
177 reflow := true 176 reflow := true
178 ignoreSection := true 177 ignoreSection := true
179 section := Section{ 178 section := GeminiDocSection{
180 Type: REFLOW_TEXT 179 Type: REFLOW_TEXT,
181 } 180 }
182 181
183 for scanner.Scan() { 182 for scanner.Scan() {
@@ -185,23 +184,23 @@ func ParseGeminiDocument(body *bytes.Buffer) (sections []Section) {
185 line = TermEscapeSGRPattern.ReplaceAllString(line, "") 184 line = TermEscapeSGRPattern.ReplaceAllString(line, "")
186 185
187 reflowMatch := ReflowModePattern.FindStringSubmatch(line) 186 reflowMatch := ReflowModePattern.FindStringSubmatch(line)
188 if len(heading3Match) != 0 { 187 if len(reflowMatch) != 0 && reflowMatch[0] != "" {
189 reflow = !reflow 188 reflow = !reflow
190 continue 189 continue
191 } 190 }
192 191
193 if !reflow { 192 if !reflow {
194 if !ignoreSection { 193 if !ignoreSection {
195 if section.Type != REFLOW_TEXT { 194 if section.Type != RAW_TEXT {
196 sections = append(sections, section) 195 sections = append(sections, section)
197 section = Section{ 196 section = GeminiDocSection{
198 Type: REFLOW_TEXT 197 Type: RAW_TEXT,
199 } 198 }
200 } 199 }
201 } else { 200 } else {
202 ignoreSection = false 201 ignoreSection = false
203 section = Section{ 202 section = GeminiDocSection{
204 Type: REFLOW_TEXT 203 Type: RAW_TEXT,
205 } 204 }
206 } 205 }
207 206
@@ -222,80 +221,96 @@ func ParseGeminiDocument(body *bytes.Buffer) (sections []Section) {
222 } 221 }
223 222
224 ignoreSection = false 223 ignoreSection = false
225 section = Section{ 224 section = GeminiDocSection{
226 Type: LINK, 225 Type: LINK,
227 Text: label, 226 Text: label,
228 URL: template.URL(resolveURI(linkMatch[1], baseURL)), 227 URL: linkMatch[1],
229 } 228 }
230 229
231 continue 230 continue
232 } 231 }
233 232
234 heading3Match := Heading3Pattern.FindStringSubmatch(line) 233 heading3Match := Heading3Pattern.FindStringSubmatch(line)
235 if len(heading3Match) != 0 { 234 if len(heading3Match) != 0 && heading3Match[0] != "" {
236 if !ignoreSection { 235 if !ignoreSection {
237 sections = append(sections, section) 236 sections = append(sections, section)
238 } 237 }
239 238
240 ignoreSection = false 239 ignoreSection = false
241 section = Section{ 240 section = GeminiDocSection{
242 Type: HEADING_3, 241 Type: HEADING_3,
243 Text: heading3Match[1] 242 Text: heading3Match[1],
244 } 243 }
245 244
246 continue 245 continue
247 } 246 }
248 247
249 heading2Match := Heading2Pattern.FindStringSubmatch(line) 248 heading2Match := Heading2Pattern.FindStringSubmatch(line)
250 if len(heading2Match) != 0 { 249 if len(heading2Match) != 0 && heading2Match[0] != "" {
251 if !ignoreSection { 250 if !ignoreSection {
252 sections = append(sections, section) 251 sections = append(sections, section)
253 } 252 }
254 253
255 ignoreSection = false 254 ignoreSection = false
256 section = Section{ 255 section = GeminiDocSection{
257 Type: HEADING_2, 256 Type: HEADING_2,
258 Text: heading2Match[1] 257 Text: heading2Match[1],
259 } 258 }
260 259
261 continue 260 continue
262 } 261 }
263 262
264 heading1Match := Heading1Pattern.FindStringSubmatch(line) 263 heading1Match := Heading1Pattern.FindStringSubmatch(line)
265 if len(heading1Match) != 0 { 264 if len(heading1Match) != 0 && heading1Match[0] != "" {
266 if !ignoreSection { 265 if !ignoreSection {
267 sections = append(sections, section) 266 sections = append(sections, section)
268 } 267 }
269 268
270 ignoreSection = false 269 ignoreSection = false
271 section = Section{ 270 section = GeminiDocSection{
272 Type: HEADING_1, 271 Type: HEADING_1,
273 Text: heading1Match[1] 272 Text: heading1Match[1],
274 } 273 }
275 274
276 continue 275 continue
277 } 276 }
278 277
279 listItemMatch := ListItemPattern.FindStringSubmatch(line) 278 listItemMatch := ListItemPattern.FindStringSubmatch(line)
280 if len(listItemMatch) != 0 { 279 if len(listItemMatch) != 0 && listItemMatch[0] != "" {
281 if !ignoreSection { 280 if !ignoreSection {
282 if section.Type != LIST { 281 if section.Type != LIST {
283 sections = append(sections, section) 282 sections = append(sections, section)
284 section = Section{ 283 section = GeminiDocSection{
285 Type: LIST 284 Type: LIST,
286 } 285 }
287 } 286 }
288 } else { 287 } else {
289 ignoreSection = false 288 ignoreSection = false
290 section = Section{ 289 section = GeminiDocSection{
291 Type: LIST, 290 Type: LIST,
292 } 291 }
293 } 292 }
294 293
295 section.Items = append(section.Items, listItemMatch[1]) 294 section.Items = append(section.Items, listItemMatch[1])
296 295
297 continue 296 continue
298 } 297 }
298
299 if !ignoreSection {
300 if section.Type != REFLOW_TEXT {
301 sections = append(sections, section)
302 section = GeminiDocSection{
303 Type: REFLOW_TEXT,
304 }
305 }
306 } else {
307 ignoreSection = false
308 section = GeminiDocSection{
309 Type: REFLOW_TEXT,
310 }
311 }
312
313 section.Text = section.Text + "\n" + line
299 } 314 }
300 315
301 if !ignoreSection { 316 if !ignoreSection {