', data, 1)
fol_num += 1
else:
middle_list += ['span']
data = re.sub('(?:{{{((?:(?! |{{{|}}}).)*) ?|(}}}))', '', data, 1)
else:
middle_list += ['code']
middle_stack += 1
data = re.sub('(?:{{{((?:(?! |{{{|}}}).)*)|(}}}))', '' + middle_data[0].replace('\\', '\\\\'), data, 1)
middle_number += 1
else:
if middle_list == []:
data = re.sub('(?:{{{((?:(?! |{{{|}}}).)*) ?|(}}}))', '}}}', data, 1)
else:
if middle_stack > 0:
middle_stack -= 1
if middle_stack > 0:
data = re.sub('(?:{{{((?:(?! |{{{|}}}).)*) ?|(}}}))', '}}}', data, 1)
else:
if middle_number > 0:
middle_number -= 1
if middle_list[middle_number] == '2div':
data = re.sub('(?:{{{((?:(?! |{{{|}}}).)*) ?|(}}}))', '', data, 1)
elif middle_list[middle_number] == 'pre':
data = re.sub('(?:{{{((?:(?! |{{{|}}}).)*) ?|(}}}))', '', data, 1)
else:
data = re.sub('(?:{{{((?:(?! |{{{|}}}).)*) ?|(}}}))', '' + middle_list[middle_number] + '>', data, 1)
del(middle_list[middle_number])
else:
break
# NoWiki 처리
num = 0
while 1:
nowiki_data = re.search('((?:(?:(?!<\/code>).)*\n*)*)<\/code>', data)
if nowiki_data:
nowiki_data = nowiki_data.groups()
num += 1
end_data += [['nowiki_' + str(num), nowiki_data[0], 'code']]
data = re.sub('((?:(?:(?!<\/code>).)*\n*)*)<\/code>', '', data, 1)
else:
break
# Syntax 처리
num = 0
while 1:
syntax_data = re.search('((?:(?:(?:(?!<\/code>|((?:(?:(?:(?!<\/code>|', data, 1)
else:
break
return data
def link_fix(main_link):
if re.search('^:', main_link):
main_link = re.sub('^:', '', main_link)
main_link = re.sub('^사용자:', 'user:', main_link)
main_link = re.sub('^파일:', 'file:', main_link)
main_link = re.sub('^분류:', 'category:', main_link)
other_link = re.search('(#.+)$', main_link)
if other_link:
other_link = other_link.groups()[0]
main_link = re.sub('(#.+)$', '', main_link)
else:
other_link = ''
return [main_link, other_link]
def namu(conn, data, title, main_num):
# DB 지정
curs = conn.cursor()
# 초기 설정
data = '\n' + data + '\n'
backlink = []
plus_data = '''
'''
global end_data
end_data = []
# XSS 이스케이프
data = html.escape(data)
# 개행 정리 1
data = re.sub('\r\n', '\n', data)
# 중괄호 파싱 1
data = middle_parser(data)
# 포함 문법 처리
while 1:
include = re.search('\[include\(((?:(?!\)\]).)+)\)\]', data)
if include:
include = include.groups()[0]
include_data = re.search('^((?:(?!,).)+)', include)
if include_data:
include_data = include_data.groups()[0]
else:
include_data = 'Test'
include_link = include_data
backlink += [[title, include_link, 'include']]
include = re.sub('^((?:(?!,).)+)', '', include)
# 틀 NoWiki
num = 0
while 1:
include_one_nowiki = re.search('(?:\\\\){2}(.)', include)
if include_one_nowiki:
include_one_nowiki = include_one_nowiki.groups()
num += 1
end_data += [['include_one_nowiki_' + str(num), include_one_nowiki[0], 'normal']]
include = re.sub('(?:\\\\){2}(.)', '', include, 1)
else:
break
curs.execute("select data from data where title = ?", [include_data])
include_data = curs.fetchall()
if include_data:
include_parser = include_data[0][0]
while 1:
include_plus = re.search(', ?((?:(?!=).)+)=((?:(?!,).)+)', include)
if include_plus:
include_plus = include_plus.groups()
include_parser = re.sub('@' + include_plus[0] + '@', include_plus[1], include_parser)
include = re.sub(', ?((?:(?!=).)+)=((?:(?!,).)+)', '', include, 1)
else:
break
include_parser = re.sub('\[\[(?:category|분류):(((?!\]\]|#include).)+)\]\]', '', include_parser)
include_parser = html.escape(include_parser)
data = re.sub('\[include\(((?:(?!\)\]).)+)\)\]', '\n[' + include_link + ']\n' + include_parser + '\n', data, 1)
else:
data = re.sub('\[include\(((?:(?!\)\]).)+)\)\]', '' + include_link + '', data, 1)
else:
break
# 개행 정리 2
data = re.sub('\r\n', '\n', data)
# 중괄호 파싱 2
data = middle_parser(data)
# 기타 처리
data = re.sub('&', '&', data)
# HTML 허용
curs.execute('select html from html_filter')
html_db = curs.fetchall()
src_list = ["www.youtube.com", "serviceapi.nmv.naver.com", "tv.kakao.com", "www.google.com", "serviceapi.rmcnmv.naver.com"]
html_list = ['div', 'span', 'embed', 'iframe', 'ruby', 'rp', 'rt']
html_data = re.findall('<(\/)?((?:(?!>| ).)+)( (?:(?:(?!>).)+)?)?>', data)
for in_data in html_data:
if in_data[0] == '':
if in_data[1] in html_list or (html_db and in_data[1] in html_db[0]):
if re.search('<\/' + in_data[1] + '>', data):
src = re.search('src=([^ ]*)', in_data[2])
if src:
v_src = re.search('http(?:s)?:\/\/([^/\'" ]*)', src.groups()[0])
if v_src:
if not v_src.groups()[0] in src_list:
and_data = re.sub(''', '\'', re.sub('"', '"', re.sub('src=([^ ]*)', '', in_data[2])))
else:
and_data = re.sub(''', '\'', re.sub('"', '"', in_data[2]))
else:
and_data = re.sub(''', '\'', re.sub('"', '"', re.sub('src=([^ ]*)', '', in_data[2])))
else:
and_data = re.sub(''', '\'', re.sub('"', '"', in_data[2]))
data = data.replace('<' + in_data[1] + in_data[2] + '>', '<' + in_data[1] + and_data + '>', 1)
data = re.sub('<\/' + in_data[1] + '>', '' + in_data[1] + '>', data, 1)
position = re.compile('position', re.I)
data = position.sub('', data)
# 표 정리
data = re.sub('\n( +)\|\|', '\n||', data)
data = re.sub('\|\|( +)\n', '||\n', data)
# 주석 처리
data = re.sub('\n##(((?!\n).)+)', '', data)
# 이중 표 처리
while 1:
wiki_table_data = re.search('
).)+)>((?:(?!
).\n*)+)<\/div_end>', data)
if wiki_table_data:
wiki_table_data = wiki_table_data.groups()
if re.search('\|\|', wiki_table_data[1]):
end_parser = re.sub('\n$', '', re.sub('^\n', '', table_start('\n' + wiki_table_data[1] + '\n')))
else:
end_parser = wiki_table_data[1]
data = re.sub('
).)+)>((?:(?!
).\n*)+)<\/div_end>', '
' + end_parser + '
', data, 1)
else:
break
data = re.sub('<\/div_end>', '
', data)
data = re.sub('<\/td>', '', data)
# 수식 처리
first = 0
while 1:
math = re.search('<math>((?:(?!<\/math>).)+)<\/math>', data)
if math:
if first == 0:
plus_data += '''
'''
math = math.groups()[0]
first += 1
data = re.sub('<math>((?:(?!<\/math>).)+)<\/math>', '', data, 1)
plus_data += ''
else:
break
# 한 글자 NoWiki
num = 0
while 1:
one_nowiki = re.search('(?:\\\\)(.)', data)
if one_nowiki:
one_nowiki = one_nowiki.groups()
num += 1
end_data += [['one_nowiki_' + str(num), one_nowiki[0], 'normal']]
data = re.sub('(?:\\\\)(.)', '', data, 1)
else:
break
# 수평줄
while 1:
hr = re.search('\n-{4,9}\n', data)
if hr:
data = re.sub('\n-{4,9}\n', '\n\n', data, 1)
else:
break
data += '\n'
# 추가 이스케이프
data = data.replace('\\', '\')
# 텍스트 꾸미기 문법
data = re.sub(''''(?P((?!''').)+)'''', '\g', data)
data = re.sub('''(?P((?!'').)+)''', '\g', data)
data = re.sub('~~(?P(?:(?!~~).)+)~~', '\g', data)
data = re.sub('--(?P(?:(?!~~).)+)--', '\g', data)
data = re.sub('__(?P(?:(?!__).)+)__', '\g', data)
data = re.sub('\^\^(?P(?:(?!\^\^).)+)\^\^', '\g', data)
data = re.sub(',,(?P(?:(?!,,).)+),,', '\g', data)
# 넘겨주기 변환
redirect = re.search('\n#(?:redirect|넘겨주기) ((?:(?!\n).)+)\n', data)
if redirect:
redirect = redirect.groups()[0]
return_link = link_fix(redirect)
main_link = return_link[0]
other_link = return_link[1]
backlink += [[title, main_link, 'redirect']]
data = re.sub('\n#(?:redirect|넘겨주기) (?P(?:(?!\n).)+)\n', '', data, 1)
# [목차(없음)] 처리
if not re.search('\[(?:목차|tableofcontents)\((?:없음|no)\)\]\n', data):
if not re.search('\[(?:목차|tableofcontents)\]', data):
data = re.sub('\n(?P={1,6}) ?(?P(?:(?!=).)+) ?={1,6}\n', '\n[목차]\n\g \g \g\n', data, 1)
else:
data = re.sub('\[(?:목차|tableofcontents)\((?:없음|no)\)\]\n', '', data)
# 문단 문법
toc_full = 0
toc_top_stack = 6
toc_stack = [0, 0, 0, 0, 0, 0]
edit_number = 0
toc_data = '
TOC\n\n'
while 1:
toc = re.search('\n(={1,6}) ?((?:(?!\n).)+) ?\n', data)
if toc:
toc = toc.groups()
toc_number = len(toc[0])
edit_number += 1
# 더 크면 그 전 스택은 초기화
if toc_full > toc_number:
for i in range(toc_number, 6):
toc_stack[i] = 0
if toc_top_stack > toc_number:
toc_top_stack = toc_number
toc_full = toc_number
toc_stack[toc_number - 1] += 1
toc_number = str(toc_number)
all_stack = ''
# 스택 합치기
for i in range(0, 6):
all_stack += str(toc_stack[i]) + '.'
while 1:
if re.search('[^0-9]0\.', all_stack):
all_stack = re.sub('[^0-9]0\.', '.', all_stack)
else:
break
all_stack = re.sub('^0\.', '', all_stack)
data = re.sub('\n(={1,6}) ?((?:(?!\n).)+) ?\n', '\n' + all_stack + ' ' + re.sub('=*$', '', toc[1]) + ' (Edit)\n', data, 1)
toc_main_data = toc[1]
toc_main_data = re.sub('=*$', '', toc_main_data)
toc_main_data = re.sub('\[\*((?:(?! |\]).)*)(?: ((?:(?!(\[\*(?:(?:(?!\]).)+)\]|\])).)+))?\]', '', toc_main_data)
toc_main_data = re.sub('<\/span>', '(수식)', toc_main_data)
toc_data += '' + all_stack + ' ' + toc_main_data + '\n'
else:
break
toc_data += '
'
data = re.sub('\[(?:목차|tableofcontents)\]', toc_data, data)
# 일부 매크로 처리
data = tool.savemark(data)
data = re.sub("\[anchor\((?P(?:(?!\)\]).)+)\)\]", '', data)
data = re.sub('\[ruby\((?P(?:(?!,).)+)\, ?(?P(?:(?!\)\]).)+)\)\]', '\g', data)
# 글 상자 끼어들기
data = re.sub('{{\|(?P(?:(?:(?!\|}}).)*\n*)+)\|}}', '
\g
', data)
# 원래 코드 재탕
now_time = tool.get_time()
data = re.sub('\[date\]', now_time, data)
time_data = re.search('^([0-9]{4}-[0-9]{2}-[0-9]{2})', now_time)
time = time_data.groups()
while 1:
age_data = re.search('\[age\(([0-9]{4}-[0-9]{2}-[0-9]{2})\)\]', data)
if age_data:
age = age_data.groups()[0]
old = datetime.datetime.strptime(time[0], '%Y-%m-%d')
will = datetime.datetime.strptime(age, '%Y-%m-%d')
e_data = old - will
data = re.sub('\[age\(([0-9]{4})-([0-9]{2})-([0-9]{2})\)\]', str(int(e_data.days / 365)), data, 1)
else:
break
while 1:
dday_data = re.search('\[dday\(([0-9]{4}-[0-9]{2}-[0-9]{2})\)\]', data)
if dday_data:
dday = dday_data.groups()[0]
old = datetime.datetime.strptime(time[0], '%Y-%m-%d')
will = datetime.datetime.strptime(dday, '%Y-%m-%d')
e_data = old - will
if re.search('^-', str(e_data.days)):
e_day = str(e_data.days)
else:
e_day = '+' + str(e_data.days)
data = re.sub('\[dday\(([0-9]{4}-[0-9]{2}-[0-9]{2})\)\]', e_day, data, 1)
else:
break
# 유튜브, 카카오 티비 처리
while 1:
video = re.search('\[(youtube|kakaotv|nicovideo)\(((?:(?!\)\]).)+)\)\]', data)
if video:
video = video.groups()
width = re.search(', ?width=((?:(?!,).)+)', video[1])
if width:
video_width = width.groups()[0]
else:
video_width = '560'
height = re.search(', ?height=((?:(?!,).)+)', video[1])
if height:
video_height = height.groups()[0]
else:
video_height = '315'
code = re.search('^(((?!,).)+)', video[1])
if code:
video_code = code.groups()[0]
else:
if video[0] == 'youtube':
video_code = 'BQ5PcIUcdUE'
else:
video_code = '66861302'
if video[0] == 'youtube':
video_code = re.sub('^https:\/\/www\.youtube\.com\/watch\?v=', '', video_code)
video_code = re.sub('^https:\/\/youtu\.be\/', '', video_code)
video_src = 'https://www.youtube.com/embed/' + video_code
elif video[0] == 'kakaotv':
video_code = re.sub('^https:\/\/tv\.kakao\.com\/channel\/9262\/cliplink\/', '', video_code)
video_code = re.sub('^http:\/\/tv\.kakao\.com\/v\/', '', video_code)
video_src = 'https://tv.kakao.com/embed/player/cliplink/' + video_code +'?service=kakao_tv'
else:
video_src = 'https://embed.nicovideo.jp/watch/' + video_code
data = re.sub('\[(youtube|kakaotv|nicovideo)\(((?:(?!\)\]).)+)\)\]', '', data, 1)
else:
break
# 인용문 구현
while 1:
block = re.search('(\n(?:> ?(?:(?:(?!\n).)+)?\n)+)', data)
if block:
block = block.groups()[0]
block = re.sub('^\n> ?', '', block)
block = re.sub('\n> ?', '\n', block)
block = re.sub('\n$', '', block)
data = re.sub('(\n(?:> ?(?:(?:(?!\n).)+)?\n)+)', '\n
' + block + '
\n', data, 1)
else:
break
data = re.sub('(?P\n +\* ?(?:(?:(?!\|\|).)+))\|\|', '\g\n ||', data)
# 리스트 구현
while 1:
li = re.search('(\n(?:(?: *)\* ?(?:(?:(?!\n).)+)\n)+)', data)
if li:
li = li.groups()[0]
while 1:
sub_li = re.search('\n(?:( *)\* ?((?:(?!\n).)+))', li)
if sub_li:
sub_li = sub_li.groups()
# 앞의 공백 만큼 margin 먹임
if len(sub_li[0]) == 0:
margin = 20
else:
margin = len(sub_li[0]) * 20
li = re.sub('\n(?:( *)\* ?((?:(?!\n).)+))', '
':
footdata_all = ''
data = re.sub('\n$', footdata_all, data + '\n', 1)
# 분류 마지막 처리
category += '
'
category = re.sub(' / <\/div>$', '
', category)
if category == '\n
Category :
':
category = ''
data += category
# NoWiki 마지막 처리
i = 0
while 1:
try:
_ = end_data[i][0]
except:
break
if end_data[i][2] == 'normal':
data = data.replace('', end_data[i][1])
data = data.replace(tool.url_pas(''), tool.url_pas(end_data[i][1]))
else:
if re.search('\n', end_data[i][1]):
data = data.replace('', '\n
' + re.sub('^\n', '', end_data[i][1]) + '
')
else:
data = data.replace('', '' + end_data[i][1] + '')
i += 1
if main_num == 1:
# 역링크에도
i = 0
while 1:
try:
_ = backlink[i][0]
except:
break
find_data = re.search('', backlink[i][1])
if find_data:
j = 0
find_data = find_data.groups()[0]
while 1:
try:
_ = end_data[j][0]
except:
break
if end_data[j][0] == find_data:
backlink[i][1] = backlink[i][1].replace('', end_data[j][1])
j += 1
i += 1
# 마지막 처리
data = re.sub('<\/td_end>', '
', data)
data = re.sub('\n', '', data)
data = re.sub('\n<\/include>', '', data)
data = re.sub('(?P<\/h[0-9]>)(\n)+', '\g', data)
data = re.sub('\n\n
', '\n
', data)
data = re.sub('<\/ul>\n\n', '
\n', data)
data = re.sub('^(\n)+', '', data)
data = re.sub('(\n)+
', '
', data)
data = re.sub('(?P
).)*)>)\n', '\g', data)
data = re.sub('(\n)?(\n)?', '', data)
data = re.sub('<\/ul>\n\n