[文档]deffence(state:StateBlock,startLine:int,endLine:int,silent:bool):LOGGER.debug("entering fence: %s, %s, %s, %s",state,startLine,endLine,silent)haveEndMarker=Falsepos=state.bMarks[startLine]+state.tShift[startLine]maximum=state.eMarks[startLine]# if it's indented more than 3 spaces, it should be a code blockifstate.sCount[startLine]-state.blkIndent>=4:returnFalseifpos+3>maximum:returnFalsemarker=state.srcCharCode[pos]# /* ~ */ /* ` */ifmarker!=0x7Eandmarker!=0x60:returnFalse# scan marker lengthmem=pospos=state.skipChars(pos,marker)length=pos-memiflength<3:returnFalsemarkup=state.src[mem:pos]params=state.src[pos:maximum]# /* ` */ifmarker==0x60:ifchr(marker)inparams:returnFalse# Since start is found, we can report success here in validation modeifsilent:returnTrue# search end of blocknextLine=startLinewhileTrue:nextLine+=1ifnextLine>=endLine:# unclosed block should be autoclosed by end of document.# also block seems to be autoclosed by end of parentbreakpos=mem=state.bMarks[nextLine]+state.tShift[nextLine]maximum=state.eMarks[nextLine]ifpos<maximumandstate.sCount[nextLine]<state.blkIndent:# non-empty line with negative indent should stop the list:# - ```# testbreakifstate.srcCharCode[pos]!=marker:continueifstate.sCount[nextLine]-state.blkIndent>=4:# closing fence should be indented less than 4 spacescontinuepos=state.skipChars(pos,marker)# closing code fence must be at least as long as the opening oneifpos-mem<length:continue# make sure tail has spaces onlypos=state.skipSpaces(pos)ifpos<maximum:continuehaveEndMarker=True# found!break# If a fence has heading spaces, they should be removed from its inner blocklength=state.sCount[startLine]state.line=nextLine+(1ifhaveEndMarkerelse0)token=state.push("fence","code",0)token.info=stripEscape(params)token.content=state.getLines(startLine+1,nextLine,length,True)token.markup=markuptoken.map=[startLine,state.line]returnTrue