From 2b231184d89f971d06feb321ebdd46749611ad01 Mon Sep 17 00:00:00 2001 From: asdf Date: Wed, 8 Jan 2020 14:33:49 +1100 Subject: [PATCH 01/14] Added DEVELOPING.md to include versioning process steps --- DEVELOPING.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 6 +---- 2 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 DEVELOPING.md diff --git a/DEVELOPING.md b/DEVELOPING.md new file mode 100644 index 0000000..019f1d0 --- /dev/null +++ b/DEVELOPING.md @@ -0,0 +1,67 @@ +# Developing Bombadillo + +## Getting Started + +Following the standard install instructions should lead you to have nearly everything you need to commence development. The only additions to this are: + +- To be able to submit pull requests, you will need to fork this repository first. +- The build process must be tested with Go 1.11 to ensure backward compatibility. This version can be installed as per the [Go install documentation](https://golang.org/doc/install#extra_versions). Check that changes build with this version using `make test`. +- Linting must be performed on new changes using `gofmt` and [golangci-lint](https://github.com/golangci/golangci-lint) + + +## How changes are made + +A stable version of Bombadillo is kept in the default branch, so that people can easily clone the repo and get a good version of the software. + +New changes are introduced to the **develop** branch. + +Changes to the default branch occur as part of the software release process. This usually occurs when: + + - there are a set of changes in **develop** that are good enough to be considered stable. + - an urgent issue is identified in the stable version that requires immediate changes + + +### Process for introducing a new change + +Please refer to our [notes on contributing](README.md#contributing) to get an understanding of how new changes are initiated, the type of changes accepted and the review process. + +1. Create a new feature branch based on the **develop** branch. +1. Raise a pull request (PR) targeting the **develop** branch. +1. The PR is reviewed. +1. If the PR is approved, it is merged. +1. The version patch number is incremented. + + +### Incrementing the version number + +Version numbers are comprised of three digits: major version number, minor version number, and patch number. + +Each new change added to **develop** should increment the patch number. For example, version 2.0.1 would become 2.0.2. After the change is merged from the feature branch to **develop**: + +```shell +# ensure everything is up to date and in the right place +git checkout develop +git pull + +# get the commit ID for the recent merge +git log + +# get the current version number +git tag + +# add the incremented version number to the commit-id, for example: +git tag 2.0.2 abcdef +``` + +As part of the software release process, any part of the version number may change: +- Urgent changes increment the **patch** number +- A set of small changes increments the **minor** version number +- A significant change to large parts of the application increments the **major** version number + +The process is very similar to the above commands, however the final command should include an annotation: + +```shell +git tag 2.1.0 abdef -a "This version adds several new features..." +``` + +Release information should also be added to the [tildegit releases page](https://tildegit.org/sloum/bombadillo/releases). diff --git a/README.md b/README.md index f965945..1b1af0f 100644 --- a/README.md +++ b/README.md @@ -127,11 +127,7 @@ The maintainers use the [tildegit](https://tildegit.org) issues system to discus ## Development -Following the standard install instructions should lead you to have nearly everything you need to commence development. The only additions to this are: - -- To be able to submit pull requests, you will need to fork this repository first. -- The build process must be tested with Go 1.11 to ensure backward compatibility. This version can be installed as per the [Go install documentation](https://golang.org/doc/install#extra_versions). Check that changes build with this version using `make test`. -- Linting must be performed on new changes using `gofmt` and [golangci-lint](https://github.com/golangci/golangci-lint) +See [DEVELOPING.md](DEVELOPING.md) for information on how changes to Bombadillo are made, along with other technical information for developers. ## License From 6720b62276b4db778cffdc127576321ed858922f Mon Sep 17 00:00:00 2001 From: asdf Date: Wed, 8 Jan 2020 14:57:38 +1100 Subject: [PATCH 02/14] Added information regarding the VERSION file --- DEVELOPING.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/DEVELOPING.md b/DEVELOPING.md index 019f1d0..b6ef58f 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -34,8 +34,14 @@ Please refer to our [notes on contributing](README.md#contributing) to get an un ### Incrementing the version number +This process is handled by maintainers after a change has been merged. + Version numbers are comprised of three digits: major version number, minor version number, and patch number. +The version number is incremented in the following situations: + +#### New changes + Each new change added to **develop** should increment the patch number. For example, version 2.0.1 would become 2.0.2. After the change is merged from the feature branch to **develop**: ```shell @@ -46,22 +52,22 @@ git pull # get the commit ID for the recent merge git log -# get the current version number +# get the current version number (the highest number) git tag # add the incremented version number to the commit-id, for example: -git tag 2.0.2 abcdef +git tag 2.0.2 abcdef ``` +#### Release process + As part of the software release process, any part of the version number may change: + - Urgent changes increment the **patch** number - A set of small changes increments the **minor** version number - A significant change to large parts of the application increments the **major** version number -The process is very similar to the above commands, however the final command should include an annotation: - -```shell -git tag 2.1.0 abdef -a "This version adds several new features..." -``` - -Release information should also be added to the [tildegit releases page](https://tildegit.org/sloum/bombadillo/releases). +1. The version number in the VERSION file is incremented. This change is committed to the default branch. +1. The **develop** branch is merged to the default branch. +1. The commands from the New Changes section are followed, but the final command includes an annotation: `git tag 2.1.0 abdef -a "This version adds several new features..."` +1. Release information should also be added to the [tildegit releases page](https://tildegit.org/sloum/bombadillo/releases). From 3cf27b82ad90237856612e360950fe2b6a3ee162 Mon Sep 17 00:00:00 2001 From: asdf Date: Thu, 23 Jan 2020 13:48:38 +1100 Subject: [PATCH 03/14] Further review of release information --- DEVELOPING.md | 49 ++++++++++++++++++++----------------------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/DEVELOPING.md b/DEVELOPING.md index b6ef58f..4b05842 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -13,12 +13,14 @@ Following the standard install instructions should lead you to have nearly every A stable version of Bombadillo is kept in the default branch, so that people can easily clone the repo and get a good version of the software. -New changes are introduced to the **develop** branch. +New changes are implemented to the **develop** branch as **development releases**. -Changes to the default branch occur as part of the software release process. This usually occurs when: +Changes are implemented to the default branch when: - - there are a set of changes in **develop** that are good enough to be considered stable. - - an urgent issue is identified in the stable version that requires immediate changes + - There are a set of changes in **develop** that are good enough to be considered stable. + - This may be a **minor** set of changes for a **minor release**, or + - a large **major** change for **major release**. + - An urgent issue is identified in the stable version that requires an immediate **patch release**. ### Process for introducing a new change @@ -29,24 +31,18 @@ Please refer to our [notes on contributing](README.md#contributing) to get an un 1. Raise a pull request (PR) targeting the **develop** branch. 1. The PR is reviewed. 1. If the PR is approved, it is merged. -1. The version patch number is incremented. +1. The version number is incremented, along with any other release activity. -### Incrementing the version number +### Process for incrementing the version number -This process is handled by maintainers after a change has been merged. - -Version numbers are comprised of three digits: major version number, minor version number, and patch number. - -The version number is incremented in the following situations: - -#### New changes - -Each new change added to **develop** should increment the patch number. For example, version 2.0.1 would become 2.0.2. After the change is merged from the feature branch to **develop**: +The version number is incremented during a **development release**, **patch release**, and **minor** and **major releases**. This is primarily managed through git tags in the following way: ```shell -# ensure everything is up to date and in the right place -git checkout develop +# switch to the branch the release is being performed for +git checkout branch + +# ensure everything is up to date git pull # get the commit ID for the recent merge @@ -55,19 +51,14 @@ git log # get the current version number (the highest number) git tag -# add the incremented version number to the commit-id, for example: +# for a development release, add the incremented version number to the commit-id, for example: git tag 2.0.2 abcdef + +# for releases to the default branch, this tag can also be added with annotations +git tag 2.1.0 abdef -a "This version adds several new features..." ``` -#### Release process +Releases to the default branch also include the following tasks: -As part of the software release process, any part of the version number may change: - -- Urgent changes increment the **patch** number -- A set of small changes increments the **minor** version number -- A significant change to large parts of the application increments the **major** version number - -1. The version number in the VERSION file is incremented. This change is committed to the default branch. -1. The **develop** branch is merged to the default branch. -1. The commands from the New Changes section are followed, but the final command includes an annotation: `git tag 2.1.0 abdef -a "This version adds several new features..."` -1. Release information should also be added to the [tildegit releases page](https://tildegit.org/sloum/bombadillo/releases). +1. The version number in the VERSION file is incremented and committed. +1. Release information should also be verified on the [tildegit releases page](https://tildegit.org/sloum/bombadillo/releases). From 8444784221f3c8724f6116820792802d1ca80e7c Mon Sep 17 00:00:00 2001 From: sloum Date: Thu, 30 Jan 2020 19:41:55 -0800 Subject: [PATCH 04/14] Fixes bug that causes crash on broken gophermaps --- VERSION | 2 +- gopher/gopher.go | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index 7ec1d6d..eca07e4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.0 +2.1.2 diff --git a/gopher/gopher.go b/gopher/gopher.go index fd5744f..eec64b6 100644 --- a/gopher/gopher.go +++ b/gopher/gopher.go @@ -133,11 +133,12 @@ func parseMap(text string) (string, []string) { title = line[0][1:] } else { title = "" + line[0] = "i " } - if len(line) > 1 && len(line[0]) > 0 && string(line[0][0]) == "i" { + if len(line) < 4 || strings.HasPrefix(line[0], "i") { splitContent[i] = " " + string(title) - } else if len(line) >= 4 { + } else { link := buildLink(line[2], line[3], string(line[0][0]), line[1]) links = append(links, link) linktext := fmt.Sprintf("(%s) %2d %s", getType(string(line[0][0])), len(links), title) From 9e68f383a0b51611e4fcbbc67e5da475016b3105 Mon Sep 17 00:00:00 2001 From: sloum Date: Thu, 30 Jan 2020 19:42:45 -0800 Subject: [PATCH 05/14] Updates version number --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index eca07e4..ac2cdeb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.2 +2.1.3 From 53cbb9dd026c95703ff33ef2fd82176cfd8d8e3d Mon Sep 17 00:00:00 2001 From: sloum Date: Sat, 1 Feb 2020 09:55:55 -0800 Subject: [PATCH 06/14] Improves upon previoius fixes to gophermap parsing --- gopher/gopher.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gopher/gopher.go b/gopher/gopher.go index eec64b6..20e76e9 100644 --- a/gopher/gopher.go +++ b/gopher/gopher.go @@ -131,9 +131,11 @@ func parseMap(text string) (string, []string) { if len(line[0]) > 1 { title = line[0][1:] + } else if len(line[0]) == 1 { + title = "" } else { title = "" - line[0] = "i " + line[0] = "i" } if len(line) < 4 || strings.HasPrefix(line[0], "i") { From c9765bf0fa03ca1209c54478fb29259972781a10 Mon Sep 17 00:00:00 2001 From: sloum Date: Thu, 13 Feb 2020 21:26:23 -0800 Subject: [PATCH 07/14] Adds lo-fi image rendering to Bombadillo --- client.go | 10 +- defaults.go | 5 +- main.go | 3 +- page.go | 17 ++- tdiv/tdiv.go | 290 +++++++++++++++++++++++++++++++++++++++++++++++++++ url.go | 2 +- 6 files changed, 320 insertions(+), 7 deletions(-) create mode 100644 tdiv/tdiv.go diff --git a/client.go b/client.go index ed642a2..1809d15 100644 --- a/client.go +++ b/client.go @@ -929,7 +929,7 @@ func (c *client) Visit(url string) { // +++ Begin Protocol Handlers +++ func (c *client) handleGopher(u Url) { - if u.DownloadOnly { + if u.DownloadOnly || (c.Options["showimages"] == "false" && (u.Mime == "I" || u.Mime == "g")) { nameSplit := strings.Split(u.Resource, "/") filename := nameSplit[len(nameSplit)-1] filename = strings.Trim(filename, " \t\r\n\v\f\a") @@ -947,6 +947,11 @@ func (c *client) handleGopher(u Url) { return } pg := MakePage(u, content, links) + if u.Mime == "I" || u.Mime == "g" { + pg.FileType = "image" + } else { + pg.FileType = "text" + } pg.WrapContent(c.Width-1, (c.Options["theme"] == "color")) c.PageState.Add(pg) c.SetPercentRead() @@ -968,8 +973,9 @@ func (c *client) handleGemini(u Url) { case 1: c.search("", u.Full, capsule.Content) case 2: - if capsule.MimeMaj == "text" { + if capsule.MimeMaj == "text" || (c.Options["showimages"] == "true" && capsule.MimeMaj == "image") { pg := MakePage(u, capsule.Content, capsule.Links) + pg.FileType = capsule.MimeMaj pg.WrapContent(c.Width-1, (c.Options["theme"] == "color")) c.PageState.Add(pg) c.SetPercentRead() diff --git a/defaults.go b/defaults.go index 1c0a230..58ff0c4 100644 --- a/defaults.go +++ b/defaults.go @@ -45,12 +45,13 @@ var defaultOptions = map[string]string{ // the "configlocation" as follows: // "configlocation": xdgConfigPath() + "configlocation": xdgConfigPath(), + "defaultscheme": "gopher", // "gopher", "gemini", "http", "https" "homeurl": "gopher://bombadillo.colorfield.space:70/1/user-guide.map", + "showimages": "false", "savelocation": homePath(), "searchengine": "gopher://gopher.floodgap.com:70/7/v2/vs", "telnetcommand": "telnet", - "configlocation": xdgConfigPath(), - "defaultscheme": "gopher", // "gopher", "gemini", "http", "https" "theme": "normal", // "normal", "inverted", "color" "tlscertificate": "", "tlskey": "", diff --git a/main.go b/main.go index 1362e78..53918f7 100644 --- a/main.go +++ b/main.go @@ -65,6 +65,7 @@ func validateOpt(opt, val string) bool { "webmode": []string{"none", "gui", "lynx", "w3m", "elinks"}, "theme": []string{"normal", "inverse", "color"}, "defaultscheme": []string{"gopher", "gemini", "http", "https"}, + "showimages": []string{"true", "false"}, } opt = strings.ToLower(opt) @@ -83,7 +84,7 @@ func validateOpt(opt, val string) bool { func lowerCaseOpt(opt, val string) string { switch opt { - case "webmode", "theme", "defaultscheme": + case "webmode", "theme", "defaultscheme", "showimages": return strings.ToLower(val) default: return val diff --git a/page.go b/page.go index 08e75fb..ba9258b 100644 --- a/page.go +++ b/page.go @@ -3,6 +3,8 @@ package main import ( "fmt" "strings" + + "tildegit.org/sloum/bombadillo/tdiv" ) //------------------------------------------------\\ @@ -21,6 +23,7 @@ type Page struct { FoundLinkLines []int SearchTerm string SearchIndex int + FileType string } //------------------------------------------------\\ @@ -47,11 +50,23 @@ func (p *Page) ScrollPositionRange(termHeight int) (int, int) { return p.ScrollPosition, end } +func (p *Page) RenderImage(width int) { + w := (width - 5) * 2 + if w > 300 { + w = 300 + } + p.WrappedContent = tdiv.Render([]byte(p.RawContent), w) +} + // WrapContent performs a hard wrap to the requested // width and updates the WrappedContent // of the Page struct width a string slice // of the wrapped data func (p *Page) WrapContent(width int, color bool) { + if p.FileType == "image" { + p.RenderImage(width) + return + } counter := 0 var content strings.Builder var esc strings.Builder @@ -165,6 +180,6 @@ func (p *Page) FindText() { // MakePage returns a Page struct with default values func MakePage(url Url, content string, links []string) Page { - p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0} + p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, ""} return p } diff --git a/tdiv/tdiv.go b/tdiv/tdiv.go new file mode 100644 index 0000000..2ce3e2d --- /dev/null +++ b/tdiv/tdiv.go @@ -0,0 +1,290 @@ +package tdiv + +import ( + "bytes" + "fmt" + "image" + "image/gif" + "image/jpeg" + "image/png" + "io" + "strings" +) + +func getBraille(pattern string) (rune, error) { + switch pattern { + case "000000": + return ' ', nil + case "100000": + return '⠁', nil + case "001000": + return '⠂', nil + case "101000": + return '⠃', nil + case "000010": + return '⠄', nil + case "100010": + return '⠅', nil + case "001010": + return '⠆', nil + case "101010": + return '⠇', nil + case "010000": + return '⠈', nil + case "110000": + return '⠉', nil + case "011000": + return '⠊', nil + case "111000": + return '⠋', nil + case "010010": + return '⠌', nil + case "110010": + return '⠍', nil + case "011010": + return '⠎', nil + case "111010": + return '⠏', nil + case "000100": + return '⠐', nil + case "100100": + return '⠑', nil + case "001100": + return '⠒', nil + case "101100": + return '⠓', nil + case "000110": + return '⠔', nil + case "100110": + return '⠕', nil + case "001110": + return '⠖', nil + case "101110": + return '⠗', nil + case "010100": + return '⠘', nil + case "110100": + return '⠙', nil + case "011100": + return '⠚', nil + case "111100": + return '⠛', nil + case "010110": + return '⠜', nil + case "110110": + return '⠝', nil + case "011110": + return '⠞', nil + case "111110": + return '⠟', nil + case "000001": + return '⠠', nil + case "100001": + return '⠡', nil + case "001001": + return '⠢', nil + case "101001": + return '⠣', nil + case "000011": + return '⠤', nil + case "100011": + return '⠥', nil + case "001011": + return '⠦', nil + case "101011": + return '⠧', nil + case "010001": + return '⠨', nil + case "110001": + return '⠩', nil + case "011001": + return '⠪', nil + case "111001": + return '⠫', nil + case "010011": + return '⠬', nil + case "110011": + return '⠭', nil + case "011011": + return '⠮', nil + case "111011": + return '⠯', nil + case "000101": + return '⠰', nil + case "100101": + return '⠱', nil + case "001101": + return '⠲', nil + case "101101": + return '⠳', nil + case "000111": + return '⠴', nil + case "100111": + return '⠵', nil + case "001111": + return '⠶', nil + case "101111": + return '⠷', nil + case "010101": + return '⠸', nil + case "110101": + return '⠹', nil + case "011101": + return '⠺', nil + case "111101": + return '⠻', nil + case "010111": + return '⠼', nil + case "110111": + return '⠽', nil + case "011111": + return '⠾', nil + case "111111": + return '⠿', nil + default: + return '!', fmt.Errorf("Invalid character entry") + } +} + +// scaleImage loads and scales an image and returns a 2d pixel-int slice +// +// Adapted from: +// http://tech-algorithm.com/articles/nearest-neighbor-image-scaling/ +func scaleImage(file io.Reader, newWidth int) (int, int, [][]int, error) { + img, _, err := image.Decode(file) + if err != nil { + return 0, 0, nil, err + } + + bounds := img.Bounds() + width, height := bounds.Max.X, bounds.Max.Y + newHeight := int(float64(newWidth) * (float64(height) / float64(width))) + + out := make([][]int, newHeight) + for i := range out { + out[i] = make([]int, newWidth) + } + + xRatio := float64(width) / float64(newWidth) + yRatio := float64(height) / float64(newHeight) + var px, py int + for i := 0; i < newHeight; i++ { + for j := 0; j < newWidth; j++ { + px = int(float64(j) * xRatio) + py = int(float64(i) * yRatio) + out[i][j] = rgbaToGray(img.At(px, py).RGBA()) + } + } + return newWidth, newHeight, out, nil +} + +// Get the bi-dimensional pixel array +func getPixels(file io.Reader) (int, int, [][]int, error) { + img, _, err := image.Decode(file) + if err != nil { + return 0, 0, nil, err + } + + bounds := img.Bounds() + width, height := bounds.Max.X, bounds.Max.Y + + var pixels [][]int + for y := 0; y < height; y++ { + var row []int + for x := 0; x < width; x++ { + row = append(row, rgbaToGray(img.At(x, y).RGBA())) + } + pixels = append(pixels, row) + } + + return width, height, pixels, nil +} + +func errorDither(w, h int, p [][]int) [][]int { + mv := [4][2]int{ + [2]int{0, 1}, + [2]int{1, 1}, + [2]int{1, 0}, + [2]int{1, -1}, + } + per := [4]float64{0.4375, 0.0625, 0.3125, 0.1875} + var res, diff int + for y := 0; y < h; y++ { + for x := 0; x < w; x++ { + cur := p[y][x] + if cur > 128 { + res = 1 + diff = -(255 - cur) + } else { + res = 0 + diff = cur // TODO see why this was abs() in the py version + } + for i, v := range mv { + if y+v[0] >= h || x+v[1] >= w || x+v[1] <= 0 { + continue + } + px := p[y+v[0]][x+v[1]] + px = int(float64(diff)*per[i] + float64(px)) + if px < 0 { + px = 0 + } else if px > 255 { + px = 255 + } + p[y+v[0]][x+v[1]] = px + p[y][x] = res + } + } + } + return p +} + +func toBraille(p [][]int) []rune { + w := len(p[0]) // TODO this is unsafe + h := len(p) + rows := h / 3 + cols := w / 2 + out := make([]rune, rows*(cols+1)) + counter := 0 + for y := 0; y < h-3; y += 4 { + for x := 0; x < w-1; x += 2 { + str := fmt.Sprintf( + "%d%d%d%d%d%d", + p[y][x], p[y][x+1], + p[y+1][x], p[y+1][x+1], + p[y+2][x], p[y+2][x+1]) + b, err := getBraille(str) + if err != nil { + out[counter] = ' ' + } else { + out[counter] = b + } + counter++ + } + out[counter] = '\n' + counter++ + } + return out +} + +func rgbaToGray(r uint32, g uint32, b uint32, a uint32) int { + rf := float64(r/257) * 0.92126 + gf := float64(g/257) * 0.97152 + bf := float64(b/257) * 0.90722 + grey := int((rf + gf + bf) / 3) + return grey +} + +func Render(in []byte, width int) []string { + image.RegisterFormat("jpeg", "jpeg", jpeg.Decode, jpeg.DecodeConfig) + image.RegisterFormat("png", "png", png.Decode, png.DecodeConfig) + image.RegisterFormat("gif", "gif", gif.Decode, gif.DecodeConfig) + w, h, p, err := scaleImage(bytes.NewReader(in), width) + + if err != nil { + return []string{"Unable to render image.", "Please download using:", "", " :w ."} + } + px := errorDither(w, h, p) + b := toBraille(px) + out := strings.SplitN(string(b), "\n", -1) + return out +} diff --git a/url.go b/url.go index a6823fa..0831411 100644 --- a/url.go +++ b/url.go @@ -130,7 +130,7 @@ func MakeUrl(u string) (Url, error) { out.Mime = "1" } switch out.Mime { - case "1", "0", "h", "7": + case "1", "0", "h", "7", "I", "g": out.DownloadOnly = false default: out.DownloadOnly = true From 996e209c500cac9db711cda28735b7121c3e9375 Mon Sep 17 00:00:00 2001 From: sloum Date: Thu, 13 Feb 2020 22:46:39 -0800 Subject: [PATCH 08/14] Leaves a note re: improving render speeds --- client.go | 4 ++++ pages.go | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/client.go b/client.go index 1809d15..855f79d 100644 --- a/client.go +++ b/client.go @@ -1024,6 +1024,10 @@ func (c *client) handleLocal(u Url) { return } pg := MakePage(u, content, links) + ext := strings.ToLower(filepath.Ext(u.Full)) + if ext == ".jpg" || ext == ".jpeg" || ext == ".gif" || ext == ".png" { + pg.FileType = "image" + } pg.WrapContent(c.Width-1, (c.Options["theme"] == "color")) c.PageState.Add(pg) c.SetPercentRead() diff --git a/pages.go b/pages.go index 46d962b..241ea74 100644 --- a/pages.go +++ b/pages.go @@ -66,7 +66,17 @@ func (p *Pages) Render(termHeight, termWidth int, color bool) []string { } pos := p.History[p.Position].ScrollPosition prev := len(p.History[p.Position].WrappedContent) + + // TODO figure out a way to only do this when needed + // it is horribly slow to do this every render. + // + // Current thought is add a "WrapWidth" to each page + // and compare the WrapWidth against the width being + // passed in here. If it is different then go through + // all of that. Otherwise, just send the already wrapped + // data. p.History[p.Position].WrapContent(termWidth, color) + now := len(p.History[p.Position].WrappedContent) if prev > now { diff := prev - now From cda502fbb85efdba5d03b2f9fa9b184fba53b09c Mon Sep 17 00:00:00 2001 From: sloum Date: Sat, 15 Feb 2020 08:43:54 -0800 Subject: [PATCH 09/14] Adds a WrapWidth param to the page struct so that pages.go does not have to rewrap on every render. --- page.go | 5 ++++- pages.go | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/page.go b/page.go index ba9258b..418975d 100644 --- a/page.go +++ b/page.go @@ -24,6 +24,7 @@ type Page struct { SearchTerm string SearchIndex int FileType string + WrapWidth int } //------------------------------------------------\\ @@ -56,6 +57,7 @@ func (p *Page) RenderImage(width int) { w = 300 } p.WrappedContent = tdiv.Render([]byte(p.RawContent), w) + p.WrapWidth = width } // WrapContent performs a hard wrap to the requested @@ -131,6 +133,7 @@ func (p *Page) WrapContent(width int, color bool) { } p.WrappedContent = strings.Split(content.String(), "\n") + p.WrapWidth = width p.HighlightFoundText() } @@ -180,6 +183,6 @@ func (p *Page) FindText() { // MakePage returns a Page struct with default values func MakePage(url Url, content string, links []string) Page { - p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, ""} + p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, "", 40} return p } diff --git a/pages.go b/pages.go index 241ea74..01cd1e0 100644 --- a/pages.go +++ b/pages.go @@ -75,7 +75,9 @@ func (p *Pages) Render(termHeight, termWidth int, color bool) []string { // passed in here. If it is different then go through // all of that. Otherwise, just send the already wrapped // data. - p.History[p.Position].WrapContent(termWidth, color) + if termWidth != p.History[p.Position].WrapWidth { + p.History[p.Position].WrapContent(termWidth, color) + } now := len(p.History[p.Position].WrappedContent) if prev > now { From 4f9c8877b504eedf8f1607cb83372ba4bb084d45 Mon Sep 17 00:00:00 2001 From: sloum Date: Sat, 15 Feb 2020 10:44:41 -0800 Subject: [PATCH 10/14] Removes unneeded comment --- pages.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pages.go b/pages.go index 01cd1e0..f3d761d 100644 --- a/pages.go +++ b/pages.go @@ -67,14 +67,6 @@ func (p *Pages) Render(termHeight, termWidth int, color bool) []string { pos := p.History[p.Position].ScrollPosition prev := len(p.History[p.Position].WrappedContent) - // TODO figure out a way to only do this when needed - // it is horribly slow to do this every render. - // - // Current thought is add a "WrapWidth" to each page - // and compare the WrapWidth against the width being - // passed in here. If it is different then go through - // all of that. Otherwise, just send the already wrapped - // data. if termWidth != p.History[p.Position].WrapWidth { p.History[p.Position].WrapContent(termWidth, color) } From 7edf01eb99945cc1954d6edc22a2b360b2a1ce54 Mon Sep 17 00:00:00 2001 From: sloum Date: Sat, 15 Feb 2020 10:51:39 -0800 Subject: [PATCH 11/14] Adds a color property to the page struct to track the color mode --- page.go | 4 +++- pages.go | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/page.go b/page.go index 418975d..4ca0842 100644 --- a/page.go +++ b/page.go @@ -25,6 +25,7 @@ type Page struct { SearchIndex int FileType string WrapWidth int + Color bool } //------------------------------------------------\\ @@ -134,6 +135,7 @@ func (p *Page) WrapContent(width int, color bool) { p.WrappedContent = strings.Split(content.String(), "\n") p.WrapWidth = width + p.Color = color p.HighlightFoundText() } @@ -183,6 +185,6 @@ func (p *Page) FindText() { // MakePage returns a Page struct with default values func MakePage(url Url, content string, links []string) Page { - p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, "", 40} + p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, "", 40, false} return p } diff --git a/pages.go b/pages.go index f3d761d..9fa6606 100644 --- a/pages.go +++ b/pages.go @@ -67,7 +67,7 @@ func (p *Pages) Render(termHeight, termWidth int, color bool) []string { pos := p.History[p.Position].ScrollPosition prev := len(p.History[p.Position].WrappedContent) - if termWidth != p.History[p.Position].WrapWidth { + if termWidth != p.History[p.Position].WrapWidth || p.History[p.Position].Color != color { p.History[p.Position].WrapContent(termWidth, color) } From cd1be92d34c7a492f13f7dcde89c85cf663dc64a Mon Sep 17 00:00:00 2001 From: sloum Date: Wed, 4 Mar 2020 21:27:21 -0800 Subject: [PATCH 12/14] Changing default to true --- defaults.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/defaults.go b/defaults.go index 58ff0c4..c4ca227 100644 --- a/defaults.go +++ b/defaults.go @@ -48,9 +48,9 @@ var defaultOptions = map[string]string{ "configlocation": xdgConfigPath(), "defaultscheme": "gopher", // "gopher", "gemini", "http", "https" "homeurl": "gopher://bombadillo.colorfield.space:70/1/user-guide.map", - "showimages": "false", "savelocation": homePath(), "searchengine": "gopher://gopher.floodgap.com:70/7/v2/vs", + "showimages": "true", "telnetcommand": "telnet", "theme": "normal", // "normal", "inverted", "color" "tlscertificate": "", From 021f1290d4e044b1aa1a2038cd301917fe9be8ad Mon Sep 17 00:00:00 2001 From: sloum Date: Wed, 4 Mar 2020 21:51:54 -0800 Subject: [PATCH 13/14] Adds support for gemini tripple backticks --- gemini/gemini.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/gemini/gemini.go b/gemini/gemini.go index 884303a..e13cb59 100644 --- a/gemini/gemini.go +++ b/gemini/gemini.go @@ -339,9 +339,16 @@ func parseGemini(b, rootUrl, currentUrl string) (string, []string) { splitContent := strings.Split(b, "\n") links := make([]string, 0, 10) + outputIndex := 0 for i, ln := range splitContent { splitContent[i] = strings.Trim(ln, "\r\n") - if len([]rune(ln)) > 3 && ln[:2] == "=>" { + if ln == "```" { + // By continuing we create a variance between i and outputIndex + // the other branches here will write to the outputIndex rather + // than i, thus removing these lines while itterating without + // needing mroe allocations. + continue + } else if len([]rune(ln)) > 3 && ln[:2] == "=>" { var link, decorator string subLn := strings.Trim(ln[2:], "\r\n\t \a") splitPoint := strings.IndexAny(subLn, " \t") @@ -360,10 +367,14 @@ func parseGemini(b, rootUrl, currentUrl string) (string, []string) { links = append(links, link) linknum := fmt.Sprintf("[%d]", len(links)) - splitContent[i] = fmt.Sprintf("%-5s %s", linknum, decorator) + splitContent[outputIndex] = fmt.Sprintf("%-5s %s", linknum, decorator) + outputIndex++ + } else { + splitContent[outputIndex] = ln + outputIndex++ } } - return strings.Join(splitContent, "\n"), links + return strings.Join(splitContent[:outputIndex], "\n"), links } func handleRelativeUrl(u, root, current string) string { From 8b7441ea177f1883b8ee2e991bf0c6b13c4002d3 Mon Sep 17 00:00:00 2001 From: sloum Date: Sun, 22 Mar 2020 22:27:38 -0700 Subject: [PATCH 14/14] Updated version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index ac2cdeb..ccbccc3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.1.3 +2.2.0