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 @@
+
+
+
+
+
+
# 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 {