From 078128aa91a209fb2a51794a36d700fd142623e2 Mon Sep 17 00:00:00 2001 From: nicbn Date: Sat, 30 Sep 2017 10:08:25 -0300 Subject: [PATCH] Paper markdown (#30873) * why it doesn't work * list thing * oops * fixes list. maybe * Less regex * wip * Done I think. I think * return your functions * Replace $10 by $a --- code/__HELPERS/text.dm | 175 +++++++++++++++--- code/game/machinery/newscaster.dm | 4 +- code/game/objects/items/devices/PDA/PDA.dm | 2 +- .../file_system/programs/file_browser.dm | 7 + code/modules/paperwork/paper.dm | 63 ++----- 5 files changed, 176 insertions(+), 75 deletions(-) diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 53691d122e..ce8f9f9bd2 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -414,34 +414,159 @@ GLOBAL_LIST_INIT(binary, list("0","1")) end = temp return end - -/proc/parsepencode(t, mob/user=null, signfont=SIGNFONT) - if(length(t) < 1) //No input means nothing needs to be parsed +/proc/parsemarkdown_basic_step1(t, limited=FALSE) + if(length(t) <= 0) return - t = replacetext(t, "\[center\]", "
") - t = replacetext(t, "\[/center\]", "
") - t = replacetext(t, "\[br\]", "
") - t = replacetext(t, "\[b\]", "") - t = replacetext(t, "\[/b\]", "") - t = replacetext(t, "\[i\]", "") - t = replacetext(t, "\[/i\]", "") - t = replacetext(t, "\[u\]", "") - t = replacetext(t, "\[/u\]", "") - t = replacetext(t, "\[large\]", "") - t = replacetext(t, "\[/large\]", "") - if(user) - t = replacetext(t, "\[sign\]", "[user.real_name]") - else - t = replacetext(t, "\[sign\]", "") - t = replacetext(t, "\[field\]", "") + // This parses markdown with no custom rules - t = replacetext(t, "\[*\]", "
  • ") - t = replacetext(t, "\[hr\]", "
    ") - t = replacetext(t, "\[small\]", "") - t = replacetext(t, "\[/small\]", "") - t = replacetext(t, "\[list\]", "") + // Escape backslashed + + t = replacetext(t, "$", "$-") + t = replacetext(t, "\\\\", "$1") + t = replacetext(t, "\\**", "$2") + t = replacetext(t, "\\*", "$3") + t = replacetext(t, "\\__", "$4") + t = replacetext(t, "\\_", "$5") + t = replacetext(t, "\\^", "$6") + t = replacetext(t, "\\((", "$7") + t = replacetext(t, "\\))", "$8") + t = replacetext(t, "\\|", "$9") + t = replacetext(t, "\\%", "$0") + + // Escape single characters that will be used + + t = replacetext(t, "!", "$a") + + // Parse hr and small + + if(!limited) + t = replacetext(t, "((", "") + t = replacetext(t, "))", "") + t = replacetext(t, regex("^-{3,}$", "gm"), "
    ") + t = replacetext(t, regex("^\\(-{3,})$", "gm"), "$1") + + // Parse lists + + var/list/tlist = splittext(t, "\n") + var/tlistlen = tlist.len + var/listlevel = -1 + var/singlespace = -1 // if 0, double spaces are used before asterisks, if 1, single are + for(var/i = 1, i <= tlistlen, i++) + var/line = tlist[i] + var/count_asterisk = length(replacetext(line, regex("\[^\\*\]+", "g"), "")) + if(count_asterisk % 2 == 1 && findtext(line, regex("^\\s*\\*", "g"))) // there is an extra asterisk in the beggining + + var/count_w = length(replacetext(line, regex("^( *)\\*.*$", "g"), "$1")) // whitespace before asterisk + line = replacetext(line, regex("^ *(\\*.*)$", "g"), "$1") + + if(singlespace == -1 && count_w == 2) + if(listlevel == 0) + singlespace = 0 + else + singlespace = 1 + + if(singlespace == 0) + count_w = count_w % 2 ? round(count_w / 2 + 0.25) : count_w / 2 + + line = replacetext(line, regex("\\*", ""), "
  • ") + while(listlevel < count_w) + line = "" + line + listlevel-- + + else while(listlevel >= 0) + line = "" + line + listlevel-- + + tlist[i] = line + // end for + + t = tlist[1] + for(var/i = 2, i <= tlistlen, i++) + t += "\n" + tlist[i] + + while(listlevel >= 0) + t += "" + listlevel-- + + else + t = replacetext(t, "((", "") + t = replacetext(t, "))", "") + + // Parse headers + + t = replacetext(t, regex("^#(?!#) ?(.+)$", "gm"), "

    $1

    ") + t = replacetext(t, regex("^##(?!#) ?(.+)$", "gm"), "

    $1

    ") + t = replacetext(t, regex("^###(?!#) ?(.+)$", "gm"), "

    $1

    ") + t = replacetext(t, regex("^#### ?(.+)$", "gm"), "
    $1
    ") + + // Parse most rules + + t = replacetext(t, regex("\\*(\[^\\*\]*)\\*", "g"), "$1") + t = replacetext(t, regex("_(\[^_\]*)_", "g"), "$1") + t = replacetext(t, "", "!") + t = replacetext(t, "", "!") + t = replacetext(t, regex("\\!(\[^\\!\]+)\\!", "g"), "$1") + t = replacetext(t, regex("\\^(\[^\\^\]+)\\^", "g"), "$1") + t = replacetext(t, regex("\\|(\[^\\|\]+)\\|", "g"), "
    $1
    ") + t = replacetext(t, "!", "
    ") + + return t + +/proc/parsemarkdown_basic_step2(t) + if(length(t) <= 0) + return + + // Restore the single characters used + + t = replacetext(t, "$a", "!") + + // Redo the escaping + + t = replacetext(t, "$1", "\\") + t = replacetext(t, "$2", "**") + t = replacetext(t, "$3", "*") + t = replacetext(t, "$4", "__") + t = replacetext(t, "$5", "_") + t = replacetext(t, "$6", "^") + t = replacetext(t, "$7", "((") + t = replacetext(t, "$8", "))") + t = replacetext(t, "$9", "|") + t = replacetext(t, "$0", "%") + t = replacetext(t, "$-", "$") + + return t + +/proc/parsemarkdown_basic(t, limited=FALSE) + t = parsemarkdown_basic_step1(t, limited) + t = parsemarkdown_basic_step2(t) + return t + +/proc/parsemarkdown(t, mob/user=null, limited=FALSE) + if(length(t) <= 0) + return + + // Premanage whitespace + + t = replacetext(t, regex("\[^\\S\\r\\n \]", "g"), " ") + + t = parsemarkdown_basic_step1(t) + + t = replacetext(t, regex("%s(?:ign)?(?=\\s|$)", "igm"), user ? "[user.real_name]" : "") + t = replacetext(t, regex("%f(?:ield)?(?=\\s|$)", "igm"), "") + + t = parsemarkdown_basic_step2(t) + + // Manage whitespace + + t = replacetext(t, regex("(?:\\r\\n?|\\n)", "g"), "
    ") + + t = replacetext(t, " ", "  ") + + // Done return t diff --git a/code/game/machinery/newscaster.dm b/code/game/machinery/newscaster.dm index f50ddbdf7e..204ae83c9d 100644 --- a/code/game/machinery/newscaster.dm +++ b/code/game/machinery/newscaster.dm @@ -305,7 +305,7 @@ GLOBAL_LIST_EMPTY(allCasters) dat+="Creating new Feed Message..." dat+="
    Receiving Channel: [channel_name]
    " dat+="Message Author: [scanned_user]
    " - dat+="Message Body:
    [parsepencode(msg, user, SIGNFONT)]
    " + dat+="Message Body:
    [parsemarkdown(msg, user)]
    " dat+="Attach Photo: [(photo ? "Photo Attached" : "No Photo")]
    " dat+="Comments [allow_comments ? "Enabled" : "Disabled"]
    " dat+="
    Submit

    Cancel
    " @@ -555,7 +555,7 @@ GLOBAL_LIST_EMPTY(allCasters) if(msg =="" || msg=="\[REDACTED\]" || scanned_user == "Unknown" || channel_name == "" ) screen=6 else - GLOB.news_network.SubmitArticle("[parsepencode(msg, usr, SIGNFONT)]", scanned_user, channel_name, photo, 0, allow_comments) + GLOB.news_network.SubmitArticle("[parsemarkdown(msg, usr)]", scanned_user, channel_name, photo, 0, allow_comments) SSblackbox.inc("newscaster_stories",1) screen=4 msg = "" diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index 2e7163bfa1..f573518000 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -433,7 +433,7 @@ GLOBAL_LIST_EMPTY(PDAs) if (in_range(src, U) && loc == U) if (mode == 1 && n) note = n - notehtml = parsepencode(n, U, SIGNFONT) + notehtml = parsemarkdown(n, U) notescanned = 0 else U << browse(null, "window=pda") diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm index 4a94090ed4..f42174320e 100644 --- a/code/modules/modular_computers/file_system/programs/file_browser.dm +++ b/code/modules/modular_computers/file_system/programs/file_browser.dm @@ -170,12 +170,19 @@ t = replacetext(t, "\[td\]", "") t = replacetext(t, "\[cell\]", "") t = replacetext(t, "\[tab\]", "    ") + + t = parsemarkdown_basic(t) + return t /datum/computer_file/program/filemanager/proc/prepare_printjob(t) // Additional stuff to parse if we want to print it and make a happy Head of Personnel. Forms FTW. t = replacetext(t, "\[field\]", "") t = replacetext(t, "\[sign\]", "") + t = parse_tags(t) + + t = replacetext(t, regex("(?:%s(?:ign)|%f(?:ield))(?=\\s|$)", "ig"), "") + return t /datum/computer_file/program/filemanager/ui_data(mob/user) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index e3d6154606..229b28a030 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -187,47 +187,15 @@ if(length(t) < 1) //No input means nothing needs to be parsed return -// t = copytext(sanitize(t),1,MAX_MESSAGE_LEN) - - t = replacetext(t, "\[center\]", "
    ") - t = replacetext(t, "\[/center\]", "
    ") - t = replacetext(t, "\[br\]", "
    ") - t = replacetext(t, "\n", "
    ") - t = replacetext(t, "\[b\]", "") - t = replacetext(t, "\[/b\]", "") - t = replacetext(t, "\[i\]", "") - t = replacetext(t, "\[/i\]", "") - t = replacetext(t, "\[u\]", "") - t = replacetext(t, "\[/u\]", "") - t = replacetext(t, "\[large\]", "") - t = replacetext(t, "\[/large\]", "") - t = replacetext(t, "\[sign\]", "[user.real_name]") - t = replacetext(t, "\[field\]", "") - t = replacetext(t, "\[tab\]", "    ") + t = parsemarkdown(t, user, iscrayon) if(!iscrayon) - t = replacetext(t, "\[*\]", "
  • ") - t = replacetext(t, "\[hr\]", "
    ") - t = replacetext(t, "\[small\]", "") - t = replacetext(t, "\[/small\]", "") - t = replacetext(t, "\[list\]", "
      ") - t = replacetext(t, "\[/list\]", "
    ") - t = "[t]" - else // If it is a crayon, and he still tries to use these, make them empty! + else var/obj/item/toy/crayon/C = P - t = replacetext(t, "\[*\]", "") - t = replacetext(t, "\[hr\]", "") - t = replacetext(t, "\[small\]", "") - t = replacetext(t, "\[/small\]", "") - t = replacetext(t, "\[list\]", "") - t = replacetext(t, "\[/list\]", "") - t = "[t]" -// t = replacetext(t, "#", "") // Junk converted to nothing! - -//Count the fields + // Count the fields var/laststart = 1 while(1) var/i = findtext(t, "", laststart) @@ -253,22 +221,23 @@ /obj/item/paper/proc/openhelp(mob/user) user << browse({"Paper Help + You can use backslash (\\) to escape special characters.
    +
    Crayon&Pen commands


    - \[br\] : Creates a linebreak.
    - \[center\] - \[/center\] : Centers the text.
    - \[b\] - \[/b\] : Makes the text bold.
    - \[i\] - \[/i\] : Makes the text italic.
    - \[u\] - \[/u\] : Makes the text underlined.
    - \[large\] - \[/large\] : Increases the size of the text.
    - \[sign\] : Inserts a signature of your name in a foolproof way.
    - \[field\] : Inserts an invisible field which lets you start type from there. Useful for forms.
    + # text : Defines a header.
    + |text| : Centers the text.
    + **text** : Makes the text bold.
    + *text* : Makes the text italic.
    + ^text^ : Increases the size of the text.
    + %s : Inserts a signature of your name in a foolproof way.
    + %f : Inserts an invisible field which lets you start type from there. Useful for forms.

    Pen exclusive commands

    - \[small\] - \[/small\] : Decreases the size of the text.
    - \[list\] - \[/list\] : A list.
    - \[*\] : A dot used for lists.
    - \[hr\] : Adds a horizontal rule. + ((text)) : Decreases the size of the text.
    + * item : An unordered list item.
    +   * item: An unordered list child item.
    + --- : Adds a horizontal rule. "}, "window=paper_help")