1
1
package main
2
2
3
3
import (
4
+ "bufio"
5
+ // "encoding/json"
6
+ "fmt"
7
+ // m "github.com/halfrost/LeetCode-Go/ctl/models"
8
+ // "github.com/halfrost/LeetCode-Go/ctl/util"
9
+ "github.com/halfrost/LeetCode-Go/ctl/util"
4
10
"github.com/spf13/cobra"
11
+ "io"
12
+ "os"
13
+ "regexp"
14
+ // "sort"
15
+ // "strconv"
16
+ "errors"
17
+ "io/ioutil"
18
+ "strings"
5
19
)
6
20
21
+ var (
22
+ chapterOneFileOrder = []string {"_index" , "Data_Structure" , "Algorithm" }
23
+ chapterTwoFileOrder = []string {"_index" , "Array" , "String" , "Two_Pointers" , "Linked_List" , "Stack" , "Tree" , "Dynamic_Programming" , "Backtracking" , "Depth_First_Search" , "Breadth_First_Search" ,
24
+ "Binary_Search" , "Math" , "Hash_Table" , "Sort" , "Bit_Manipulation" , "Union_Find" , "Sliding_Window" , "Segment_Tree" , "Binary_Indexed_Tree" }
25
+ chapterThreeFileOrder = []string {"_index" , "Segment_Tree" , "UnionFind" , "LRUCache" , "LFUCache" }
26
+ preNextHeader = "----------------------------------------------\n <div style=\" display: flex;justify-content: space-between;align-items: center;\" >\n "
27
+ preNextFotter = "</div>"
28
+ delLine = "----------------------------------------------\n "
29
+ delHeader = "<div style=\" display: flex;justify-content: space-between;align-items: center;\" >"
30
+ delLabel = "<[a-zA-Z]+.*?>([\\ s\\ S]*?)</[a-zA-Z]*?>"
31
+ delFooter = "</div>"
32
+
33
+ //ErrNoFilename is thrown when the path the the file to tail was not given
34
+ ErrNoFilename = errors .New ("You must provide the path to a file in the \" -file\" flag." )
35
+
36
+ //ErrInvalidLineCount is thrown when the user provided 0 (zero) as the value for number of lines to tail
37
+ ErrInvalidLineCount = errors .New ("You cannot tail zero lines." )
38
+ )
39
+
40
+ func getChapterFourFileOrder () []string {
41
+ solutions := util .LoadChapterFourDir ()
42
+ chapterFourFileOrder := []string {"_index" }
43
+ chapterFourFileOrder = append (chapterFourFileOrder , solutions ... )
44
+ fmt .Printf ("ChapterFour 中包括 _index 有 %v 个文件\n " , len (chapterFourFileOrder ))
45
+ return chapterFourFileOrder
46
+ }
47
+
7
48
func newLabelCommand () * cobra.Command {
8
49
mc := & cobra.Command {
9
50
Use : "label <subcommand>" ,
@@ -22,7 +63,7 @@ func newAddPreNext() *cobra.Command {
22
63
Use : "add-pre-next" ,
23
64
Short : "Add pre-next label" ,
24
65
Run : func (cmd * cobra.Command , args []string ) {
25
-
66
+ addPreNext ()
26
67
},
27
68
}
28
69
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
@@ -32,12 +73,215 @@ func newAddPreNext() *cobra.Command {
32
73
33
74
func newDeletePreNext () * cobra.Command {
34
75
cmd := & cobra.Command {
35
- Use : "delete -pre-next" ,
76
+ Use : "del -pre-next" ,
36
77
Short : "Delete pre-next label" ,
37
78
Run : func (cmd * cobra.Command , args []string ) {
79
+ delPreNext ()
38
80
},
39
81
}
40
82
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
41
83
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
42
84
return cmd
43
85
}
86
+
87
+ func addPreNext () {
88
+ // Chpater one add pre-next
89
+ addPreNextLabel (chapterOneFileOrder , []string {}, "" , "ChapterOne" , "ChapterTwo" )
90
+ // Chpater two add pre-next
91
+ addPreNextLabel (chapterTwoFileOrder , chapterOneFileOrder , "ChapterOne" , "ChapterTwo" , "ChapterThree" )
92
+ // Chpater three add pre-next
93
+ addPreNextLabel (chapterThreeFileOrder , chapterTwoFileOrder , "ChapterTwo" , "ChapterThree" , "ChapterFour" )
94
+ // Chpater four add pre-next
95
+ //fmt.Printf("%v\n", getChapterFourFileOrder())
96
+ addPreNextLabel (getChapterFourFileOrder (), chapterThreeFileOrder , "ChapterThree" , "ChapterFour" , "" )
97
+ }
98
+
99
+ func addPreNextLabel (order , preOrder []string , preChapter , chapter , nextChapter string ) {
100
+ var (
101
+ exist bool
102
+ err error
103
+ res []byte
104
+ count int
105
+ )
106
+ for index , v := range order {
107
+ tmp := ""
108
+ if index == 0 {
109
+ if chapter == "ChapterOne" {
110
+ // 第一页不需要“上一章”
111
+ tmp = "\n \n " + delLine + fmt .Sprintf ("<p align = \" right\" ><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >下一页➡️</a></p>\n " , chapter , order [index + 1 ])
112
+ } else {
113
+ tmp = "\n \n " + preNextHeader + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >⬅️上一章</a></p>\n " , preChapter , preOrder [len (preOrder )- 1 ]) + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >下一页➡️</a></p>\n " , chapter , order [index + 1 ]) + preNextFotter
114
+ }
115
+ } else if index == len (order )- 1 {
116
+ if chapter == "ChapterFour" {
117
+ // 最后一页不需要“下一页”
118
+ tmp = "\n \n " + delLine + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >⬅️上一页</a></p>\n " , chapter , order [index - 1 ])
119
+ } else {
120
+ tmp = "\n \n " + preNextHeader + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >⬅️上一页</a></p>\n " , chapter , order [index - 1 ]) + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/\" >下一章➡️</a></p>\n " , nextChapter ) + preNextFotter
121
+ }
122
+ } else if index == 1 {
123
+ tmp = "\n \n " + preNextHeader + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/\" >⬅️上一页</a></p>\n " , chapter ) + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >下一页➡️</a></p>\n " , chapter , order [index + 1 ]) + preNextFotter
124
+ } else {
125
+ tmp = "\n \n " + preNextHeader + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >⬅️上一页</a></p>\n " , chapter , order [index - 1 ]) + fmt .Sprintf ("<p><a href=\" https://books.halfrost.com/leetcode/%v/%v/\" >下一页➡️</a></p>\n " , chapter , order [index + 1 ]) + preNextFotter
126
+ }
127
+ exist , err = needAdd (fmt .Sprintf ("../website/content/%v/%v.md" , chapter , v ))
128
+ if err != nil {
129
+ fmt .Println (err )
130
+ return
131
+ }
132
+ // 当前没有上一页和下一页,才添加
133
+ if ! exist && err == nil {
134
+ res , err = eofAdd (fmt .Sprintf ("../website/content/%v/%v.md" , chapter , v ), tmp )
135
+ if err != nil {
136
+ fmt .Println (err )
137
+ return
138
+ }
139
+ util .WriteFile (fmt .Sprintf ("../website/content/%v/%v.md" , chapter , v ), res )
140
+ count ++
141
+ }
142
+ }
143
+ fmt .Printf ("添加了 %v 个文件的 pre-next\n " , count )
144
+ }
145
+
146
+ func eofAdd (filePath string , labelString string ) ([]byte , error ) {
147
+ f , err := os .OpenFile (filePath , os .O_RDONLY , 0644 )
148
+ if err != nil {
149
+ return nil , err
150
+ }
151
+ defer f .Close ()
152
+ reader , output := bufio .NewReader (f ), []byte {}
153
+
154
+ for {
155
+ line , _ , err := reader .ReadLine ()
156
+ if err != nil {
157
+ if err == io .EOF {
158
+ output = append (output , []byte (labelString )... )
159
+ output = append (output , []byte ("\n " )... )
160
+ return output , nil
161
+ }
162
+ return nil , err
163
+ }
164
+ output = append (output , line ... )
165
+ output = append (output , []byte ("\n " )... )
166
+ }
167
+ }
168
+
169
+ func delPreNext () {
170
+ // Chpater one del pre-next
171
+ delPreNextLabel (chapterOneFileOrder , "ChapterOne" )
172
+ // Chpater two del pre-next
173
+ delPreNextLabel (chapterTwoFileOrder , "ChapterTwo" )
174
+ // Chpater three del pre-next
175
+ delPreNextLabel (chapterThreeFileOrder , "ChapterThree" )
176
+ // Chpater four del pre-next
177
+ delPreNextLabel (getChapterFourFileOrder (), "ChapterFour" )
178
+ }
179
+
180
+ func delPreNextLabel (order []string , chapter string ) {
181
+ count := 0
182
+ for index , v := range order {
183
+ lineNum := 5
184
+ if index == 0 && chapter == "ChapterOne" || index == len (order )- 1 && chapter == "ChapterFour" {
185
+ lineNum = 3
186
+ }
187
+ exist , err := needAdd (fmt .Sprintf ("../website/content/%v/%v.md" , chapter , v ))
188
+ if err != nil {
189
+ fmt .Println (err )
190
+ return
191
+ }
192
+ // 存在才删除
193
+ if exist && err == nil {
194
+ removeLine (fmt .Sprintf ("../website/content/%v/%v.md" , chapter , v ), lineNum + 1 )
195
+ count ++
196
+ }
197
+ }
198
+ fmt .Printf ("删除了 %v 个文件的 pre-next\n " , count )
199
+ // 另外一种删除方法
200
+ // res, err := eofDel(fmt.Sprintf("../website/content/ChapterOne/%v.md", v))
201
+ // if err != nil {
202
+ // fmt.Println(err)
203
+ // return
204
+ // }
205
+ // util.WriteFile(fmt.Sprintf("../website/content/ChapterOne/%v.md", v), res)
206
+ }
207
+
208
+ func needAdd (filePath string ) (bool , error ) {
209
+ f , err := os .OpenFile (filePath , os .O_RDONLY , 0644 )
210
+ if err != nil {
211
+ return false , err
212
+ }
213
+ defer f .Close ()
214
+ reader , output := bufio .NewReader (f ), []byte {}
215
+ for {
216
+ line , _ , err := reader .ReadLine ()
217
+ if err != nil {
218
+ if err == io .EOF {
219
+ return false , nil
220
+ }
221
+ return false , err
222
+ }
223
+ if ok , _ := regexp .Match (delHeader , line ); ok {
224
+ return true , nil
225
+ } else if ok , _ := regexp .Match (delLabel , line ); ok {
226
+ return true , nil
227
+ } else {
228
+ output = append (output , line ... )
229
+ output = append (output , []byte ("\n " )... )
230
+ }
231
+ }
232
+ }
233
+
234
+ func eofDel (filePath string ) ([]byte , error ) {
235
+ f , err := os .OpenFile (filePath , os .O_RDONLY , 0644 )
236
+ if err != nil {
237
+ return nil , err
238
+ }
239
+ defer f .Close ()
240
+ reader , output := bufio .NewReader (f ), []byte {}
241
+ for {
242
+ line , _ , err := reader .ReadLine ()
243
+ if err != nil {
244
+ if err == io .EOF {
245
+ return output , nil
246
+ }
247
+ return nil , err
248
+ }
249
+ if ok , _ := regexp .Match (delLine , line ); ok {
250
+ reg := regexp .MustCompile (delLine )
251
+ newByte := reg .ReplaceAll (line , []byte (" " ))
252
+ output = append (output , newByte ... )
253
+ output = append (output , []byte ("\n " )... )
254
+ } else if ok , _ := regexp .Match (delHeader , line ); ok {
255
+ reg := regexp .MustCompile (delHeader )
256
+ newByte := reg .ReplaceAll (line , []byte (" " ))
257
+ output = append (output , newByte ... )
258
+ output = append (output , []byte ("\n " )... )
259
+ } else if ok , _ := regexp .Match (delLabel , line ); ok {
260
+ reg := regexp .MustCompile (delLabel )
261
+ newByte := reg .ReplaceAll (line , []byte (" " ))
262
+ output = append (output , newByte ... )
263
+ output = append (output , []byte ("\n " )... )
264
+ } else if ok , _ := regexp .Match (delFooter , line ); ok {
265
+ reg := regexp .MustCompile (delFooter )
266
+ newByte := reg .ReplaceAll (line , []byte (" " ))
267
+ output = append (output , newByte ... )
268
+ output = append (output , []byte ("\n " )... )
269
+ } else {
270
+ output = append (output , line ... )
271
+ output = append (output , []byte ("\n " )... )
272
+ }
273
+ }
274
+ }
275
+
276
+ func removeLine (path string , lineNumber int ) {
277
+ file , err := ioutil .ReadFile (path )
278
+ if err != nil {
279
+ panic (err )
280
+ }
281
+ info , _ := os .Stat (path )
282
+ mode := info .Mode ()
283
+ array := strings .Split (string (file ), "\n " )
284
+ array = array [:len (array )- lineNumber - 1 ]
285
+ ioutil .WriteFile (path , []byte (strings .Join (array , "\n " )), mode )
286
+ //fmt.Println("remove line successful")
287
+ }
0 commit comments