Skip to content

Commit

Permalink
Merge pull request #112 from cpuguy83/fix_newline_escape
Browse files Browse the repository at this point in the history
Fix escape characters for content with newline
  • Loading branch information
cpuguy83 authored Mar 18, 2024
2 parents 1e915fd + f0c6142 commit d6816bf
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
23 changes: 23 additions & 0 deletions md2man/roff.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package md2man

import (
"bufio"
"bytes"
"fmt"
"io"
Expand Down Expand Up @@ -333,6 +334,28 @@ func out(w io.Writer, output string) {
}

func escapeSpecialChars(w io.Writer, text []byte) {
scanner := bufio.NewScanner(bytes.NewReader(text))

// count the number of lines in the text
// we need to know this to avoid adding a newline after the last line
n := bytes.Count(text, []byte{'\n'})
idx := 0

for scanner.Scan() {
dt := scanner.Bytes()
if idx < n {
idx++
dt = append(dt, '\n')
}
escapeSpecialCharsLine(w, dt)
}

if err := scanner.Err(); err != nil {
panic(err)
}
}

func escapeSpecialCharsLine(w io.Writer, text []byte) {
for i := 0; i < len(text); i++ {
// escape initial apostrophe or period
if len(text) >= 1 && (text[0] == '\'' || text[0] == '.') {
Expand Down
32 changes: 18 additions & 14 deletions md2man/roff_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ func TestEscapeCharacters(t *testing.T) {
tests := []string{
"Test-one_two&three\\four~five",
".nh\n\n.PP\nTest-one_two&three\\\\four~five\n",
"'foo'\n'bar'",
".nh\n\n.PP\n\\&'foo'\n\\&'bar'\n",
}
doTestsInline(t, tests)
}
Expand Down Expand Up @@ -445,23 +447,25 @@ func doTestsParam(t *testing.T, tests []string, params TestParams) {
execRecoverableTestSuite(t, tests, params, func(candidate *string) {
for i := 0; i+1 < len(tests); i += 2 {
input := tests[i]
*candidate = input
expected := tests[i+1]
actual := runMarkdown(*candidate, params)
if actual != expected {
t.Errorf("\nInput [%#v]\nExpected[%#v]\nActual [%#v]",
*candidate, expected, actual)
}
t.Run(input, func(t *testing.T) {
*candidate = input
expected := tests[i+1]
actual := runMarkdown(*candidate, params)
if actual != expected {
t.Errorf("\nInput [%#v]\nExpected[%#v]\nActual [%#v]",
*candidate, expected, actual)
}

// now test every substring to stress test bounds checking
if !testing.Short() {
for start := 0; start < len(input); start++ {
for end := start + 1; end <= len(input); end++ {
*candidate = input[start:end]
runMarkdown(*candidate, params)
// now test every substring to stress test bounds checking
if !testing.Short() {
for start := 0; start < len(input); start++ {
for end := start + 1; end <= len(input); end++ {
*candidate = input[start:end]
runMarkdown(*candidate, params)
}
}
}
}
})
}
})
}
Expand Down

0 comments on commit d6816bf

Please sign in to comment.