diff --git a/.doc/doki/doc/image-requirements.md b/.doc/doki/doc/image-requirements.md index 8846f7b..434cc05 100644 --- a/.doc/doki/doc/image-requirements.md +++ b/.doc/doki/doc/image-requirements.md @@ -40,7 +40,7 @@ If `mmdc` is not found, Mermaid blocks are displayed as plain code blocks. ## Graphviz diagrams -Rendering fenced code blocks tagged `` ```dot `` or `` ```graphviz `` requires [`dot`](https://graphviz.org/) (from the Graphviz suite) to be installed and available in `PATH`. +Rendering fenced code blocks tagged `dot` or `graphviz` requires [`dot`](https://graphviz.org/) (from the Graphviz suite) to be installed and available in `PATH`. ``` # macOS diff --git a/README.md b/README.md index 9a25fc6..a8220ba 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +

+ + X (Twitter) + +

+ # tiki UPDATE: @@ -159,6 +165,7 @@ Feedback is always welcome! Whether you have an improvement request, a feature s or just chat: - use GitHub issues to submit and issue or a feature request - use GitHub discussions for everything else +- follow and DM on [X](https://x.com/booleanandmaybe) to contribute: [Contributing](CONTRIBUTING.md) diff --git a/internal/pipe/create.go b/internal/pipe/create.go index 28f6a98..4260e38 100644 --- a/internal/pipe/create.go +++ b/internal/pipe/create.go @@ -109,12 +109,29 @@ func CreateTaskFromReader(r io.Reader) (string, error) { } // parseInput splits piped text into title and description. -// Single line: entire input becomes the title, no description. -// Multi-line: first line is the title, everything after is the description (trimmed). +// If the first line is a markdown heading (e.g. "# Title"), the '#' prefix is +// stripped for the title and the description contains the entire original input. +// Otherwise: first line is the title, everything after is the description. func parseInput(input string) (title, description string) { first, rest, found := strings.Cut(input, "\n") - if !found { - return strings.TrimSpace(input), "" + title = strings.TrimSpace(first) + + if heading, ok := stripMarkdownHeading(title); ok { + return heading, strings.TrimSpace(input) } - return strings.TrimSpace(first), strings.TrimSpace(rest) + + if !found { + return title, "" + } + return title, strings.TrimSpace(rest) +} + +// stripMarkdownHeading returns the heading text without the leading '#' chars +// if line is a valid ATX heading (one or more '#' followed by a space). +func stripMarkdownHeading(line string) (string, bool) { + trimmed := strings.TrimLeft(line, "#") + if trimmed == line || !strings.HasPrefix(trimmed, " ") { + return "", false + } + return strings.TrimSpace(trimmed), true } diff --git a/internal/pipe/create_test.go b/internal/pipe/create_test.go index a4d2152..cd056f1 100644 --- a/internal/pipe/create_test.go +++ b/internal/pipe/create_test.go @@ -51,6 +51,36 @@ func TestParseInput(t *testing.T) { wantTitle: "Title", wantDesc: "Description after gaps", }, + { + name: "markdown h1 heading becomes title without hash", + input: "# Try attempt\n\nThis is just a try", + wantTitle: "Try attempt", + wantDesc: "# Try attempt\n\nThis is just a try", + }, + { + name: "markdown h2 heading stripped", + input: "## Second level\n\nBody text", + wantTitle: "Second level", + wantDesc: "## Second level\n\nBody text", + }, + { + name: "markdown h3 heading with multi-line body", + input: "### Deep heading\n\nLine 1\nLine 2", + wantTitle: "Deep heading", + wantDesc: "### Deep heading\n\nLine 1\nLine 2", + }, + { + name: "markdown heading only no body", + input: "# Solo heading", + wantTitle: "Solo heading", + wantDesc: "# Solo heading", + }, + { + name: "hash without space is not a heading", + input: "#notaheading\n\nBody", + wantTitle: "#notaheading", + wantDesc: "Body", + }, } for _, tt := range tests {