Convert copied jira kanban to org (jira-to-org)

I have been fiddling around with some very rudimentary Jira integration to org, basically something very simple, just a regular copy from the kanban and then convert into org headlines!

This package is designed for simpler workflows where you copy data from Jira rather than maintaining API integration.

Here is a link to the package:

https://github.com/captainflasmr/jira-to-org

Overview

jira-to-org is an Emacs package that converts Jira sprint board data into org-mode task entries. It parses text copied directly from Jira sprint boards and transforms it into properly formatted org-mode headings with TODO keywords, priorities, tags, and metadata.

Features

Installation

Manual Installation

  1. Download jira-to-org.el to your Emacs configuration directory
  2. Add to your init.el:
(add-to-list 'load-path "/path/to/jira-to-org/")
(require 'jira-to-org)

Using use-package

(use-package jira-to-org
  :load-path "/path/to/jira-to-org/"
  :custom
  (jira-to-org-default-sprint "s7")
  (jira-to-org-default-year "2025")
  (jira-to-org-heading-level 4))

Usage

Basic Workflow

  1. Open your Jira sprint board in a web browser
  2. Select and copy the sprint data (the entire board or specific columns)
  3. In Emacs, use one of the parsing commands

Commands

jira-to-org-parse-buffer

Parse the entire current buffer as Jira data. The result is copied to the kill ring.

M-x jira-to-org-parse-buffer

With prefix argument (C-u), prompts for a sprint tag:

C-u M-x jira-to-org-parse-buffer
Sprint tag (e.g., s7): s8

jira-to-org-parse-region

Parse Jira data in the selected region. The result is copied to the kill ring.

1. Select region containing Jira data
2. M-x jira-to-org-parse-region

jira-to-org-parse-and-insert

Parse Jira data from the clipboard and insert the org headings at point.

1. Copy Jira data to clipboard
2. Position cursor where you want entries inserted
3. M-x jira-to-org-parse-and-insert

jira-to-org-update-from-jira

Update existing org entries based on fresh Jira data. This command:

M-x jira-to-org-update-from-jira

Example Input Format

The package expects text copied from Jira sprint boards in this format:

To Do
MM-78
Implement IG connection management APIs
Assignee: James Dyer
Priority: Medium
Issue Type: Story
2

In Progress
MM-79
Create gRPC service definition
Assignee: Freddy
Priority: High
3

Done
MM-75
Setup project structure
Assignee: N Cropper
Priority: Low
Issue Type: Task
1

Example Output

The above input would be converted to:

#+BEGIN_EXAMPLE

Configuration

Customization Variables

jira-to-org-default-sprint

Default sprint tag to add to all entries (e.g., "s7"). If nil, no sprint tag is added.

(setq jira-to-org-default-sprint "s7")

jira-to-org-default-year

Default year to add as a tag to all entries.

(setq jira-to-org-default-year "2025")

jira-to-org-assignee-map

Alist mapping full names (as they appear in Jira) to short tag names.

(setq jira-to-org-assignee-map
      '(("James Dyer" . "jdyer")
        ("Freddy" . "freddy")
        ("N Cropper" . "ncropper")))

jira-to-org-priority-map

Alist mapping Jira priority levels to org-mode priority letters.

(setq jira-to-org-priority-map
      '(("Highest" . "A")
        ("High" . "A")
        ("Medium" . "B")
        ("Low" . "C")
        ("Lowest" . "C")))

jira-to-org-status-map

Alist mapping Jira status names to org-mode TODO keywords.

(setq jira-to-org-status-map
      '(("To Do" . "TODO")
        ("In Progress" . "DOING")
        ("Done" . "DONE")))

jira-to-org-heading-level

Number of asterisks for generated org headings (default: 4).

(setq jira-to-org-heading-level 3)  ; Use *** instead of ****

Complete Configuration Example

(use-package jira-to-org
  :custom
  (jira-to-org-default-sprint "s8")
  (jira-to-org-default-year "2025")
  (jira-to-org-heading-level 4)
  (jira-to-org-assignee-map
   '(("James Dyer" . "jdyer")
     ("Freddy Johnson" . "freddy")
     ("Sarah Chen" . "schen")
     ("Mike Wilson" . "mwilson")))
  (jira-to-org-priority-map
   '(("Highest" . "A")
     ("High" . "A")
     ("Medium" . "B")
     ("Low" . "C")
     ("Lowest" . "C")))
  (jira-to-org-status-map
   '(("To Do" . "TODO")
     ("In Progress" . "DOING")
     ("In Review" . "REVIEW")
     ("Done" . "DONE")))
  :bind
  (:map org-mode-map
        ("C-c j p" . jira-to-org-parse-and-insert)
        ("C-c j u" . jira-to-org-update-from-jira)))

Workflow Integration

Sprint Planning Workflow

  1. Open your sprint planning org file
  2. Navigate to the sprint section
  3. Copy the Jira sprint board data
  4. Run M-x jira-to-org-parse-and-insert
  5. Adjust any entries as needed

Daily Standup Updates

  1. Copy current sprint board state from Jira
  2. Run M-x jira-to-org-update-from-jira
  3. Review updated TODO states
  4. Any new items are copied to kill ring for manual placement

Custom Key Bindings

;; Add to your org-mode configuration
(with-eval-after-load 'org
  (define-key org-mode-map (kbd "C-c j p") #'jira-to-org-parse-and-insert)
  (define-key org-mode-map (kbd "C-c j r") #'jira-to-org-parse-region)
  (define-key org-mode-map (kbd "C-c j b") #'jira-to-org-parse-buffer)
  (define-key org-mode-map (kbd "C-c j u") #'jira-to-org-update-from-jira))

Parsed Fields

The package extracts and uses the following fields from Jira data:

Jira Field Usage Example
Issue Key Included in heading MM-78
Title Included in heading Fix bug in API
Status Converted to TODO keyword In Progress
Assignee Converted to tag James Dyer
Priority Converted to org priority Medium
Story Points Extracted (not currently used in output) 3

Customizing for Your Organization

Adjusting Issue Key Pattern

If your Jira instance uses a different project key pattern, modify the regex in jira-to-org--parse-buffer-to-items:

;; Current pattern matches MM-123
((string-match "^\\(MM-[0-9]+\\)$" line)

;; Example: Match PROJECT-123
((string-match "^\\(PROJECT-[0-9]+\\)$" line)

;; Example: Match multiple projects (PROJ1-123 or PROJ2-123)
((string-match "^\\(\\(?:PROJ1\\|PROJ2\\)-[0-9]+\\)$" line)

Adding Custom Status Mappings

If your Jira workflow has additional statuses:

(setq jira-to-org-status-map
      '(("To Do" . "TODO")
        ("In Progress" . "DOING")
        ("Code Review" . "REVIEW")
        ("QA Testing" . "TESTING")
        ("Blocked" . "BLOCKED")
        ("Done" . "DONE")))

Make sure your org-mode TODO keywords match:

(setq org-todo-keywords
      '((sequence "TODO" "DOING" "REVIEW" "TESTING" "BLOCKED" "|" "DONE")))

Troubleshooting

No Items Parsed

Wrong Assignee Tags

Incorrect TODO Keywords

Entries Not Found During Update

API Functions

For programmatic use:

jira-to-org-parse-string

(jira-to-org-parse-string STRING &optional SPRINT)

Parse STRING containing Jira data and return org-mode headings as a string.

jira-to-org--parse-buffer-to-items

(jira-to-org--parse-buffer-to-items BUFFER-OR-STRING)

Parse Jira data into a list of jira-to-org-item structs for further processing.

jira-to-org--item-to-org-heading

(jira-to-org--item-to-org-heading ITEM &optional SPRINT)

Convert a jira-to-org-item struct to an org-mode heading string.

Contributing

Contributions are welcome! Please submit issues or pull requests on the project repository.

Development Setup

  1. Clone the repository
  2. Load jira-to-org.el in Emacs
  3. Make changes and test with sample Jira data
  4. Run byte-compilation: M-x byte-compile-file

Testing

Create a test file with sample Jira data and verify parsing:

(with-temp-buffer
  (insert "To Do\nMM-1\nTest Issue\nAssignee: Test User\nPriority: High\n")
  (jira-to-org-parse-buffer))

License

This package is provided as-is for personal and professional use.

Changelog

Version 1.0

Comments

comments powered by Disqus