SUBROUTINE RENDER.MARKDOWN(MARKDOWN,HTML)
*
GIT.FILENAME = 'RENDER.MARKDOWN'
GIT.REPO = 'https://github.com/Krowemoh/TCL-Utilities.git'
*
EQU TRUE TO 1
EQU FALSE TO 0
*
HTML = ''
*
MARKDOWN = CHANGE(MARKDOWN,CHAR(10),@AM)
NUMBER.OF.LINES = DCOUNT(MARKDOWN,@AM)
*
BLOCK = ''
BLOCK.TYPE = 'PARAGRAPH'
*
FOR I = 1 TO NUMBER.OF.LINES
LINE = MARKDOWN
*
IF LINE = '' OR TRIM(LINE) = '' THEN
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
BLOCK.TYPE = 'PARAGRAPH'
*
END ELSE IF LINE[1,3] = '```' THEN
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
*
BLOCK.TYPE = 'CODE'
*
LOOP
I = I + 1
LINE = MARKDOWN
UNTIL LINE = '```' OR I > NUMBER.OF.LINES DO
BLOCK = BLOCK : LINE : CHAR(10)
REPEAT
*
GOSUB BUILD.BLOCK
*
END ELSE IF LINE[1,6] = '' THEN
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
*
BLOCK.TYPE = 'HTML'
*
LOOP
I = I + 1
LINE = MARKDOWN
UNTIL LINE = '' OR I > NUMBER.OF.LINES DO
BLOCK = BLOCK : LINE : CHAR(10)
REPEAT
*
GOSUB BUILD.BLOCK
*
END ELSE IF LINE[1,4] = SPACE(4) THEN
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
*
BLOCK.TYPE = 'CODE'
*
BLOCK = BLOCK : LINE[5,9999] : CHAR(10)
*
LOOP
I = I + 1
LINE = MARKDOWN
UNTIL LINE[1,4] # SPACE(4) OR I > NUMBER.OF.LINES DO
BLOCK = BLOCK : LINE[5,9999] : CHAR(10)
REPEAT
*
GOSUB BUILD.BLOCK
I = I - 1
*
END ELSE IF LINE MATCHES "> 0X" THEN
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
*
BLOCK.TYPE = 'BLOCKQUOTE'
*
IF LINE[1,2] = '> ' THEN
LINE = TRIM(LINE[3,9999])
END
BLOCK = BLOCK : LINE : CHAR(10)
*
LOOP
I = I + 1
LINE = MARKDOWN
UNTIL NOT(LINE MATCHES "> 0X") OR I > NUMBER.OF.LINES DO
IF LINE[1,2] = '> ' THEN
LINE = TRIM(LINE[3,9999])
END
BLOCK = BLOCK : LINE : CHAR(10)
REPEAT
*
BLOCK.HTML = ''
CALL RENDER.MARKDOWN(BLOCK,BLOCK.HTML)
BLOCK = BLOCK.HTML
GOSUB BUILD.BLOCK
*
I = I - 1
*
END ELSE IF LINE MATCHES "- 0X" OR LINE MATCHES "* 0X" OR LINE MATCHES "1N'.' 0X" THEN
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
*
IF LINE MATCHES "1N'.' 0X" THEN
BLOCK.TYPE = 'ORDERED.LIST'
END ELSE
BLOCK.TYPE = 'UNORDERED.LIST'
END
*
IF LINE[1,2] = '- ' OR LINE[1,2] = '* ' OR LINE MATCHES "1N'.' 0X" THEN
LINE = TRIM(LINE[3,9999])
END
BLOCK = BLOCK : LINE : CHAR(10) : CHAR(10)
*
LOOP
I = I + 1
LINE = MARKDOWN
NEXT.LINE = MARKDOWN
UNTIL (TRIM(LINE) = '' AND TRIM(NEXT.LINE) = '') OR I > NUMBER.OF.LINES DO
IF LINE[1,2] = '- ' OR LINE[1,2] = '* ' OR LINE MATCHES "1N'.' 0X" THEN
LINE = TRIM(LINE[3,9999])
END
BLOCK = BLOCK : LINE : CHAR(10) : CHAR(10)
REPEAT
*
BLOCK.HTML = ''
CALL RENDER.MARKDOWN(BLOCK,BLOCK.HTML)
BLOCK = BLOCK.HTML
GOSUB BUILD.BLOCK
*
END ELSE
GOSUB PARSE.LINE
END
NEXT I
*
IF BLOCK.TYPE = '' THEN
BLOCK.TYPE = 'PARAGRAPH'
END
*
IF BLOCK THEN
GOSUB BUILD.BLOCK
END
*
RETURN
*
********************* S U B R O U T I N E *********************
*
PARSE.LINE:NULL
*
TRIGGER.BLOCK = FALSE
*
PATTERN = "0X'\'1X0X"
*
* Escape characters
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,4)
*
LINE = ONE : '
'
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
BLOCK.TYPE = 'HORIZONTAL.LINE'
END
*
* `code`
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'
' : THREE
REPEAT
*
* ***bold and italic**
*
PATTERN = "0X'***'0X'***'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'' : THREE
REPEAT
*
* ~~strikethrough~~
*
PATTERN = "0X'~~'0X'~~'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'' : THREE
REPEAT
*
* **bold**
*
PATTERN = "0X'**'0X'**'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'' : THREE
REPEAT
*
* __bold__
*
PATTERN = "0X'__'0X'__'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'' : THREE
REPEAT
*
* *italic*
*
PATTERN = "0X'*'0X'*'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'' : THREE
REPEAT
*
* _italic_
*
PATTERN = "0X'_'0X'_'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'' : THREE
REPEAT
*
* ...small...
*
PATTERN = "0X'...'0X'...'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,5)
*
LINE = ONE : '' : TWO :'' : THREE
REPEAT
*
* ![link](http://link.com)
*
PATTERN = "0X'!['0X']''('0X')'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,6)
FOUR = MATCHFIELD(LINE,PATTERN,8)
*
LINE = ONE : '' : FOUR
REPEAT
*
* [link](http://link.com)
*
PATTERN = "0X'['0X']''('0X')'0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,3)
THREE = MATCHFIELD(LINE,PATTERN,6)
FOUR = MATCHFIELD(LINE,PATTERN,8)
*
LINE = ONE : '' : TWO :'' : FOUR
REPEAT
*
* => Gemini Link
*
PATTERN = "'=> '0X"
*
LOOP UNTIL NOT(LINE MATCHES PATTERN) DO
ONE = MATCHFIELD(LINE,PATTERN,1)
TWO = MATCHFIELD(LINE,PATTERN,2)
*
THREE = TRIM(FIELD(TWO,' ',2,9999))
TWO = TRIM(FIELD(TWO,' ',1))
*
IF BLOCK.TYPE THEN
GOSUB BUILD.BLOCK
END
*
EXT = TWO[LEN(TWO)-3,999]
*
IF EXT = '.png' OR EXT = '.jpg' OR EXT = 'jpeg' OR EXT = '.gif' THEN
LINE = ''
END ELSE
LINE = '⇒ ' : THREE :''
END
*
BLOCK.TYPE = 'GEMINI.LINK'
REPEAT
*
* Unescape characters
*
PATTERN = "0X'
' : BLOCK : '
' : CHAR(10) END * END ELSE IF BLOCK.TYPE = 'HEADER' THEN HTML = HTML : BLOCK : CHAR(10) * END ELSE IF BLOCK.TYPE = 'HORIZONTAL.LINE' THEN HTML = HTML : BLOCK : CHAR(10) * END ELSE IF BLOCK.TYPE = 'GEMINI.LINK' THEN HTML = HTML : '' : BLOCK : '
' : CHAR(10) * END ELSE IF BLOCK.TYPE = 'CODE' THEN BLOCK = CHANGE(BLOCK,'<','<') BLOCK = CHANGE(BLOCK,'>','>') HTML = HTML : '' : BLOCK : '
' : CHAR(10)
*
END ELSE IF BLOCK.TYPE = 'HTML' THEN
HTML = BLOCK
*
END ELSE IF BLOCK.TYPE = 'BLOCKQUOTE' THEN
HTML = HTML : '' : CHAR(10) : BLOCK : '' : CHAR(10) * END ELSE IF BLOCK.TYPE = 'UNORDERED.LIST' OR BLOCK.TYPE = 'ORDERED.LIST' THEN IF BLOCK.TYPE = 'UNORDERED.LIST' THEN OPEN.LIST.TAG = '