Skip to content

Instantly share code, notes, and snippets.

@hoangmy92
Created August 5, 2016 07:57
Show Gist options
  • Save hoangmy92/a2a98c89c07a929fcb906c80b01fe266 to your computer and use it in GitHub Desktop.
Save hoangmy92/a2a98c89c07a929fcb906c80b01fe266 to your computer and use it in GitHub Desktop.
Backlog2Markdown
# -*- encoding: utf-8 -*-
import re
def convert_bold(content):
raw = bytearray(content)
for m in re.finditer(r"\'\'((?!\'\').)+\'\'", content):
start = m.start()
end = m.end()
raw[start] = raw[start + 1] = raw[end - 1] = raw[end - 2] = ord('_')
return str(raw)
def convert_italic(content):
raw = bytearray(content)
for m in re.finditer(r"\'\'\'((?!\'\'\').)+\'\'\'", content):
start = m.start()
end = m.end()
raw[start] = raw[start + 1] = raw[end - 1] = raw[end - 2] = ord(' ')
raw[start + 2] = raw[end - 3] = ord('_')
return str(raw)
def convert_header(content):
pattern = re.compile(r'(\*)\1{0,5}')
mem = 0
raw = bytearray(content)
for m in pattern.finditer(content):
start = m.start()
end = m.end()
for n in range(start, end):
raw[n + mem] = ord('#')
if raw[end + mem] != ord(' '):
raw.insert(end + mem, ord(' '))
mem += 1
return str(raw)
def convert_bulleted_list(content):
pattern = re.compile(r'(?:^|\n)(-)\1{0,4} ')
mem = 0
raw = bytearray(content)
for m in pattern.finditer(content):
start = m.start()
end = m.end() - 1
# Skip endline character
start = (start + 1) if raw[start + mem] == 10 else start
# Replace '-' to whitespace except the latter
for n in range(start, end):
raw[n + mem] = ord(' ') if (n != end - 1) else ord('*')
# Insert additional space
if end - start - 1 > 0:
for n in range(start, end - 1):
raw.insert(n + mem, ord(' '))
mem += (end - start - 1)
return str(raw)
def convert_numbered_list(content):
pattern = re.compile(r'(?:^|\n)(\+)\1{0,4} ')
mem = 0
raw = bytearray(content)
for m in pattern.finditer(content):
start = m.start()
end = m.end() - 1
# Skip endline character
start = (start + 1) if raw[start + mem] == 10 else start
# Replace '+' to whitespace except the latter
for n in range(start, end):
raw[n + mem] = ord(' ') if (n != end - 1) else ord('1')
# Add '.' after 1
raw.insert(end + mem, ord('.'))
mem += 1
# Insert additional space
if end - start - 1 > 0:
for n in range(start, end - 1):
raw.insert(n + mem, ord(' '))
mem += (end - start - 1)
return str(raw)
def convert_code(content):
# Replace `{code}`
content = re.sub(r'(?:^|\n)\{code\}', '\n``` ', content)
# Replace `{/code}`
content = re.sub(r'(?:^|\n)\{\/code\}', '\n``` ', content)
return content
def convert_quote(content):
lines = content.split('\n')
quote_content = False
is_first = False
mem = 0
for m in range(0, len(lines)):
if re.match(r'^\{quote\}$', lines[m + mem]):
is_first = quote_content = True
elif re.match(r'^\{\/quote\}$', lines[m + mem]):
is_first = quote_content = False
elif quote_content:
# Trick to prevent markdown inline
if not is_first and len(lines[m + mem]) != 0 and len(lines[m + mem -1]) != 2:
lines.insert(m + mem, '> ')
mem += 1
lines[m + mem] = "> " + lines[m + mem]
if is_first:
is_first = False
result = '\n'.join(lines)
return result.replace('{quote}', '').replace('{/quote}', '')
def convert_table(content):
lines = content.split('\n')
length = len(lines)
marks = dict()
cols = 0
mem = 0
for m in range(0, length):
if is_table_row(lines[m]):
cur_cols = calc_cols(lines[m])
# Remove backlog markup
lines[m] = lines[m].replace('|~', '|')
# Track new table
if cols != cur_cols:
marks[m] = cur_cols
cols = cur_cols
for key, value in marks.items():
heading = '|-|'
for i in range(1, value - 1):
heading += ':-|'
lines.insert(key + mem + 1, heading)
mem += 1
return '\n'.join(lines)
def convert_link(content):
return re.sub(r'\[\[(((?!\>|\]\]|\:).)*)(\>|\:)(((?!\]\])(.|\/|\:))*)\]\]', link_rule, content)
def convert_cacoo_link(content):
return re.sub(r'\#cacoo\((((?!\)|\/view\,).)*)(((?!\)).)*)+\)', cacoo_rule, content)
def cacoo_rule(found):
return 'https://cacoo.com/' + found.group(1)
def link_rule(found):
return '[' + found.group(1) + '](' + found.group(4) + ')'
def is_table_row(str):
return re.match(r'^\|.+\|\s*$', str)
def calc_cols(str):
return len(re.findall(r'\|', str))
def convert(content):
return convert_bold(
convert_italic(
convert_quote(
convert_bulleted_list(
convert_numbered_list(
convert_header(
convert_code(
convert_table(
content
)
)
)
)
)
)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment