1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
|
// quicknote
// Copyright (C) 2023 M R Lemon
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package main
import (
"bufio"
"flag"
"fmt"
"io"
"net/http"
"os"
"os/user"
"path/filepath"
"regexp"
"strings"
"github.com/atotto/clipboard"
)
var commentVar string
var mainContent string
/*
The init() function is a special function in Go that is automatically executed
before the main() function. It is typically used for initialization tasks, such
as parsing command-line flags or setting up global variables.
In this specific code, the init() function performs the following tasks:
1. Defines two constants:
- defaultComment: An empty string, which will be used as the default value
for the comment flag.
- usage: A string that describes the purpose of the comment flag.
2. Registers two command-line flags using the flag package:
- -c or --comment: A string flag that allows the user to provide a comment.
The flag is bound to the commentVar variable, and the default value is
defaultComment. The usage string is used to describe the flag.
3. Calls flag.Parse() to parse the command-line arguments.
4. Assigns the first non-flag command-line argument to the mainContent variable.
This function is likely part of a larger program that deals with managing
quicknotes or similar text-based notes. The commentVar and mainContent variables
are likely used elsewhere in the program to handle the user-provided comment and
the main content of the note, respectively.
*/
func init() {
const (
defaultComment = ""
usage = "add a comment to the quicknote"
)
flag.StringVar(&commentVar, "c", defaultComment, usage+" (shorthand)")
flag.StringVar(&commentVar, "comment", defaultComment, usage)
flag.Parse()
mainContent = flag.Arg(0)
}
func main() {
var url, markdownFile string
urlFromClipboard, err := clipboard.ReadAll()
if err != nil {
fmt.Printf("Error getting URL from clipboard: %v\n", err)
os.Exit(1)
}
url = strings.TrimSpace(urlFromClipboard)
usr, err := user.Current()
if err != nil {
fmt.Printf("Error getting user home directory: %v\n", err)
os.Exit(1)
}
markdownFile = filepath.Join(usr.HomeDir, "Documents", "Notes", "quicknote.md")
resp, err := http.Get(url)
if err != nil {
fmt.Printf("Error fetching URL: %v\n", err)
os.Exit(1)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Printf("Error reading response body: %v\n", err)
os.Exit(1)
}
htmlContent := string(body)
title, err := extractTitle(htmlContent)
if err != nil {
fmt.Printf("Error: %v\n", err)
title = promptForTitle()
}
markdownLink := fmt.Sprintf("- [%s](%s)\n", title, url)
if commentVar != "" {
markdownLink = fmt.Sprintf("- %s: [%s](%s)\n", strings.TrimSpace(commentVar), title, url)
}
err = appendToFile(markdownFile, markdownLink)
if err != nil {
fmt.Printf("Error appending to file: %v\n", err)
os.Exit(1)
}
}
/*
extractTitle extracts the title from an HTML string.
Parameters:
- html (string): The HTML string to extract the title from.
Returns:
- string: The extracted title.
- error: An error if the title tag is not present or empty.
The function uses a regular expression to find the <title> tag in the HTML string.
If the tag is found, it trims any leading or trailing whitespace from the title text
and returns it. If the title is an empty string, it returns an error indicating that
the title tag is empty. If the title tag is not found, it returns an error indicating
that the title tag is not present.
*/
func extractTitle(html string) (string, error) {
re := regexp.MustCompile(`(?i)<\s*title\s*>(.*?)<\s*/\s*title\s*>`)
match := re.FindStringSubmatch(html)
if len(match) > 0 {
title := strings.TrimSpace(match[1])
if title != "" {
return title, nil
}
return "", fmt.Errorf("title tag is empty")
}
return "", fmt.Errorf("title tag is not present")
}
// promptForTitle prompts the user to enter a title for a URL and returns the trimmed input string.
// It reads from standard input (os.Stdin) using a buffered reader (bufio.NewReader).
// The user's input is read until a newline character ('\n') is encountered.
// The leading and trailing whitespace characters are removed from the input string using strings.TrimSpace.
func promptForTitle() string {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Please enter a title for the URL: ")
title, _ := reader.ReadString('\n')
return strings.TrimSpace(title)
}
// appendToFile writes content to the file filename.
func appendToFile(filename, content string) error {
f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return err
}
defer f.Close()
if _, err := f.WriteString(content); err != nil {
return err
}
return nil
}
|