[文档]deftable(state:StateBlock,startLine:int,endLine:int,silent:bool):tbodyLines=None# should have at least two linesifstartLine+2>endLine:returnFalsenextLine=startLine+1ifstate.sCount[nextLine]<state.blkIndent:returnFalse# if it's indented more than 3 spaces, it should be a code blockifstate.sCount[nextLine]-state.blkIndent>=4:returnFalse# first character of the second line should be '|', '-', ':',# and no other characters are allowed but spaces;# basically, this is the equivalent of /^[-:|][-:|\s]*$/ regexppos=state.bMarks[nextLine]+state.tShift[nextLine]ifpos>=state.eMarks[nextLine]:returnFalsefirst_ch=state.srcCharCode[pos]pos+=1iffirst_chnotin{0x7C,0x2D,0x3A}:# not in {"|", "-", ":"}returnFalseifpos>=state.eMarks[nextLine]:returnFalsesecond_ch=state.srcCharCode[pos]pos+=1# not in {"|", "-", ":"} and not spaceifsecond_chnotin{0x7C,0x2D,0x3A}andnotisSpace(second_ch):returnFalse# if first character is '-', then second character must not be a space# (due to parsing ambiguity with list)iffirst_ch==0x2DandisSpace(second_ch):returnFalsewhilepos<state.eMarks[nextLine]:ch=state.srcCharCode[pos]# /* | */ /* - */ /* : */ifchnotin{0x7C,0x2D,0x3A}andnotisSpace(ch):returnFalsepos+=1lineText=getLine(state,startLine+1)columns=lineText.split("|")aligns=[]foriinrange(len(columns)):t=columns[i].strip()ifnott:# allow empty columns before and after table, but not in between columns;# e.g. allow ` |---| `, disallow ` ---||--- `ifi==0ori==len(columns)-1:continueelse:returnFalseifnotheaderLineRe.search(t):returnFalseifcharCodeAt(t,len(t)-1)==0x3A:# /* : */# /* : */aligns.append("center"ifcharCodeAt(t,0)==0x3Aelse"right")elifcharCodeAt(t,0)==0x3A:# /* : */aligns.append("left")else:aligns.append("")lineText=getLine(state,startLine).strip()if"|"notinlineText:returnFalseifstate.sCount[startLine]-state.blkIndent>=4:returnFalsecolumns=escapedSplit(lineText)ifcolumnsandcolumns[0]=="":columns.pop(0)ifcolumnsandcolumns[-1]=="":columns.pop()# header row will define an amount of columns in the entire table,# and align row should be exactly the same (the rest of the rows can differ)columnCount=len(columns)ifcolumnCount==0orcolumnCount!=len(aligns):returnFalseifsilent:returnTrueoldParentType=state.parentTypestate.parentType="table"# use 'blockquote' lists for termination because it's# the most similar to tablesterminatorRules=state.md.block.ruler.getRules("blockquote")token=state.push("table_open","table",1)token.map=tableLines=[startLine,0]token=state.push("thead_open","thead",1)token.map=[startLine,startLine+1]token=state.push("tr_open","tr",1)token.map=[startLine,startLine+1]foriinrange(len(columns)):token=state.push("th_open","th",1)ifaligns[i]:token.attrs={"style":"text-align:"+aligns[i]}token=state.push("inline","",0)# note in markdown-it this map was removed in v12.0.0 however, we keep it,# since it is helpful to propagate to children tokenstoken.map=[startLine,startLine+1]token.content=columns[i].strip()token.children=[]token=state.push("th_close","th",-1)token=state.push("tr_close","tr",-1)token=state.push("thead_close","thead",-1)nextLine=startLine+2whilenextLine<endLine:ifstate.sCount[nextLine]<state.blkIndent:breakterminate=Falseforiinrange(len(terminatorRules)):ifterminatorRules[i](state,nextLine,endLine,True):terminate=Truebreakifterminate:breaklineText=getLine(state,nextLine).strip()ifnotlineText:breakifstate.sCount[nextLine]-state.blkIndent>=4:breakcolumns=escapedSplit(lineText)ifcolumnsandcolumns[0]=="":columns.pop(0)ifcolumnsandcolumns[-1]=="":columns.pop()ifnextLine==startLine+2:token=state.push("tbody_open","tbody",1)token.map=tbodyLines=[startLine+2,0]token=state.push("tr_open","tr",1)token.map=[nextLine,nextLine+1]foriinrange(columnCount):token=state.push("td_open","td",1)ifaligns[i]:token.attrs={"style":"text-align:"+aligns[i]}token=state.push("inline","",0)# note in markdown-it this map was removed in v12.0.0 however, we keep it,# since it is helpful to propagate to children tokenstoken.map=[nextLine,nextLine+1]try:token.content=columns[i].strip()ifcolumns[i]else""exceptIndexError:token.content=""token.children=[]token=state.push("td_close","td",-1)token=state.push("tr_close","tr",-1)nextLine+=1iftbodyLines:token=state.push("tbody_close","tbody",-1)tbodyLines[1]=nextLinetoken=state.push("table_close","table",-1)tableLines[1]=nextLinestate.parentType=oldParentTypestate.line=nextLinereturnTrue