# 冠亞軍賽 Last Encore {%youtube 0-H4Bobp8FI %} > 本次上場的怪獸表格下收 > 這裡的表格是電腦生成的,抓取YGO-Pro 的card.cdb 資料庫,詳細請看下面 ## 游矢 |卡名|卡圖 |效果說明 |ID | | - | - | - | - | |EM橡皮羊|![](https://i.imgur.com/iVATqBx.jpg)|←1 【靈擺】 1→<br/>①:1回合1次,我方怪獸和對方怪獸進行戰鬥的攻擊宣言時可以發動。該我方怪獸不會被該次戰鬥破壞。<br/>【怪獸效果】<br/>①:1回合1次,我方怪獸和對方怪獸進行戰鬥的攻擊宣言時可以發動。該我方怪獸不會被該次戰鬥破壞。|8384771| |EM骷髏雜技小丑|![](https://i.imgur.com/STHKZS5.jpg)|①:我方僅能靈擺召喚「EM」怪獸﹒「魔術師」怪獸﹒「異色眼」怪獸以外的怪獸。此效果不會被無效化。<br/>【怪獸效果】<br/>①:此卡召喚成功時可以發動。從牌組將此卡名以外的「EM」怪獸﹒「魔術師」怪獸﹒「異色眼」怪獸中選擇1張加入手牌。|40318957| |EM異色眼獨角獸|![](https://i.imgur.com/eF6yrpY.jpg)|←8 【靈擺】 8→<br/>①:此卡於靈擺區存在僅1次,我方的「異色眼」怪獸的攻擊宣言時,可以選擇該怪獸以外我方場上1體「EM」怪獸來發動。到戰鬥階段結束以前該攻擊怪獸的攻擊力上升對象怪獸的原攻擊力數值。<br/>【怪獸效果】<br/>①:此卡召喚﹒特殊召喚成功時,可以選擇我方墓地1體「EM」怪獸為對象發動。我方生命值回復該怪獸的攻擊力數值。|86157908| |EM猛薔薇巴拉庫達|![](https://i.imgur.com/zkW4ZTp.jpg)|①:1回合1次,我方的「EM」怪獸和對方怪獸進行戰鬥的傷害計算前可以發動。<br/>該對方怪獸的攻擊力下降和原攻擊力的差值。<br/>【怪獸效果】<br/>此卡名的①怪獸效果1回合僅能使用1次。<br/>①:可以1體攻擊力和原攻擊力相異的「EM」怪獸為對象發動。到回合結束以前該怪獸的攻擊力上升和原攻擊力的差值。此效果也可以在對方回合發動。 |92767273| |EM靈擺魔術家|![](https://i.imgur.com/GNI1Uh3.jpg)|①:「EM」怪獸靈擺召喚到我方場上的場合發動。我方場上的「EM」怪獸的攻擊力到回合結束時為止上升1000。<br/>【怪獸效果】<br/>此卡名的①效果①回合僅能使用1次。<br/>①:此卡特殊召喚成功的場合,以我方場上最多2張卡為對象才能發動。破壞那些卡,從牌組將此卡名以外破壞的張數的「EM」怪獸加入手牌(同名卡最多1張)。|47075569| |異色眼之龍|![](https://i.imgur.com/GvaCy0f.jpg)|①:此卡以戰鬥將對方怪獸破壞送入墓地的場合發動。給予對方該怪獸原攻擊力一半的傷害。|53025096| |EM撲克女孩|![](https://i.imgur.com/CSHfrv4.jpg)|←4 【靈擺】 4→<br/>【怪獸效果】<br/>①:1回合1次,我方的主要階段時可以發動。<br/>從我方場上將包含此卡的融合怪獸卡上決定的融合素材怪獸送入墓地,從額外牌組將該1體融合怪獸融合召喚。<br/>②:此卡從靈擺區被破壞的場合,可以我方墓地1體龍族融合怪獸為對象發動。該怪獸特殊召喚。以此效果特殊召喚的怪獸在結束階段時破壞。|42002073| |EM搭檔蛇|![](https://i.imgur.com/E4wh8i9.jpg)|←3 【靈擺】 3→<br/>①:1回合1次,以我方場上的1體怪獸為對象才能發動。該怪獸的攻擊力到回合結束時為止上升我方場上的「EM」卡片數量×300。<br/>【怪獸效果】<br/>①:此卡召喚﹒特殊召喚成功的場合,以我方場上的1體怪獸為對象才能發動。該怪獸的攻擊力上升我方場上的「EM」怪獸數量×300。<br/>②:此卡在怪獸區存在為限,等級5以下的怪獸不能攻擊。 |69211541| |EM融合石魔|![](https://i.imgur.com/SUe6qYD.jpg)|←1 【靈擺】 1→<br/>①:1回合1次,我方場上有融合怪獸融合召喚的場合可以發動。從我方墓地的靈擺怪獸或我方額外牌組表側表示的靈擺怪獸之中選擇「EM」怪獸﹒「魔術師」怪獸﹒「異色眼」怪獸其中1張加入手牌。<br/>【怪獸效果】<br/>①:此卡靈擺召喚的回合的主要階段時可以發動從我方場上包含此卡的融合怪獸卡決定的融合素材怪獸送入墓地,從額外牌組將該1體融合怪獸融合召喚。此時,其他融合素材怪獸僅能為龍族怪獸。|73511233| |飢餓毒液融合龍|![](https://i.imgur.com/ADub4Hl.jpg)|衍生物以外場上的闇屬性怪獸二體<br/>①:此卡融合召喚成功的場合可以發動。選擇對方場上1體特殊召喚出場的怪獸,到回合結束以前此卡的攻擊力上升該攻擊力數值。<br/>②:1回合1次,可以選擇對方場上1體等級5以上的怪獸為對象發動。到回合結束以前,此卡視為該怪獸的同名卡片,得到相同效果。<br/>③:融合召喚出場的此卡被破壞的場合可以發動。對方場上所有特殊召喚出場的怪獸破壞。 |41209827| |EM雅薔薇巴拉德|![](https://i.imgur.com/1WPHprQ.jpg)|①:1回合1次,我方的「EM」怪獸和對方的表側表示怪獸進行戰鬥的傷害步驟開始時可以發動。該對方怪獸的攻擊力下降600。<br/>【怪獸效果】<br/>①:我方的「EM」怪獸進行攻擊的傷害計算以後,可以選擇對方場上1體表側表示怪獸為對象發動。該對方怪獸的攻擊力下降該「EM」怪獸的攻擊力數值。|66768175| ## 零兒 |卡名|卡圖 |效果說明 |ID | | - | - | - | - | |DD 螺渦史萊姆|![](https://i.imgur.com/gzq0poe.jpg)|「DD 螺渦史萊姆」的①②效果1回合各能使用1次。<br/>①:此卡在手牌存在的場合,我方主要階段才能發動。「DDD」融合怪獸卡決定的包含此卡的融合素材怪獸從手牌送去墓地,把那1體融合怪獸從額外牌組融合召喚。<br/>②:把墓地的此卡除外才能發動。從手牌把1體「DD」怪獸特殊召喚。|45206713| |DD 拉米亞|![](https://i.imgur.com/Yh8b5Z1.jpg)|此卡名的效果1回合只能使用1次。<br/>①:此卡在手牌﹒墓地存在的場合,從手牌以及我方場上的表側表示的卡之中把「DD 拉米亞」以外的1張「DD」卡或「契約書」卡送去墓地才能發動。此卡特殊召喚。這個效果特殊召喚的此卡從場上離開的場合除外。|19580308| |DDD烈火王 鐵木真|![](https://i.imgur.com/62VnLNF.jpg)|「DD」怪獸2體<br/>此卡名的①效果1回合僅能使用1次。<br/>①:此卡於怪獸區存在,我方場上除此卡以外有「DD」怪獸特殊召喚的場合,可以我方墓地1體「DD」怪獸為對象發動。該怪獸特殊召喚。<br/>②:此卡被戰鬥或對方的卡片效果破壞的場合,可以我方墓地1張「契約書」卡片為對象發動。該卡片加入手牌。 |74583607| |DD魔導賢者 哥白尼|![](https://i.imgur.com/aJ8hCS6.jpg)|←1 【靈擺】 1→<br/>①:我方不是「DD」怪獸不能靈擺召喚。這個效果不會被無效化。<br/>②:只在此卡在靈擺區存在才有一次,給予我方傷害的魔法卡的效果發動的場合,可以把那個效果無效。那之後,此卡破壞。<br/>【怪獸效果】<br/>「DD魔導賢者 哥白尼」的怪獸效果1回合1次。<br/>①:此卡召喚﹒特殊召喚成功的場合才能發動。從牌組把「DD魔導賢者 哥白尼」以外的1張「DD」卡片或「契約書」卡片送入墓地。|46796664| |DD 亡靈史萊姆|![](https://i.imgur.com/B13p7oi.jpg)|此卡名的效果①1回合只能使用1次。<br/>①:此卡在墓地存在的場合可以發動。將「DDD」融合怪獸卡決定的包含此卡的融合素材怪獸從我方的墓地除外,從額外牌組融合召喚那1體融合怪獸。|72291412| |DDD疾風王 亞歷山大|![](https://i.imgur.com/sVk9nIX.jpg)|「DD」協調+協調以外的怪獸一體以上<br/>此卡名的①效果1回合僅能使用1次。<br/>①:此卡在怪獸區存在,我方場上除此卡以外有「DD」怪獸召喚﹒特殊召喚的場合,可以以我方墓地1體等級4以下的「DD」怪獸為對象發動。該怪獸特殊召喚。|987311| |DDD剋龍王 貝奧武夫|![](https://i.imgur.com/bj9lTyR.jpg)|「DDD」怪獸+「DD」怪獸<br/>①:只要此卡在怪獸區存在,我方的「DD」怪獸向守備表示怪獸攻擊的場合,給予對方為攻擊力超過那個守備力的數值的戰鬥傷害。<br/>②:我方準備階段才能發動。雙方的魔法陷阱區的卡片全部破壞。|8463720| |魔神王的契約書|![](https://i.imgur.com/iYOxL45.jpg)|「魔神王的契約書」的①效果1回合只能發動1次。<br/>①:我方主要階段時可以發動。將我方手牌.場上,融合怪獸卡上決定的融合素材怪獸送入墓地。之後從額外牌組當作融合召喚特殊召喚該1體惡魔族融合怪獸。若融合召喚「DD」融合怪獸,可以除外我方墓地的怪獸當作融合素材。<br/>②:我方準備階段時發動。我方受到1000傷害。|73360025| |DDD神托王 貞德|![](https://i.imgur.com/cLBbzvN.jpg)|「DD」怪獸2體<br/>①:此卡於怪獸區存在為限,給予我方生命值傷害的卡片效果變為回復我方生命值的卡片效果。|82956492| |DD魔導賢者 克卜勒|![](https://i.imgur.com/aC1AijV.jpg)|←10 【靈擺】 10→<br/>①:我方僅能靈擺召喚「DD」怪獸。此效果不會被無效化。<br/>②:我方的準備階段時發動。此卡的靈擺刻度下降2(最少到1)。之後,我方場上除「DD」怪獸以外等級在此卡的靈擺刻度以上的所有怪獸破壞。<br/>【怪獸效果】<br/>「DD魔導賢者 克卜勒」的怪獸效果1回合僅能使用1次。 此卡召喚﹒特殊召喚成功的場合,可以從以下效果選擇1個發動。<br/>●可以除此卡以外我方場上1張「DD」卡片為對象發動。該卡片回到持有者手牌。<br/>●從牌組將1張「契約書」卡片加入手牌。|11609969| # 後記 總之原本只是單純的決鬥構成,卻好像又生出了兩個程式碼,可以協助整理ydk 與 卡片ID 如果有人會python 就拿來用吧 ## 卡牌ID 整理器 ### 功能 1. 輸入ID 2. 自動上傳卡圖到imgur 3. 整理出markdown 表格方便分享 ### 使用重點 1. 記得把python 的workingspace 設定在跟YGOPro_test.exe 同個資料夾 2. Markdown 檔案放在跟YGOPro_test.exe 同個資料夾,才能看到圖片 3. 手動輸入cardlist ## 整理出純表格 ```python # -*- coding: UTF-8 -*- """ Spyder Editor This is a temporary script file. """ import sqlite3 conn = sqlite3.connect('cards.cdb') c = conn.cursor() cardlist = ['8384771','40318957','86157908','92767273', '47075569','53025096','42002073','69211541', '73511233','41209827','66768175'] cardlist2 = ['45206713','19580308','74583607','46796664', '72291412','987311','8463720','73360025', '82956492','11609969'] import codecs with codecs.open('card_desc_pics.md','w',encoding='utf8') as f: f.write(u'''# 冠亞軍賽 Last Encho ## 游矢 |卡名|卡圖 |效果說明 |ID | | - | - | - | - | ''') for card in cardlist: c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(card)) (name,desc) = c.fetchone() f.write(u'''|{0}|![](./pics/{2}.jpg)|{1}|{2}|\r\n'''.format(name,desc.replace('\r\n','<br/>'),card)) f.write(u''' ## 零兒 |卡名|卡圖 |效果說明 |ID | | - | - | - | - | ''') for card in cardlist2: c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(card)) (name,desc) = c.fetchone() f.write(u'''|{0}|![](./pics/{2}.jpg)|{1}|{2}|\r\n'''.format(name,desc.replace('\r\n','<br/>'),card)) f.close() c.close ``` ## imgur client 需要申請client id https://apidocs.imgur.com/#intro ```python import requests headers = { 'Authorization': "Client-ID {ClientID}" } url = "https://api.imgur.com/3/image" payload = open('./pics/42002073.jpg','rb') response = requests.request("POST", url, files={'image':(None, payload),'album':(None, '{ablumDeleteHash}')},headers=headers) print(response.json()[u'data']) ``` ## 整合自動上傳的 ### 使用重點 1. 記得把python 的workingspace 設定在跟YGOPro_test.exe 同個資料夾 2. 手動輸入cardlist 3. **記得替換掉{ClientID} 與 {ablumDeleteHash}** ```python # -*- coding: UTF-8 -*- """ Spyder Editor This is a temporary script file. """ import requests headers = {'Authorization': "Client-ID {ClientID}"} url = "https://api.imgur.com/3/image" import sqlite3 conn = sqlite3.connect('cards.cdb') c = conn.cursor() cardlist = ['8384771','40318957','86157908','92767273', '47075569','53025096','42002073','69211541', '73511233','41209827','66768175'] cardlist2 = ['45206713','19580308','74583607','46796664', '72291412','987311','8463720','73360025', '82956492','11609969'] import codecs with codecs.open('card_desc_pics.md','w',encoding='utf8') as f: f.write(u'''# 冠亞軍賽 Last Encho ## 游矢 |卡名|卡圖 |效果說明 |ID | | - | - | - | - | ''') for card in cardlist: c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(card)) (name,desc) = c.fetchone() payload = open('./pics/{0}.jpg'.format(card),'rb') response = requests.request("POST", url, files={'image':(None, payload),'album':(None, '{ablumDeleteHash}')},headers=headers) f.write(u'''|{0}|![]({3})|{1}|{2}|\r\n'''.format(name,desc.replace('\r\n','<br/>'),card,response.json()[u'data'][u'link'])) f.write(u''' ## 零兒 |卡名|卡圖 |效果說明 |ID | | - | - | - | - | ''') for card in cardlist2: c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(card)) (name,desc) = c.fetchone() payload = open('./pics/{0}.jpg'.format(card),'rb') response = requests.request("POST", url, files={'image':(None, payload),'album':(None, '{ablumDeleteHash}')},headers=headers) f.write(u'''|{0}|![]({3})|{1}|{2}|\r\n'''.format(name,desc.replace('\r\n','<br/>'),card,response.json()[u'data'][u'link'])) f.close() c.close ``` 記得加上 ```htmlmixed <style> .markdown-body img{ max-width: 200px; } </style> ``` <style> .markdown-body img{ max-width: 200px; } </style> # 延伸程式 ## ydk 排版程式 將這個python 放在YGOPro_test.exe 同一個資料夾 就可以產生出local 用的markdown ```python # -*- coding: UTF-8 -*- from Tkinter import Tk from tkinter.filedialog import askopenfilename root = Tk() root.withdraw() # we don't want a full GUI, so keep the root window from appearing root.focus_force() ydkfilename = askopenfilename(parent=root,filetypes=[('牌組', '.ydk')], title=u'選擇牌組開啟',initialdir="./deck") # show an "Open" dialog box and return the path to the selected file #cdbfilename = askopenfilename(parent=root,filetypes=[('牌組資料庫', '.cdb')], # title=u'選擇牌組資料庫開啟') # show an "Open" dialog box and return the path to the selected file ydkFile = open(ydkfilename,'r'); deckText = ydkFile.read() ydkFile.close() main = deckText.split('!')[0].split('#')[2] extra = deckText.split('!')[0].split('#')[3] side = deckText.split('!')[1] import re mainCardList = sorted(re.findall(r'(\d+)', main)) extraCardList = sorted(re.findall(r'(\d+)', extra)) sideCardList = sorted(re.findall(r'(\d+)', side)) import codecs f = codecs.open('{0}.md'.format(ydkfilename.split('/')[-1][:-4]),'w',encoding='utf8') import sqlite3 conn = sqlite3.connect('cards.cdb') c = conn.cursor() if len(mainCardList) > 0: f.write(u'''# 主要牌組 |卡名|卡圖 |數量 |ID |卡片效果| | - | - | - | - | - | ''') lastCard = ''; counter = 1; for card in mainCardList: if(card == lastCard): counter = counter + 1 else: if(lastCard != ''): c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"./pics/{0}.jpg".format(lastCard),desc.replace('\r\n','<br/>'))) lastCard = card counter = 1 c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"./pics/{0}.jpg".format(lastCard),desc.replace('\r\n','<br/>'))) if len(extraCardList) > 0: f.write(u'''# 額外牌組 |卡名|卡圖 |數量 |ID |卡片效果| | - | - | - | - | - | ''') lastCard = ''; counter = 1; for card in extraCardList: if(card == lastCard): counter = counter + 1 else: if(lastCard != ''): c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"./pics/{0}.jpg".format(lastCard),desc.replace('\r\n','<br/>'))) lastCard = card counter = 1 c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"./pics/{0}.jpg".format(lastCard),desc.replace('\r\n','<br/>'))) if len(sideCardList) > 0: f.write(u'''# 備用牌組 |卡名|卡圖 |數量 |ID |卡片效果| | - | - | - | - | - | ''') lastCard = ''; counter = 1; for card in sideCardList: if(card == lastCard): counter = counter + 1 else: if(lastCard != ''): c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"./pics/{0}.jpg".format(lastCard),desc.replace('\r\n','<br/>'))) lastCard = card counter = 1 c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"./pics/{0}.jpg".format(lastCard),desc.replace('\r\n','<br/>'))) c.close() f.close() root.destroy() ``` ## 排版程式2 可以將ydk 轉出html css from:https://gist.github.com/andyferra/2554919 ```python # -*- coding: UTF-8 -*- import markdown import sys reload(sys) sys.setdefaultencoding('utf8') def md2html(mdstr): exts = ['markdown.extensions.nl2br','markdown.extensions.extra', 'markdown.extensions.codehilite','markdown.extensions.tables','markdown.extensions.toc'] html = ''' <html lang="zh-tw"> <head> <meta content="text/html; charset=utf-8" http-equiv="content-type" /> <style> body{font-family:Helvetica,arial,sans-serif;font-size:14px;line-height:1.6;padding-top:10px;padding-bottom:10px;background-color:white;padding:30px}body>*:first-child{margin-top:0!important}body>*:last-child{margin-bottom:0!important}a{color:#4183C4}a.absent{color:#cc0000}a.anchor{display:block;padding-left:30px;margin-left:-30px;cursor:pointer;position:absolute;top:0;left:0;bottom:0}h1,h2,h3,h4,h5,h6{margin:20px 0 10px;padding:0;font-weight:bold;-webkit-font-smoothing:antialiased;cursor:text;position:relative}h1:hover a.anchor,h2:hover a.anchor,h3:hover a.anchor,h4:hover a.anchor,h5:hover a.anchor,h6:hover a.anchor{background:url("../../images/modules/styleguide/para.png") no-repeat 10px center;text-decoration:none}h1 tt,h1 code{font-size:inherit}h2 tt,h2 code{font-size:inherit}h3 tt,h3 code{font-size:inherit}h4 tt,h4 code{font-size:inherit}h5 tt,h5 code{font-size:inherit}h6 tt,h6 code{font-size:inherit}h1{font-size:28px;color:black}h2{font-size:24px;border-bottom:1px solid #cccccc;color:black}h3{font-size:18px}h4{font-size:16px}h5{font-size:14px}h6{color:#777777;font-size:14px}p,blockquote,ul,ol,dl,li,table,pre{margin:15px 0}hr{background:transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0;border:0 none;color:#cccccc;height:4px;padding:0}body>h2:first-child{margin-top:0;padding-top:0}body>h1:first-child{margin-top:0;padding-top:0}body>h1:first-child+h2{margin-top:0;padding-top:0}body>h3:first-child,body>h4:first-child,body>h5:first-child,body>h6:first-child{margin-top:0;padding-top:0}a:first-child h1,a:first-child h2,a:first-child h3,a:first-child h4,a:first-child h5,a:first-child h6{margin-top:0;padding-top:0}h1 p,h2 p,h3 p,h4 p,h5 p,h6 p{margin-top:0}li p.first{display:inline-block}ul,ol{padding-left:30px}ul :first-child,ol :first-child{margin-top:0}ul :last-child,ol :last-child{margin-bottom:0}dl{padding:0}dl dt{font-size:14px;font-weight:bold;font-style:italic;padding:0;margin:15px 0 5px}dl dt:first-child{padding:0}dl dt>:first-child{margin-top:0}dl dt>:last-child{margin-bottom:0}dl dd{margin:0 0 15px;padding:0 15px}dl dd>:first-child{margin-top:0}dl dd>:last-child{margin-bottom:0}blockquote{border-left:4px solid #dddddd;padding:0 15px;color:#777777}blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}table{padding:0}table tr{border-top:1px solid #cccccc;background-color:white;margin:0;padding:0}table tr:nth-child(2n){background-color:#f8f8f8}table tr th{font-weight:bold;border:1px solid #cccccc;text-align:left;margin:0;padding:6px 13px}table tr td{border:1px solid #cccccc;text-align:left;margin:0;padding:6px 13px}table tr th :first-child,table tr td :first-child{margin-top:0}table tr th :last-child,table tr td :last-child{margin-bottom:0}img{max-width:100%}span.frame{display:block;overflow:hidden}span.frame>span{border:1px solid #dddddd;display:block;float:left;overflow:hidden;margin:13px 0 0;padding:7px;width:auto}span.frame span img{display:block;float:left}span.frame span span{clear:both;color:#333333;display:block;padding:5px 0 0}span.align-center{display:block;overflow:hidden;clear:both}span.align-center>span{display:block;overflow:hidden;margin:13px auto 0;text-align:center}span.align-center span img{margin:0 auto;text-align:center}span.align-right{display:block;overflow:hidden;clear:both}span.align-right>span{display:block;overflow:hidden;margin:13px 0 0;text-align:right}span.align-right span img{margin:0;text-align:right}span.float-left{display:block;margin-right:13px;overflow:hidden;float:left}span.float-left span{margin:13px 0 0}span.float-right{display:block;margin-left:13px;overflow:hidden;float:right}span.float-right>span{display:block;overflow:hidden;margin:13px auto 0;text-align:right}code,tt{margin:0 2px;padding:0 5px;white-space:nowrap;border:1px solid #eaeaea;background-color:#f8f8f8;border-radius:3px}pre code{margin:0;padding:0;white-space:pre;border:none;background:transparent}.highlight pre{background-color:#f8f8f8;border:1px solid #cccccc;font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px}pre{background-color:#f8f8f8;border:1px solid #cccccc;font-size:13px;line-height:19px;overflow:auto;padding:6px 10px;border-radius:3px}pre code,pre tt{background-color:transparent;border:none} </style> '''+''' <style> img{ max-width: 200px; } </style> </head> <body> %s </body> </html> ''' % (markdown.markdown(mdstr,extensions=exts)) return html from Tkinter import Tk from tkinter.filedialog import askopenfilename root = Tk() root.withdraw() # we don't want a full GUI, so keep the root window from appearing root.focus_force() cdbfilename = askopenfilename(parent=root,filetypes=[('牌組資料庫', '.cdb')], title=u'選擇牌組資料庫開啟') # show an "Open" dialog box and return the path to the selected file mainPath = '/'.join(cdbfilename.split('/')[:-1]) ydkfilename = askopenfilename(parent=root,filetypes=[('牌組', '.ydk')], title=u'選擇牌組開啟',initialdir=mainPath+"/deck") # show an "Open" dialog box and return the path to the selected file ydkFile = open(ydkfilename,'r'); deckText = ydkFile.read() ydkFile.close() main = deckText.split('!')[0].split('#')[2] extra = deckText.split('!')[0].split('#')[3] side = deckText.split('!')[1] import re mainCardList = sorted(re.findall(r'(\d+)', main)) extraCardList = sorted(re.findall(r'(\d+)', extra)) sideCardList = sorted(re.findall(r'(\d+)', side)) import codecs f = codecs.open('{0}.md'.format(ydkfilename.split('/')[-1][:-4]),'w',encoding='utf8') import sqlite3 conn = sqlite3.connect(cdbfilename) c = conn.cursor() if len(mainCardList) > 0: f.write(u'''# 主要牌組 |卡名|卡圖 |數量 |ID |卡片效果| | - | - | - | - | - | ''') lastCard = ''; counter = 1; for card in mainCardList: if(card == lastCard): counter = counter + 1 else: if(lastCard != ''): c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"{1}/pics/{0}.jpg".format(lastCard,mainPath),desc.replace('\r\n','<br/>'))) lastCard = card counter = 1 c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"{1}/pics/{0}.jpg".format(lastCard,mainPath),desc.replace('\r\n','<br/>'))) if len(extraCardList) > 0: f.write(u''' # 額外牌組 |卡名|卡圖 |數量 |ID |卡片效果| | - | - | - | - | - | ''') lastCard = ''; counter = 1; for card in extraCardList: if(card == lastCard): counter = counter + 1 else: if(lastCard != ''): c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"{1}/pics/{0}.jpg".format(lastCard,mainPath),desc.replace('\r\n','<br/>'))) lastCard = card counter = 1 c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"{1}/pics/{0}.jpg".format(lastCard,mainPath),desc.replace('\r\n','<br/>'))) if len(sideCardList) > 0: f.write(u''' # 備用牌組 |卡名|卡圖 |數量 |ID |卡片效果| | - | - | - | - | - | ''') lastCard = ''; counter = 1; for card in sideCardList: if(card == lastCard): counter = counter + 1 else: if(lastCard != ''): c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"{1}/pics/{0}.jpg".format(lastCard,mainPath),desc.replace('\r\n','<br/>'))) lastCard = card counter = 1 c.execute(''' SELECT `name`,`desc` FROM `texts` WHERE `id` = "{0}" '''.format(lastCard)) (name,desc) = c.fetchone() f.write(u'''|{0}|![]({3})|{1}|{2}|{4}|\r\n'''.format(name,counter,lastCard,u"{1}/pics/{0}.jpg".format(lastCard,mainPath),desc.replace('\r\n','<br/>'))) c.close() f.close() root.destroy() f = codecs.open('{0}.md'.format(ydkfilename.split('/')[-1][:-4]),'r',encoding='utf8') md = f.read() f.close() print("Open") of = codecs.open('{0}.html'.format(ydkfilename.split('/')[-1][:-4]),'w',encoding='utf8') of.write(md2html(md)) of.close() print("Done") ```