Commit Diff


commit - 4bcb477f41800862d0a7c265b40dfccf97180dcc
commit + a5169896c9f629389d4effce43b784aa90204dcb
blob - 3ee0fe29e984c743a573219152d6c86e8d380abf
blob + 9bdacfefd2524571c7fa026b8340643500b1b0de
--- cmd/Jira/Jira.go
+++ cmd/Jira/Jira.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"bytes"
 	"errors"
 	"flag"
 	"fmt"
@@ -197,7 +196,8 @@ func (w *awin) postComment() error {
 	}
 	elems := strings.Split(w.name(), "/")
 	ikey := fmt.Sprintf("%s-%s", elems[0], elems[1])
-	return f.Client.PostComment(ikey, bytes.NewReader(body))
+	jtf := toJTF(string(body))
+	return f.Client.PostComment(ikey, strings.NewReader(jtf))
 }
 
 func newSearch(fsys fs.FS, query string) {
blob - /dev/null
blob + 11b174e2b5625023437a253062b6e96cf6111641 (mode 644)
--- /dev/null
+++ cmd/Jira/comment.jtf
@@ -0,0 +1,20 @@
+h3. My comment
+
+{quote}Hello, world! this is a test{quote}
+
+A bit confused here. The code says something but I'm not sure that's so important.
+
+The reality is that it says this:
+
+{noformat}echo hello world!
+{noformat}
+
+So it's not upper case according to [RFC 7666|http://example.com].
+
+h3. Why this *matters*
+
+Because youse are all fucked m8. But to keep it short, without worrying about fmt.Println:
+
+* Who is your Daddy?
+* And what does he do?
+* Show me the money
\ No newline at end of file
blob - /dev/null
blob + 9531ebe77170bfbb77267fda48ee20414ca6eeba (mode 644)
--- /dev/null
+++ cmd/Jira/comment.md
@@ -0,0 +1,24 @@
+# My comment
+
+> Hello, world!
+> this is a test
+
+A bit confused here.
+The code says something but I'm not sure that's so important.
+
+The reality is that it says this:
+
+	echo hello world!
+
+So it's not upper case according to [RFC 7666].
+
+# Why this *matters*
+
+Because youse are all fucked m8.
+But to keep it short, without worrying about [fmt.Println]:
+
+	* Who is your Daddy?
+	* And what does he do?
+	* Show me the money
+
+[RFC 7666]: http://example.com
blob - /dev/null
blob + c813b41259ff09d03f1d9ebe7603203237b724fe (mode 644)
--- /dev/null
+++ cmd/Jira/jtf.go
@@ -0,0 +1,77 @@
+package main
+
+import (
+	"fmt"
+	"go/doc/comment"
+	"strings"
+)
+
+// https://jira.atlassian.com/secure/WikiRendererHelpAction.jspa?section=all
+
+func toJTF(content string) string {
+	var p comment.Parser
+	doc := p.Parse(content)
+	buf := &strings.Builder{}
+	for _, block := range doc.Content {
+		switch v := block.(type) {
+		case *comment.Heading:
+			fmt.Fprintf(buf, "h3. %s\n", render(v.Text))
+		case *comment.Paragraph:
+			fmt.Fprintln(buf, render(v.Text))
+		case *comment.Code:
+			fmt.Fprintf(buf, "{noformat}%s{noformat}\n", v.Text)
+		case *comment.List:
+			fmt.Fprintln(buf, renderList(v))
+		}
+		fmt.Fprintln(buf)
+	}
+	return strings.TrimSpace(buf.String())
+}
+
+func renderList(list *comment.List) string {
+	buf := &strings.Builder{}
+	prefix := "*"
+	for _, it := range list.Items {
+		if it.Number != "" {
+			prefix = "#"
+		}
+		for _, block := range it.Content {
+			// the block is known to be a paragraph
+			s := render(block.(*comment.Paragraph).Text)
+			fmt.Fprintln(buf, prefix, s)
+		}
+	}
+	return buf.String()
+}
+
+func render(text []comment.Text) string {
+	buf := &strings.Builder{}
+	for _, txt := range text {
+		switch v := txt.(type) {
+		case comment.Plain:
+			s := strings.ReplaceAll(string(v), "\n", " ")
+			if strings.HasPrefix(s, "> ") {
+				s = strings.ReplaceAll(s, "> ", "")
+				fmt.Fprintf(buf, "{quote}%s{quote}", s)
+			} else {
+				buf.WriteString(s)
+			}
+		case comment.Italic:
+			fmt.Fprintf(buf, "*%s*", v)
+		case *comment.Link:
+			if v.Auto {
+				fmt.Fprintf(buf, "[%s]", v.URL)
+			} else {
+				title := render(v.Text)
+				fmt.Fprintf(buf, "[%s|%s]", title, v.URL)
+			}
+		case *comment.DocLink:
+			// we're not actually printing godoc, so treat
+			// any accidental DocLink as plain text.
+			buf.WriteString(render(v.Text))
+		default:
+			fmt.Fprintf(buf, "%v", v)
+		}
+	}
+	return buf.String()
+}
blob - /dev/null
blob + a666ea56f0c25005db773b0d9d1225ac7e10721c (mode 644)
--- /dev/null
+++ cmd/Jira/jtf_test.go
@@ -0,0 +1,26 @@
+package main
+
+import (
+	"hash/crc32"
+	"os"
+	"testing"
+)
+
+func TestJTF(t *testing.T) {
+	b, err := os.ReadFile("comment.jtf")
+	if err != nil {
+		t.Fatal(err)
+	}
+	want := crc32.ChecksumIEEE(b)
+
+	b, err = os.ReadFile("comment.md")
+	if err != nil {
+		t.Fatal(err)
+	}
+	rendered := toJTF(string(b))
+	got := crc32.ChecksumIEEE([]byte(rendered))
+	if want != got {
+		t.Errorf("unexepected content in rendered comment")
+		t.Logf("%s\n", string(rendered))
+	}
+}