-
Notifications
You must be signed in to change notification settings - Fork 0
/
context.go
196 lines (174 loc) · 5.69 KB
/
context.go
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package main
import (
"fmt"
"strconv"
"strings"
//"os"
"golang.org/x/net/html"
"github.com/PuerkitoBio/goquery"
"github.com/k0kubun/pp"
"github.com/gookit/color"
"github.com/rs/zerolog"
)
var (
mapfunc = map[string]Capillary {
"UsingRef": NoteType.UsingRef,
"FromSuperior": NoteType.FromSuperior,
"FromSuperiorAndDescendants": NoteType.FromSuperiorAndDescendants,
//"CaptionInspector": NoteType.CaptionInspector,
}
isReusable = map[string]bool {
"UsingRef": false,
"FromSuperior": true,
"FromSuperiorAndDescendants": true,
}
)
type Capillary func(NoteType, []*html.Node, []string, string, int) (ObjectSlice []ObjectT)
// TODO func MoveTxtAddendumToSrc(n *html.Node, TXT string) (string, SRC string){
func (Note NoteType) MkCxt(loc Location, tStack []*html.Node/*, tRefStack []string*/) (src string) {
// in some books headings may contain direct reference to a pic / table,
// tRefStack should contain these from Preprocess but the corresponding Capillary hasn't been rewritten atm
var tRefStack []string
// ignore card(s) not preceed by a heading
if loc.IsEmpty() {
return
}
for num, fstr := range(pref.Fn) {
for _, obj := range Note.ObjProvider(num, fstr, loc, tStack, tRefStack) {
main, _ := goquery.OuterHtml(obj.Selec)
if !strings.Contains(Note.Txt, main) && !strings.Contains(src, main) {
src += obj.Fmt()
}
}
}
return
}
// num = func number (position) in Fn
func (Note NoteType) ObjProvider(num int, fstr string, loc Location, tStack []*html.Node, tRefStack []string) (ObjectSlice []ObjectT) {
if DataRegister[loc].ShrdObjectSlices[num] == nil {
// load the func of type "Capillary" and its scope of
// execution (target heading level)
f, ok := mapfunc[fstr]; if ok == false {
panic(fmt.Sprintf("Unknown Capillary: \"%s\"\n", fstr))
}
scope := pref.FnScope[num]
// get object from that func
ObjectSlice = f(Note, tStack, tRefStack, fstr, scope)
// cache ObjectSlice in case redesired later
if isReusable[fstr] {
DataRegister[loc].ShrdObjectSlices[num] = ObjectSlice
}
} else {
// or get object from cache
ObjectSlice = DataRegister[loc].ShrdObjectSlices[num]
}
return ObjectSlice
}
// TODO Rewrite + if scope=0 search whole doc
//var reRef = regexp.MustCompile(`(?m)[^\s]+?.*?((?:Abb|Tab)\.\s*?\d*?\.\d*)`)
func (Note NoteType) UsingRef(tStack []*html.Node, tRefStack []string, fstr string, scope int) (ObjectSlice []ObjectT) {
return
}
// share the img in the higher section level between the to-be-created notes of that section level
func (Note NoteType) FromSuperior(tStack []*html.Node, _ []string, fstr string, scope int) (ObjectSlice []ObjectT) {
return Note.superior(0, tStack, fstr, scope)
}
func (Note NoteType) FromSuperiorAndDescendants(tStack []*html.Node, _ []string, fstr string, scope int) (ObjectSlice []ObjectT) {
return Note.superior(1, tStack, fstr, scope)
}
func (Note NoteType) superior(includeDescendants int, tStack []*html.Node, fstr string, scope int) (ObjectSlice []ObjectT) {
logger := zerolog.Nop() //zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr}).With().Timestamp().Logger()
logger.Debug().
Str("fstr", fstr).
Int("scope", scope).
Msg("superior")
//printStack(logger, tStack)
// Only run if a suitable heading is available at this loc
// 1st offset = len() induced, 2nd offset for the dummy at idx 0
idxMax := len(tStack)-1-1
logger.Debug().
Int("len", len(tStack)).
Int("scope", scope).
Int("idxMax", idxMax).
Msg("superior")
var h *html.Node
var x int
var s *goquery.Selection
if idxMax < scope {
//logger.Debug().Int("maxed out to", idxMax)
//scope = idxMax
logger.Debug().
Int("idxMax", idxMax).
Int("scope", scope).
Msg("Out-of-bounds scope constrained to document root")
s = Note.QNode.Parent().Children()
if includeDescendants == 1 {
// because 0 is superior in importance to the int of h1
x = 0
} else {
x = 1 // FIXME
}
} else {
if idxMax-1 < 0 {
logger.Warn().Msg("Returned")
return
}
// this is the type of tag at which the parser must stop
// using plus sign because tStack is RELATIVE, the lower the idx, the closer the heading is to the cutpattern
h = tStack[scope+includeDescendants]
x, _ = strconv.Atoi(h.Data[1:])
s = &goquery.Selection{Nodes: []*html.Node{h}}
s = s.NextAll()
}
/*logger.Debug("query:",
"searching from", h.Data,
"stopping if finding a h", x,
)*/
// CAVEAT: NEXTALL COMBINED FIND(*) DOES NOT ITERATE OVER THE SIBLING NODE, ONLY OVER ITS DESCENDANTS
s.EachWithBreak(func(i int, selec *goquery.Selection) bool {
node := selec.Nodes[0]
if IsEqualOrMoreImportantHeading(node, x) {
return false
}
selec.Find("*").Each(func(i int, selec *goquery.Selection) {
node := selec.Nodes[0]
if node.Data == "img" || node.Data == "table" {
if p := selec.ParentsFiltered("figure, div.tmulti"); len(p.Nodes) != 0 {
selec = p
}
ObjectSlice = append(ObjectSlice, ObjectT{
Type: node.Data,
Origin: fstr,
Scope: scope,
Selec: selec,
})
}
})
return true
})
return
}
/*func printStack(logger *slog.Logger, tStack []*html.Node) {
logger.Debug("TSTACK=")
for i := 0; i<8; i++ {
if len(tStack) > i && tStack[i] != nil {
logger.Debug(fmt.Sprint("\t",i," ")+Text(tStack[i]))
} else {
logger.Debug("\tnil")
}
}
}
*/
func placeholder2() {
color.Redln(" 𝒻*** 𝓎ℴ𝓊 𝒸ℴ𝓂𝓅𝒾𝓁ℯ𝓇")
pp.Println("𝓯*** 𝔂𝓸𝓾 𝓬𝓸𝓶𝓹𝓲𝓵𝓮𝓻")
}
func IsEqualOrMoreImportantHeading(n *html.Node, x int) (b bool) {
y, err := strconv.Atoi(n.Data[1:])
// if the number of the heading user-provided is 0, treat it as
// the root of the document (-> document-wide search)
if (err == nil && n.Data[:1] == "h" && x != 0 && x >= y) {
return true
}
return
}