github.com/vipcoin-gold/reviewdog@v1.0.2/service/commentutil/code_fence.go (about) 1 package commentutil 2 3 import "io" 4 5 // GetCodeFenceLength returns the length of a code fence needed to wrap code. 6 // A test suggestion that uses four backticks w/o code fence block. 7 // Fixes: https://github.com/reviewdog/reviewdog/issues/999 8 // 9 // Code fenced blocks are supported by GitHub Flavor Markdown. 10 // A code fence is typically three backticks. 11 // 12 // ``` 13 // code 14 // ``` 15 // 16 // However, we sometimes need more backticks. 17 // https://docs.github.com/en/github/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks#fenced-code-blocks 18 // 19 // > To display triple backticks in a fenced code block, wrap them inside quadruple backticks. 20 // > 21 // > ```` 22 // > ``` 23 // > Look! You can see my backticks. 24 // > ``` 25 // > ```` 26 func GetCodeFenceLength(code string) int { 27 backticks := countBackticks(code) + 1 28 if backticks < 3 { 29 // At least three backticks are required. 30 // https://github.github.com/gfm/#fenced-code-blocks 31 // > A code fence is a sequence of at least three consecutive backtick characters (`) or tildes (~). (Tildes and backticks cannot be mixed.) 32 backticks = 3 33 } 34 return backticks 35 } 36 37 // WriteCodeFence writes a code fence to w. 38 func WriteCodeFence(w io.Writer, length int) error { 39 if w, ok := w.(io.ByteWriter); ok { 40 // use WriteByte instead of Write to avoid memory allocation. 41 for i := 0; i < length; i++ { 42 if err := w.WriteByte('`'); err != nil { 43 return err 44 } 45 } 46 return nil 47 } 48 49 buf := make([]byte, length) 50 for i := range buf { 51 buf[i] = '`' 52 } 53 _, err := w.Write(buf) 54 return err 55 } 56 57 // find code fences in s, and returns the maximum length of them. 58 func countBackticks(s string) int { 59 inBackticks := true 60 61 var count int 62 var maxCount int 63 for _, r := range s { 64 if inBackticks { 65 if r == '`' { 66 count++ 67 } else { 68 inBackticks = false 69 if count > maxCount { 70 maxCount = count 71 } 72 count = 0 73 } 74 } 75 if r == '\n' { 76 inBackticks = true 77 count = 0 78 } 79 } 80 if count > maxCount { 81 maxCount = count 82 } 83 return maxCount 84 }