Skip to content

Commit e1a090b

Browse files
committed
Add pre-next
1 parent 1a51946 commit e1a090b

35 files changed

+1993
-15
lines changed

README_old.md

Lines changed: 1173 additions & 0 deletions
Large diffs are not rendered by default.

ctl/label.go

Lines changed: 246 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,50 @@
11
package main
22

33
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"
410
"github.com/spf13/cobra"
11+
"io"
12+
"os"
13+
"regexp"
14+
// "sort"
15+
// "strconv"
16+
"errors"
17+
"io/ioutil"
18+
"strings"
519
)
620

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+
748
func newLabelCommand() *cobra.Command {
849
mc := &cobra.Command{
950
Use: "label <subcommand>",
@@ -22,7 +63,7 @@ func newAddPreNext() *cobra.Command {
2263
Use: "add-pre-next",
2364
Short: "Add pre-next label",
2465
Run: func(cmd *cobra.Command, args []string) {
25-
66+
addPreNext()
2667
},
2768
}
2869
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
@@ -32,12 +73,215 @@ func newAddPreNext() *cobra.Command {
3273

3374
func newDeletePreNext() *cobra.Command {
3475
cmd := &cobra.Command{
35-
Use: "delete-pre-next",
76+
Use: "del-pre-next",
3677
Short: "Delete pre-next label",
3778
Run: func(cmd *cobra.Command, args []string) {
79+
delPreNext()
3880
},
3981
}
4082
// cmd.Flags().StringVar(&alias, "alias", "", "alias")
4183
// cmd.Flags().StringVar(&appId, "appid", "", "appid")
4284
return cmd
4385
}
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+
}

ctl/render.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ func newBuildCommand() *cobra.Command {
3434
newBuildREADME(),
3535
newBuildChapterTwo(),
3636
)
37-
3837
return mc
3938
}
4039

@@ -101,6 +100,7 @@ func buildREADME() {
101100
return
102101
}
103102
util.WriteFile("../README.md", res)
103+
fmt.Println("write file successful")
104104
//makeReadmeFile(mds)
105105
}
106106

@@ -151,6 +151,7 @@ func buildChapterTwo() {
151151
var (
152152
gr m.GraphQLResp
153153
questions []m.Question
154+
count int
154155
)
155156
for index, tag := range chapterTwoSlug {
156157
body := getTagProblemList(tag)
@@ -177,7 +178,9 @@ func buildChapterTwo() {
177178
return
178179
}
179180
util.WriteFile(fmt.Sprintf("../website/content/ChapterTwo/%v.md", chapterTwoFileName[index]), res)
181+
count++
180182
}
183+
fmt.Println("write %v files successful", count)
181184
}
182185

183186
func loadMetaData(filePath string) (map[int]m.TagList, error) {

ctl/util/util.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,34 @@ func LoadSolutionsDir() ([]int, int) {
2929
return solutionIds, len(files) - len(solutionIds)
3030
}
3131

32+
// LoadChapterFourDir define
33+
func LoadChapterFourDir() []string {
34+
files, err := ioutil.ReadDir("../website/content/ChapterFour/")
35+
if err != nil {
36+
fmt.Println(err)
37+
}
38+
solutions, solutionIds, solutionsMap := []string{}, []int{}, map[int]string{}
39+
for _, f := range files {
40+
if f.Name()[4] == '.' {
41+
tmp, err := strconv.Atoi(f.Name()[:4])
42+
if err != nil {
43+
fmt.Println(err)
44+
}
45+
solutionIds = append(solutionIds, tmp)
46+
// len(f.Name())-3 = 文件名去掉 .md 后缀
47+
solutionsMap[tmp] = f.Name()[:len(f.Name())-3]
48+
}
49+
}
50+
sort.Ints(solutionIds)
51+
fmt.Printf("读取了第四章的 %v 道题的题解\n", len(solutionIds))
52+
for _, v := range solutionIds {
53+
if name, ok := solutionsMap[v]; ok {
54+
solutions = append(solutions, name)
55+
}
56+
}
57+
return solutions
58+
}
59+
3260
// WriteFile define
3361
func WriteFile(fileName string, content []byte) {
3462
file, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0777)
@@ -41,7 +69,7 @@ func WriteFile(fileName string, content []byte) {
4169
if err != nil {
4270
fmt.Println(err)
4371
}
44-
fmt.Println("write file successful")
72+
//fmt.Println("write file successful")
4573
}
4674

4775
// BinarySearch define

go.mod

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module github.com/halfrost/LeetCode-Go
2+
3+
go 1.14
4+
5+
require (
6+
github.com/BurntSushi/toml v0.3.1
7+
github.com/bitly/go-simplejson v0.5.0 // indirect
8+
github.com/graphql-go/graphql v0.7.9
9+
github.com/keegancsmith/rpc v1.3.0 // indirect
10+
github.com/mozillazg/request v0.8.0
11+
github.com/nsf/gocode v0.0.0-20190302080247-5bee97b48836 // indirect
12+
github.com/spf13/cobra v1.1.1
13+
github.com/stamblerre/gocode v1.0.0 // indirect
14+
golang.org/x/mod v0.4.0 // indirect
15+
golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58 // indirect
16+
)

0 commit comments

Comments
 (0)