Skip to content

Commit

Permalink
First version of mistune Jira
Browse files Browse the repository at this point in the history
  • Loading branch information
chalbersma committed Jun 16, 2023
1 parent dfb09f4 commit 0543859
Show file tree
Hide file tree
Showing 8 changed files with 292 additions and 0 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/python-publish-stag.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Upload Python Package [Staging]

on:
push:
branches:
- main

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.STAG_PYPI_TOKEN }}
repository_url: https://test.pypi.org/legacy/
36 changes: 36 additions & 0 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Upload Python Package

on:
release:
types: [published]

jobs:
deploy:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PROD_PYPI_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,4 @@ cython_debug/
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
/.idea
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,37 @@ The goal is to be able to have data in markdown and then use that markdown to cr
ticket in Jira.

Hopefully Jira will someday fully support markdown and make this project irrelevant.

## Usage

```python
import mistune
import mistune_jira

text = '''
# Lorem Ipsum
This is some sample markdown. [Say hi to google](https://www.google.com) as an example link
to be converted.
HR line
---
* a list of cool things
* doggies
* Little Doggies (Won't yet render correctly)
* Shaggy Doggies
* Grumpy Doggies
* spaceships
* $2 bills
'''

rend = mistune_jira.JiraRenderer()

markdown_parser = mistune.Markdown(renderer=rend)

jira_compat = markdown_parser(text)

print(jira_compat)
```
2 changes: 2 additions & 0 deletions mistune_jira/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

from .jiraRenderer import JiraRenderer
153 changes: 153 additions & 0 deletions mistune_jira/jiraRenderer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
#!/usr/bin/env python3

import re

from mistune import BaseRenderer, BlockState
from mistune.util import strip_end
from mistune.renderers._list import render_list


class JiraRenderer(BaseRenderer):

'''
MistuneJiraRenderer
Based off the RSTRenderer and some earlier work from 2018 of mine
'''

NAME = "jira"

HEADING_MARKERS = [
"h1. ",
"h2. ",
"h3. ",
"h4. ",
"h5. ",
"h6. "
]

INLINE_IMAGE_PREFIX = "img-"

def iter_tokens(self, tokens, state):
prev = None
for tok in tokens:
# ignore blank line
if tok['type'] == 'blank_line':
continue
tok['prev'] = prev
prev = tok
yield self.render_token(tok, state)

def __call__(self, tokens, state: BlockState):
state.env['inline_images'] = []
out = self.render_tokens(tokens, state)
return strip_end(out)

def render_referrences(self, state: BlockState):
images = state.env['inline_images']
for index, token in enumerate(images):
attrs = token['attrs']
alt = self.render_children(token, state)
ident = self.INLINE_IMAGE_PREFIX + str(index)
yield '.. |' + ident + '| image:: ' + attrs['url'] + '\n :alt: ' + alt

def render_children(self, token, state: BlockState):
children = token['children']
return self.render_tokens(children, state)

def text(self, token, state):

text = token["raw"]

return text

def emphasis(self, token, state):

return "_{}_".format(self.render_children(token, state))

def strong(self, token, state):

return "*{}*".format(self.render_children(token, state))

def linebreak(self, token, state):

return "\\"

def softbreak(self, token, state):

return " "

def inline_html(self, token, BlockState):
return token['raw']


def link(self, token, state):
# This might need more logic to handle different types of links

attrs = token['attrs']
text = self.render_children(token, state)

return "[{}|{}]".format(text, attrs["url"])

def codespan(self, token, state):

return "{{{{{}}}}}".format(token["raw"])

def paragraph(self, token, state):

return "{} \n\n".format(self.render_children(token, state))

def heading(self, token, state):

level = token["attrs"]["level"]

return "\nh{}. {}\n".format(level, self.render_children(token, state))

def thematic_break(self, token, state):

return "\n----\n"

def block_text(self, token, state):

return "{}\n".format(self.render_children(token, state))

def block_code(self, token, state):
attrs = token.get('attrs', {})
info = attrs.get('info')
try:
lang = info.split()[0]
except IndexError:
langstr = ""
else:
if lang not in ("actionscript", "ada", "applescript", "bash", "c", "c#", "c++", "css", "erlang", "go", "groovy",
"haskell", "html", "javascript", "json", "lua", "nyan", "objc", "perl", "php", "python", "r",
"ruby", "scala", "sql", "swift", "visualbasic", "xml", "yaml"):
langstr = ""
else:
langstr = ":{}".format(lang)

codestr = token['raw']

return '''\n{{code{langstr}}}
{codestr}
{{code}}\n'''.format(langstr=langstr, codestr=codestr)

def block_quote(self, token, state):

return '''\n{{quote}}
{quote}
{{quote}}\n'''.format(quote=self.render_children(token, state))

def block_html(self, token, state):

return '''\n{{noformat}}
{html}
{{noformat}}'''.format(html=token["raw"])

def block_error(self, token, state):
return '''\n{{noformat}}
{error}
{{noformat}}'''.format(error=token["raw"])

def list(self, token, state):
return render_list(self, token, state)
27 changes: 27 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[build-system]
requires = [
"twine",
"setuptools"
]
build-backend = "setuptools.build_meta"

[project]
name = "mistune_jira"
version = "2023.6.16.0"
authors = [
{name = "Chris Halbersma", email = "[email protected]"},
]
description = "A mostly functional plugin for mistune to render Jira's markup language"
readme = "README.md"
requires-python = ">=3.10"
keywords = ["mistune", "jira", "atlassian"]
license = {text = "BSD-3-Clause"}
classifiers = [
"Programming Language :: Python :: 3",
]
dependencies = [
"mistune",
]

[options]
packages = ["mistune_jira"]
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mistune>=3.0.1

0 comments on commit 0543859

Please sign in to comment.