Skip to content

Commit bcc1c16

Browse files
committed
filter mode for include command
1 parent 263dc4b commit bcc1c16

File tree

4 files changed

+96
-10
lines changed

4 files changed

+96
-10
lines changed

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.0
1+
0.3.0

cmds.go

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ type Commands map[string]Command
1818

1919
type Include struct {
2020
_Position
21-
file string
21+
file string
22+
filter *regexp.Regexp
2223
}
2324

2425
func (i *Include) getData(p string) ([]byte, error) {
@@ -45,8 +46,8 @@ type IncludePat struct {
4546

4647
// --- begin example ---
4748
// --- begin include args ---
48-
var includeExpNum = regexp.MustCompile("^{([^}]+)}(?:{([0-9]+)?(?::([0-9]+)?)?})?$")
49-
var includeExpPat = regexp.MustCompile("^{([^}]+)}{([a-zA-Z -]+)}$")
49+
var includeExpNum = regexp.MustCompile("^{([^}]+)}(?:{([0-9]+)?(?::([0-9]+)?)?}(?:{(.*)})?)?$")
50+
var includeExpPat = regexp.MustCompile("^{([^}]+)}{([a-zA-Z -]+)}(?:{(.*)})?$")
5051

5152
// --- end include args ---
5253
// --- end example ---
@@ -70,17 +71,60 @@ func NewInclude(line, col int, args []byte) (Command, error) {
7071
return nil, fmt.Errorf("invalid start line: %w", err)
7172
}
7273
}
73-
return &IncludeNum{Include{Position{line, col}, string(matches[1])}, int(start), int(end)}, nil
74+
var filter *regexp.Regexp
75+
if matches[4] != nil {
76+
filter, err = regexp.Compile(string(matches[4]))
77+
if err != nil {
78+
return nil, fmt.Errorf("invalid filter expression: %w", err)
79+
}
80+
}
81+
return &IncludeNum{Include{Position{line, col}, string(matches[1]), filter}, int(start), int(end)}, nil
7482
}
7583

7684
matches = includeExpPat.FindSubmatch(args)
7785
if len(matches) != 0 {
78-
return &IncludePat{Include{Position{line, col}, string(matches[1])}, string(matches[2])}, nil
86+
var filter *regexp.Regexp
87+
if matches[3] != nil {
88+
filter, err = regexp.Compile(string(matches[3]))
89+
if err != nil {
90+
return nil, fmt.Errorf("invalid filter expression: %w", err)
91+
}
92+
}
93+
return &IncludePat{Include{Position{line, col}, string(matches[1]), filter}, string(matches[2])}, nil
7994
}
8095

8196
return nil, fmt.Errorf("invalid include arguments %q", string(args))
8297
}
8398

99+
// --- begin filter ---
100+
// An optional third argument can be used to specify a filter regular
101+
// expression. It must contain one matching group. The
102+
// selected file range is matched by this regular expression and
103+
// the content of the first matching group of the all matches is
104+
// concatenated. If the expression uses the multi-line mode, the matches
105+
// are suffixed with a newline.
106+
// --- end filter ---
107+
108+
func (i *Include) Filter(data []byte) ([]byte, error) {
109+
if i.filter == nil {
110+
return data, nil
111+
}
112+
sep := ""
113+
if strings.HasPrefix(i.filter.String(), "(?m)") {
114+
sep = "\n"
115+
}
116+
matches := i.filter.FindAllSubmatch(data, -1)
117+
var result []byte
118+
for _, m := range matches {
119+
if len(m) != 2 {
120+
return nil, fmt.Errorf("regular expressin must contain one matching group")
121+
}
122+
result = append(result, m[1]...)
123+
result = append(result, []byte(sep)...)
124+
}
125+
return result, nil
126+
}
127+
84128
func (i *IncludeNum) GetSubstitution(p string) ([]byte, error) {
85129
data, err := i.getData(p)
86130
if err != nil {
@@ -102,7 +146,7 @@ func (i *IncludeNum) GetSubstitution(p string) ([]byte, error) {
102146
if end > len(lines) {
103147
return nil, fmt.Errorf("end line %d after end of file (%q %d lines", end, i.file, len(lines))
104148
}
105-
return []byte(strings.Join(lines[start:end], "\n")), nil
149+
return i.Filter([]byte(strings.Join(lines[start:end], "\n")))
106150
}
107151

108152
func (i *IncludePat) GetSubstitution(p string) ([]byte, error) {
@@ -119,7 +163,8 @@ func (i *IncludePat) GetSubstitution(p string) ([]byte, error) {
119163
if err != nil {
120164
return nil, err
121165
}
122-
return data[start:end], nil
166+
167+
return i.Filter(data[start:end])
123168
}
124169

125170
func (i *IncludePat) match(data []byte, key string) (int, int, error) {

doc/chapters/commands.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,36 @@ extracts the lines between the start and end pattern
5555

5656
```
5757
// --- begin include args ---
58-
var includeExpNum = regexp.MustCompile("^{([^}]+)}(?:{([0-9]+)?(?::([0-9]+)?)?})?$")
59-
var includeExpPat = regexp.MustCompile("^{([^}]+)}{([a-zA-Z -]+)}$")
58+
var includeExpNum = regexp.MustCompile("^{([^}]+)}(?:{([0-9]+)?(?::([0-9]+)?)?}(?:{(.*)})?)?$")
59+
var includeExpPat = regexp.MustCompile("^{([^}]+)}{([a-zA-Z -]+)}(?:{(.*)})?$")
6060
6161
// --- end include args ---
6262
```
6363

6464
which are the regexps used to parse the two argument flavors.
65+
66+
An optional third argument can be used to specify a filter regular
67+
expression. It must contain one matching group. The
68+
selected file range is matched by this regular expression and
69+
the content of the first matching group of the all matches is
70+
concatenated. If the expression uses the multi-line mode, the matches
71+
are suffixed with a newline.
72+
73+
74+
The previous paragraph is taken from the source file
75+
```go
76+
// --- begin filter ---
77+
// An optional third argument can be used to specify a filter regular
78+
// expression. It must contain one matching group. The
79+
// selected file range is matched by this regular expression and
80+
// the content of the first matching group of the all matches is
81+
// concatenated. If the expression uses the multi-line mode, the matches
82+
// are suffixed with a newline.
83+
// --- end filter ---
84+
```
85+
using
86+
87+
<pre>
88+
{{include}{../../../cmds.go}{filter}{(?m)^.*// ?(.*)$}&rcub;
89+
</pre>
90+

src/doc/chapters/commands.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,18 @@ extracts the lines between the start and end pattern
5656
```
5757

5858
which are the regexps used to parse the two argument flavors.
59+
60+
{{include}{../../../cmds.go}{filter}{(?m)^.*// ?(.*)$}}
61+
62+
The previous paragraph is taken from the source file
63+
```go
64+
// --- begin filter ---
65+
{{include}{../../../cmds.go}{filter}}
66+
// --- end filter ---
67+
```
68+
using
69+
70+
<pre>
71+
{{include}{../../../cmds.go}{filter}{(?m)^.*// ?(.*)$}&rcub;
72+
</pre>
73+

0 commit comments

Comments
 (0)