Skip to content

Commit 40f5a0e

Browse files
committed
#55: Remove href links from markdown template
1 parent ce8f680 commit 40f5a0e

File tree

3 files changed

+132
-30
lines changed

3 files changed

+132
-30
lines changed

formatter/formatter_md.go

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package formatter
33
import (
44
// Used in this place to have all required functionality within one binary file. No need for separate folders/files, just embed template
55
_ "embed"
6+
"fmt"
67
"html/template"
78
"strings"
89
)
@@ -30,27 +31,42 @@ func (f *MarkdownFormatter) Format(td *TemplateData) (err error) {
3031
func (f *MarkdownFormatter) defineTemplateFunctions(tmpl *template.Template) {
3132
tmpl.Funcs(
3233
template.FuncMap{
33-
"md_toc": markdownTOCEntry,
34-
"md": markdownEntry,
35-
"noesc": markdownNoEscape,
34+
"md_toc": markdownTOCEntry,
35+
"md": markdownEntry,
36+
"noesc": markdownNoEscape,
37+
"md_title": markdownHostAnchorTitle,
38+
"md_link": markdownAnchorLink,
3639
},
3740
)
3841
}
3942

43+
// markdownHostAnchorTitle helps to generate a title for specific hostname
44+
func markdownHostAnchorTitle(h *Host) string {
45+
title := h.HostAddress.Address
46+
for i := range h.HostNames.HostName {
47+
title += fmt.Sprintf(" / %s", h.HostNames.HostName[i].Name)
48+
}
49+
title += fmt.Sprintf(" (%s)", h.Status.State)
50+
return title
51+
}
52+
53+
// markdownAnchorLink is converting generated anchor title to table-of-contents entry
54+
func markdownAnchorLink(h *Host) string {
55+
return markdownTOCEntry(markdownHostAnchorTitle(h))
56+
}
57+
58+
// markdownTOCEntry returns lower-cased Table-of-Contents
59+
// anchor entry that should work as an internal link
4060
func markdownTOCEntry(v string) string {
41-
// Removing dots, replacing spaces with hyphens,
42-
// then convert it to lower-case
43-
return strings.ToLower(
44-
strings.ReplaceAll(
45-
strings.ReplaceAll(
46-
v,
47-
".",
48-
"",
49-
),
50-
" ",
51-
"-",
52-
),
61+
r := strings.NewReplacer(
62+
".", "",
63+
" ", "-",
64+
"/", "",
65+
"(", "",
66+
")", "",
5367
)
68+
// replace special characters and lower-case
69+
return strings.ToLower(r.Replace(v))
5470
}
5571

5672
func markdownEntry(v string) string {

formatter/formatter_md_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ func Test_markdownTOCEntry(t *testing.T) {
100100
},
101101
want: "19216822-test-host",
102102
},
103+
{
104+
name: "IP addr with brackets and slashes",
105+
args: args{
106+
v: "192.168.2.2 / example.com (up)",
107+
},
108+
want: "19216822--examplecom-up",
109+
},
103110
}
104111
for _, tt := range tests {
105112
t.Run(tt.name, func(t *testing.T) {
@@ -442,3 +449,95 @@ func TestMarkdownFormatter_Format(t *testing.T) {
442449
})
443450
}
444451
}
452+
453+
func Test_markdownHostAnchorTitle(t *testing.T) {
454+
type args struct {
455+
h *Host
456+
}
457+
tests := []struct {
458+
name string
459+
args args
460+
want string
461+
}{
462+
{
463+
name: "IP addr (up)",
464+
args: args{
465+
h: &Host{
466+
HostAddress: HostAddress{
467+
Address: "192.168.1.21",
468+
},
469+
Status: HostStatus{
470+
State: "up",
471+
},
472+
},
473+
},
474+
want: "192.168.1.21 (up)",
475+
},
476+
{
477+
name: "IP addr (down)",
478+
args: args{
479+
h: &Host{
480+
HostAddress: HostAddress{
481+
Address: "192.168.22.23",
482+
},
483+
Status: HostStatus{
484+
State: "down",
485+
},
486+
},
487+
},
488+
want: "192.168.22.23 (down)",
489+
},
490+
{
491+
name: "IP addr, 1 hostname (up)",
492+
args: args{
493+
h: &Host{
494+
HostAddress: HostAddress{
495+
Address: "192.168.22.23",
496+
},
497+
HostNames: HostNames{
498+
[]HostName{
499+
{
500+
Name: "example.com",
501+
},
502+
},
503+
},
504+
Status: HostStatus{
505+
State: "up",
506+
},
507+
},
508+
},
509+
want: "192.168.22.23 / example.com (up)",
510+
},
511+
{
512+
name: "IP addr, 2 hostnames (up)",
513+
args: args{
514+
h: &Host{
515+
HostAddress: HostAddress{
516+
Address: "192.168.32.33",
517+
},
518+
HostNames: HostNames{
519+
[]HostName{
520+
{
521+
Name: "example.com",
522+
},
523+
{
524+
Name: "example2.com",
525+
},
526+
},
527+
},
528+
Status: HostStatus{
529+
State: "up",
530+
},
531+
},
532+
},
533+
want: "192.168.32.33 / example.com / example2.com (up)",
534+
},
535+
}
536+
for _, tt := range tests {
537+
t.Run(tt.name, func(t *testing.T) {
538+
if got := markdownHostAnchorTitle(tt.args.h); got != tt.want {
539+
t.Errorf("markdownHostAnchorTitle() = %v, want %v", got, tt.want)
540+
}
541+
})
542+
}
543+
}

formatter/resources/templates/markdown.tmpl

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,7 @@ NMAP Scan Result: {{ .NMAPRun.StartStr }}
1111
{{- end }}{{/* if $skipSummary */}}
1212
{{- range .NMAPRun.Host -}}
1313
{{- if or ($displayDownHosts) (eq .Status.State "up") }}
14-
* [{{ .HostAddress.Address }}{{ range .HostNames.HostName }} / {{ .Name }}{{ end }} ({{ .Status.State }})](#{{ md_toc .HostAddress.Address }})
15-
{{- if eq .Status.State "up" }}
16-
* [Info](#{{ md_toc .HostAddress.Address }}-info)
17-
* [Ports](#{{ md_toc .HostAddress.Address }}-ports)
18-
{{- if not $skipPortScripts }}
19-
* [Scripts](#{{ md_toc .HostAddress.Address }}-scripts)
20-
{{- end -}}{{/* if not $skipPortScripts */}}
21-
{{- end }}
14+
* [{{ md_title . }}](#{{ md_link . }})
2215
{{- end -}}{{/* if or ($displayDownHosts) (eq .Status.State "up") */}}
2316
{{- end -}}{{/* range .Host */}}
2417

@@ -48,13 +41,10 @@ NMAP Scan Result: {{ .NMAPRun.StartStr }}
4841

4942
{{ range .NMAPRun.Host -}}
5043
{{- if or ($displayDownHosts) (eq .Status.State "up") }}
51-
<a id="{{ md_toc .HostAddress.Address }}"></a>
5244

53-
## {{ .HostAddress.Address }}{{ range .HostNames.HostName }} / {{ .Name }}{{ end }}{{ if eq .Status.State "up" }} (up){{ else }} (down){{ end }}
45+
## {{ md_title . }}
5446

5547
{{- if eq .Status.State "up" }}
56-
<a id="{{ md_toc .HostAddress.Address }}-info"></a>
57-
5848
### Info:
5949

6050
| Name | Value |
@@ -72,8 +62,6 @@ NMAP Scan Result: {{ .NMAPRun.StartStr }}
7262
{{- end -}}{{/* if .OS.OSMatch.Name */}}
7363
{{ end }}{{/* if .OS */}}
7464

75-
<a id="{{ md_toc .HostAddress.Address }}-ports"></a>
76-
7765
### Ports:
7866

7967
| Port | State | Service | Reason | Product | Version | Extra Info |
@@ -82,7 +70,6 @@ NMAP Scan Result: {{ .NMAPRun.StartStr }}
8270
| {{ .PortID }} | {{ .Protocol }} | {{ .State.State }} | {{ .Service.Name }} | {{ .State.Reason }} | {{ .Service.Product }} | {{ .Service.Version }} | {{ .Service.ExtraInfo }} |
8371
{{ end }}{{/* range .Ports.Port */}}
8472
{{ if not $skipPortScripts }}
85-
<a id="{{ md_toc .HostAddress.Address }}-scripts"></a>
8673

8774
### Scripts:
8875
{{ range .Ports.Port -}}

0 commit comments

Comments
 (0)