From 71f29deae2d9abea5375c59ffc523baa273b16f0 Mon Sep 17 00:00:00 2001 From: ebbit1q Date: Tue, 24 Jan 2023 00:49:06 +0100 Subject: [PATCH 1/4] update to xml v4 escape special xml characters in cockatrice exporter indent xml --- .../export-template | 529 ++++++++++-------- 1 file changed, 286 insertions(+), 243 deletions(-) diff --git a/data/magic-cockatrice-cs-ech-1.04.mse-export-template/export-template b/data/magic-cockatrice-cs-ech-1.04.mse-export-template/export-template index 7fcf37e24..738d46cf9 100644 --- a/data/magic-cockatrice-cs-ech-1.04.mse-export-template/export-template +++ b/data/magic-cockatrice-cs-ech-1.04.mse-export-template/export-template @@ -96,7 +96,7 @@ script: #determine if the card is a type that is a "token" i.e. it should be batched with tokens instead of with other cards is_token := {contains(card.shape, match:"token") or contains(card.shape, match:"emblem") or contains(card.shape, match:"rulestip") } is_double := {contains(card.shape, match:"double") } - + #determine if the card is of a rarity that should be included included_rarity := { (is_token() and options.include_Tokens) @@ -107,37 +107,46 @@ script: or (card.rarity == "mythic rare" and options.include_Mythic) or (card.rarity == "special" and options.include_Special) } - + #Strip bad punctuation from card names strip_card_name := replace@(match: "’",replace:"'") + #replace bad apostrophe with good apostrophe replace@(match:":", replace:"")+ #remove colons replace@(match:";", replace:"")+ #remove semicolons replace@(match:"\\.", replace:"") #remove periods - + + # escape special xml characters + xml_escape := replace@(match:"&",replace:"&") #escape ampersands + + replace@(match:"\"",replace:"\\"") #escape double quote + + replace@(match:"\'",replace:"\\'") #escape single quote + + replace@(match:"\<",replace:"\\<") #escape less than sign + #+ replace@(match:"\>",replace:"\\>") #escape greater than sign, for some reason this upsets mse and they are technically not needed to escape + # escaped set code + setcode := xml_escape(set.set_code) + #functions for the !exportname command exporter_name_filter := filter_text@(match:"!exporte?r?name [^\n\<]+") exporter_name_grabber := replace@(match:"!exporte?r?name ", replace:"") - + #determining what name should be used for the card card_name := { if exporter_name_grabber(exporter_name_filter(card.notes)) != "" then exporter_name_grabber(exporter_name_filter(card.notes)) else card.name } - + #determining what rules text should be used for the card card_rules_text := { if card.special_text != "" then card.special_text else card.rule_text } card_rules_text_2 := { if card.special_text_2 != "" then card.special_text_2 else card.rule_text_2 } - + #helpers to find the correct count for this token relation, and generate the requisite XML token_count_regex := "<([0-9]+|x)>" filter_count := filter_text@(match: token_count_regex) generate_count_XML := replace@(match:token_count_regex, replace:{" count=\"" + _1 + "\""}) add_related_count := {if filter_count(input) != "" then generate_count_XML(filter_count(input)) else ""} - + #helpers to find if a auto-attachment is desired for this token relation, and generate the requisite XML add_attachment := {if filter_text(match: "", input) != "" then " attach=\"attach\"" else ""} - + #helper functions for converted_related later related_entry_regex := "(.+?[^[:space:]]);" - + #convert the !related command field to XML blocks convert_related := replace@(match: "!related ?\n?", replace:"")+ #blank out the related command itself @@ -145,20 +154,42 @@ script: replace@(match: "’",replace:"'") + #replace bad apostrophe with good apostrophe replace@(match: "",replace:"") + #replace accidentily capital X with lowercase X replace@(match:"!",replace: "") + #blank out the command ender - + #for every other card name, surround it with reverse-related tags and put in relevant attributes - {for each entry in (break_text(match:related_entry_regex, input)) do ("\" + strip_card_name(entry) + "\\n")} - + {for each entry in (break_text(match:related_entry_regex, input)) do ("\" + xml_escape(strip_card_name(entry)) + "\\n")} + #remove accidentily created empty XML blocks remove_empty := replace@(match:"\\", replace:"") - + filter_related := filter_text@(match:"!relate ?[^!]+!?") - + #functions for the !tapped command contains_tapped := contains@(match:"!tapped") - - CIPT := {if contains_tapped(card.notes) then "\n "+"\" + "1" + "\" else ""} - + + CIPT := {if contains_tapped(card.notes) then "\n "+"\" + "1" + "\" else ""} + + # maintype, used in cockatrice's card type sorting, + # no longer automatically determined in v4 xml, + # first use the same heuristic used in "oracle" else do the same thing v3 xml did + # !maintype [type]! in the card notes overwrites this + filter_maintype := filter_text@(match:"!maintype ?[^!]+!?") + maintype := + { + "\n "+"\" + +( + if filter_maintype(card.notes) != "" then xml_escape(replace(match:"!$", replace:"", replace(match:"^!maintype ?", replace:"", filter_maintype(card.notes)))) + else if contains(card.type, match:"Planeswalker") then "Planeswalker" + else if contains(card.type, match:"Creature") then "Creature" + else if contains(card.type, match:"Land") then "Land" + else if contains(card.type, match:"Sorcery") then "Sorcery" + else if contains(card.type, match:"Instant") then "Instant" + else if contains(card.type, match:"Artifact") then "Artifact" + else if contains(card.type, match:"Enchantment") then "Enchantment" + else xml_escape(replace(match:"^.* ", replace:"", replace(match:" —.*$", replace:"", card.type))) + ) + +"\" + } + card_color := { if contains(card.type, match:"land") or contains(card.rule_text, match:"Devoid") then "" else @@ -170,7 +201,7 @@ script: +(if contains(card.card_color, match:"green") or contains(card.casting_cost, match:"G") then "G" else "") ) } - + card_color_2 := { if contains(card.type, match:"land") or contains(card.rule_text_2, match:"Devoid") then "" else @@ -182,37 +213,37 @@ script: +(if contains(card.card_color_2, match:"green") or contains(card.casting_cost_2, match:"G") then "G" else "") ) } - + #write a normal card's XML text write_normal := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name())+"\" + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name()))+"\" # Set - +"\n "+"\"+set.set_code+"\" + + ">"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" # Mana Cost - +"\n "+"\"+card.casting_cost+"\" + +"\n "+"\"+card.casting_cost+"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # P/T - +(if contains(card.type, match:"Creature") then "\n ") - +(if contains(card.type, match:"Creature") then "\") - +(if contains(card.type, match:"Creature") then card.pt) - +(if contains(card.type, match:"Creature") then "\") + +(if contains(card.type, match:"Creature") then "\n "+"\"+xml_escape(card.pt)+"\") + +"\n "+"\" # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type, match:"Instant") or contains(card.type, match:"Sorcery") then "3" else if contains(card.type, match:"Creature") then "2" else if contains(card.type, match:"Land") then "0" @@ -221,28 +252,28 @@ script: #CIPT + CIPT() # Rules Text - +"\n "+"\"+card_rules_text()+"\" - +"\n"+"\" + +"\n "+"\"+xml_escape(card_rules_text())+"\" + +"\n "+"\" } write_token := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+strip_card_name(card_name())+(if options.append_Set_Code_To_Tokens then " " + set.set_code else "")+"\" + +"\n "+"\"+xml_escape(strip_card_name(card_name())+(if options.append_Set_Code_To_Tokens then " " + setcode else ""))+"\" # Set - +"\n "+"\"+set.set_code+"\" + +"\n "+"\"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # P/T - +(if contains(card.type, match:"Creature") then "\n ") - +(if contains(card.type, match:"Creature") then "\") - +(if contains(card.type, match:"Creature") then card.pt) - +(if contains(card.type, match:"Creature") then "\") + +(if contains(card.type, match:"Creature") then "\n "+"\"+xml_escape(card.pt)+"\") + +"\n "+"\" # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type, match:"Instant") or contains(card.type, match:"Sorcery") then "3" else if contains(card.type, match:"Creature") then "2" else if contains(card.type, match:"Land") then "0" @@ -251,30 +282,31 @@ script: #CIPT + CIPT() # Rules Text - +"\n "+"\"+card_rules_text()+"\" + +"\n "+"\"+xml_escape(card_rules_text())+"\" # Token - + "\n \1\" + + "\n "+"\1\" # Reverse Related #if there is a !related block in the cards notes, set up the reverse-related XML elements + (if filter_related(card.notes) != "" then remove_empty("\n" + convert_related(filter_related(card.notes)))) - +"\n"+"\" + +"\n "+"\" } write_flip := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name()) + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name())) #+" // "+strip_card_name(card.name_2) +"\" # Set - +"\n "+"\"+set.set_code+"\" + + ">"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" +(if contains(card.shape, match:"flip") then (if contains(card.card_color, match:"multicolor") or contains(card.card_color, match:"hybrid") then "M" else if contains(card.card_color, match:"white") then "W" @@ -283,7 +315,7 @@ script: else if contains(card.card_color, match:"red") then "R" else if contains(card.card_color, match:"green") then "G" else "") - else if card.card_color != "" and card.card_color != "land" and card.card_color != "artifact" and card.card_color_2 != "" and card.card_color_2 != "land" and card.card_color_2 != "artifact"then + else if card.card_color != "" and card.card_color != "land" and card.card_color != "artifact" and card.card_color_2 != "" and card.card_color_2 != "land" and card.card_color_2 != "artifact"then (if contains(card.card_color, match:"multicolor") or contains(card.card_color, match:"hybrid") or card.card_color != card.card_color_2 then "M" else if contains(card.card_color, match:"white") and contains(card.card_color_2, match:"white") then "W" else if contains(card.card_color, match:"blue") and contains(card.card_color_2, match:"blue") then "U" @@ -302,150 +334,154 @@ script: ) +"\" # Mana Cost - +"\n "+"\"+card.casting_cost + +"\n "+"\"+card.casting_cost +(if card.casting_cost_2 != "" then " // "+card.casting_cost_2) +"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+" // "+replace(card.type_2, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-")+" // "+replace(card.type_2, match:"—", replace:"-"))+"\" + +maintype() # P/T - +(if contains(card.type, match:"Creature") or contains(card.type_2, match:"Creature") then "\n ") + +(if contains(card.type, match:"Creature") or contains(card.type_2, match:"Creature") then "\n ") +(if contains(card.type, match:"Creature") or contains(card.type_2, match:"Creature") then "\") - +(if contains(card.type, match:"Creature") then card.pt) + +(if contains(card.type, match:"Creature") then xml_escape(card.pt)) +(if contains(card.type, match:"Creature") and contains(card.type_2, match:"Creature") then " // ") - +(if contains(card.type_2, match:"Creature") then card.pt_2) + +(if contains(card.type_2, match:"Creature") then xml_escape(card.pt_2)) +(if contains(card.type, match:"Creature") or contains(card.type_2, match:"Creature") then "\") + +"\n "+"\" # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type, match:"Instant") or contains(card.type, match:"Sorcery") or contains(card.type_2, match:"Instant") or contains(card.type_2, match:"Sorcery") then "3" else if contains(card.type, match:"Creature") or contains(card.type_2, match:"Creature") then "2" else if contains(card.type, match:"Land") or contains(card.type_2, match:"Land") then "0" else "1") +"\" # Rules Text - +"\n "+"\"+card_rules_text()+"\n--- \n"+card_rules_text_2()+"\" - +"\n"+"\" + +"\n "+"\"+xml_escape(card_rules_text()+"\n--- \n"+card_rules_text_2())+"\" + +"\n "+"\" } write_double := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name()) + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name())) #+" | ("+strip_card_name(card.name_2)+")" +"\" # Set - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" - # Name of the related card - +"\n "+"\"+strip_card_name(card.name_2)+"\" # Mana Cost - +"\n "+"\"+card.casting_cost+"\" + +"\n "+"\"+card.casting_cost+"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # P/T - +(if contains(card.type, match:"Creature") then "\n ") - +(if contains(card.type, match:"Creature") then "\") - +(if contains(card.type, match:"Creature") then card.pt) - +(if contains(card.type, match:"Creature") then "\") + +(if contains(card.type, match:"Creature") then "\n "+"\"+xml_escape(card.pt)+"\") + +"\n "+"\" # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type, match:"Instant") or contains(card.type, match:"Sorcery") then "3" else if contains(card.type, match:"Creature") then "2" else if contains(card.type, match:"Land") then "0" else "1") +"\" # Rules Text - +"\n "+"\"+card_rules_text() - +"\n---\n(Back): "+strip_card_name(card.name_2)+"\" - +"\n"+"\" - +"\n"+"\" + +"\n "+"\"+xml_escape(card_rules_text() + +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" + # Name of the related card + +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + +"\n "+"\" + +"\n "+"\" # Name II - +"\n "+"\" + +"\n "+"\" #+"("+strip_card_name(card_name())+") | " - +strip_card_name(card.name_2) + +xml_escape(strip_card_name(card.name_2)) +"\" # Set II - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color II - +"\n "+"\" + +"\n "+"\" + card_color_2() +"\" # Mana Cost II - +"\n "+"\"+card.casting_cost_2+"\" + +"\n "+"\"+card.casting_cost_2+"\" # Converted Mana Cost II - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type II - +"\n "+"\"+replace(card.type_2, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type_2, match:"—", replace:"-"))+"\" # P/T II - +(if contains(card.type_2, match:"Creature") then "\n ") - +(if contains(card.type_2, match:"Creature") then "\") - +(if contains(card.type_2, match:"Creature") then card.pt_2) - +(if contains(card.type_2, match:"Creature") then "\") + +(if contains(card.type_2, match:"Creature") then "\n "+"\"+xml_escape(card.pt_2)+"\") + +"\n "+"\" # Tablerow II - +"\n "+"\" + +"\n "+"\" +(if contains(card.type_2, match:"Instant") or contains(card.type_2, match:"Sorcery") then "3" else if contains(card.type_2, match:"Creature") then "2" else if contains(card.type_2, match:"Land") then "0" else "1") +"\" # Rules Text II - +"\n "+"\"+card_rules_text_2() - +"\n---\n(Front): "+strip_card_name(card_name())+"\" - +"\n"+"\" + +"\n "+"\"+xml_escape(card_rules_text_2() + +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + +"\n "+"\" } - + # Count the number of paragraphs to detect number of walker abilities. paragraph_count := replace@(match:"\n", replace:"•")+ filter_text@(match:"•") - + write_walker := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name())+"\" + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name()))+"\" # Set - +"\n "+"\"+set.set_code+"\" + + ">"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" # Mana Cost - +"\n "+"\"+card.casting_cost+"\" + +"\n "+"\"+card.casting_cost+"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # Loyalty - +"\n "+"\"+card.loyalty+"\" + +"\n "+"\"+card.loyalty+"\" + +"\n "+"\" # Tablerow - +"\n "+"\"+"1"+"\" + +"\n "+"\"+"1"+"\" #CIPT + CIPT() # Rules Text - +"\n "+"\" - +(if card.special_text or else "" != "" then card.special_text else + +"\n "+"\" + +xml_escape((if card.special_text or else "" != "" then card.special_text else card.loyalty_cost_1 +(if card.loyalty_cost_1 !="" then ": ") +split_text(match:"\n", card.rule_text).0 @@ -460,50 +496,51 @@ script: +(if contains(paragraph_count(card.rule_text), match:"•••") then "\n") +card.loyalty_cost_4 +(if card.loyalty_cost_4 !="" then ": ") - +(if contains(paragraph_count(card.rule_text), match:"•••") then split_text(match:"\n", card.rule_text).3)) + +(if contains(paragraph_count(card.rule_text), match:"•••") then split_text(match:"\n", card.rule_text).3))) +"\" - +"\n"+"\" + +"\n "+"\" } write_double_walker := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name()) + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name())) #+" | ("+strip_card_name(card.name_2)+")" +"\" # Set - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" - # Name of the related card - +"\n "+"\"+strip_card_name(card.name_2)+"\" # Mana Cost - +"\n "+"\"+card.casting_cost+"\" + +"\n "+"\"+card.casting_cost+"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # Loyalty - +(if contains(card.type, match:"Planeswalker") then "\n "+"\"+card.loyalty+"\") + +(if contains(card.type, match:"Planeswalker") then "\n "+"\"+card.loyalty+"\") # P/T - +(if contains(card.type, match:"Creature") then "\n "+"\"+card.pt+"\") + +(if contains(card.type, match:"Creature") then "\n "+"\"+xml_escape(card.pt)+"\") + +"\n "+"\" # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type_2, match:"Instant") or contains(card.type_2, match:"Sorcery") then "3" else if contains(card.type_2, match:"Creature") then "2" else if contains(card.type_2, match:"Land") then "0" else "1") +"\" # Rules Text - +"\n "+"\" - +(if card.special_text or else "" != "" then card.special_text else + +"\n "+"\" + +xml_escape((if card.special_text or else "" != "" then card.special_text else card.loyalty_cost_1 +(if card.loyalty_cost_1 !="" then ": ") +split_text(match:"\n", card.rule_text).0 @@ -516,45 +553,49 @@ script: +(if card.loyalty_cost_3 !="" then ": ") +(if contains(paragraph_count(card.rule_text), match:"••") then split_text(match:"\n", card.rule_text).2) +(if contains(paragraph_count(card.rule_text), match:"•••") then "\n")) - +"\n---\n(Back): "+strip_card_name(card.name_2)+"\" - +"\n"+"\" - +"\n"+"\" + +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" + # Name of the related card + +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + +"\n "+"\" + +"\n "+"\" # Name II - +"\n "+"\" + +"\n "+"\" #+strip_card_name(card_name())+") | " - +strip_card_name(card.name_2)+"\" + +xml_escape(strip_card_name(card.name_2))+"\" # Set II - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color II - +"\n "+"\" + +"\n "+"\" + card_color_2() +"\" # Mana Cost II - +"\n "+"\"+card.casting_cost_2+"\" + +"\n "+"\"+card.casting_cost_2+"\" # Converted Mana Cost II - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type II - +"\n "+"\"+replace(card.type_2, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type_2, match:"—", replace:"-"))+"\" # Loyalty II - +(if contains(card.type_2, match:"Planeswalker") then "\n "+"\"+card.loyalty_2+"\") + +(if contains(card.type_2, match:"Planeswalker") then "\n "+"\"+card.loyalty_2+"\") # P/T II - +(if contains(card.type_2, match:"Creature") then "\n "+"\"+card.pt_2+"\") + +(if contains(card.type_2, match:"Creature") then "\n "+"\"+xml_escape(card.pt_2)+"\") + +"\n "+"\" # Tablerow II - +"\n "+"\" + +"\n "+"\" +(if contains(card.type_2, match:"Instant") or contains(card.type_2, match:"Sorcery") then "3" else if contains(card.type_2, match:"Creature") then "2" else if contains(card.type_2, match:"Land") then "0" else "1") +"\" # Rules Text II - +"\n "+"\" - +(if card.special_text_2 or else "" != "" then card.special_text_2 else + +"\n "+"\" + +xml_escape((if card.special_text_2 or else "" != "" then card.special_text_2 else card.loyalty_cost_4 +(if card.loyalty_cost_4 !="" then ": ") +split_text(match:"\n", card.rule_text_2).0 @@ -567,88 +608,90 @@ script: +(if card.loyalty_cost_6 !="" then ": ") +(if contains(paragraph_count(card.rule_text_2), match:"••") then split_text(match:"\n", card.rule_text_2).2) +(if contains(paragraph_count(card.rule_text_2), match:"•••") then "\n")) - +"\n---\n(Front): "+strip_card_name(card_name())+"\" - +"\n"+"\" + +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + +"\n "+"\" } write_sparker := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name()) + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name())) #+" | ("+strip_card_name(card.name_2)+")" +"\" # Set - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" - # Name of the related card - +"\n "+"\"+strip_card_name(card.name_2)+"\" # Mana Cost - +"\n "+"\"+card.casting_cost+"\" + +"\n "+"\"+card.casting_cost+"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # P/T - +(if contains(card.type, match:"Creature") then "\n ") - +(if contains(card.type, match:"Creature") then "\") - +(if contains(card.type, match:"Creature") then card.pt) - +(if contains(card.type, match:"Creature") then "\") + +(if contains(card.type, match:"Creature") then "\n "+"\"+xml_escape(card.pt)+"\") + +"\n "+"\" # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type, match:"Instant") or contains(card.type, match:"Sorcery") then "3" else if contains(card.type, match:"Creature") then "2" else if contains(card.type, match:"Land") then "0" else "1") +"\" # Rules Text - +"\n "+"\"+card_rules_text() - +"\n---\n(Back): "+strip_card_name(card.name_2)+"\" - +"\n"+"\" - +"\n"+"\" + +"\n "+"\"+xml_escape(card_rules_text() + +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" + # Name of the related card + +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + +"\n "+"\" + +"\n "+"\" # Name II - +"\n "+"\" + +"\n "+"\" #+strip_card_name(card_name())+") | " - +strip_card_name(card.name_2)+"\" + +xml_escape(strip_card_name(card.name_2))+"\" # Set II - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color II - +"\n "+"\" + +"\n "+"\" + card_color_2() +"\" # Mana Cost II - +"\n "+"\"+card.casting_cost_2+"\" + +"\n "+"\"+card.casting_cost_2+"\" # Converted Mana Cost II - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type II - +"\n "+"\"+replace(card.type_2, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type_2, match:"—", replace:"-"))+"\" # Loyalty II - +(if contains(card.type_2, match:"Planeswalker") then "\n "+"\"+card.loyalty_2+"\") + +(if contains(card.type_2, match:"Planeswalker") then "\n "+"\"+card.loyalty_2+"\") # P/T II - +(if contains(card.type_2, match:"Creature") then "\n "+"\"+card.pt_2+"\") + +(if contains(card.type_2, match:"Creature") then "\n "+"\"+xml_escape(card.pt_2)+"\") + +"\n "+"\" # Tablerow II - +"\n "+"\" + +"\n "+"\" +(if contains(card.type_2, match:"Instant") or contains(card.type_2, match:"Sorcery") then "3" else if contains(card.type_2, match:"Creature") then "2" else if contains(card.type_2, match:"Land") then "0" else "1") +"\" # Rules Text II - +"\n "+"\" - +(if card.special_text_2 or else "" != "" then card.special_text_2 else + +"\n "+"\" + +xml_escape((if card.special_text_2 or else "" != "" then card.special_text_2 else card.loyalty_cost_4 +(if card.loyalty_cost_4 !="" then ": ") +split_text(match:"\n", card.rule_text_2).0 @@ -661,49 +704,50 @@ script: +(if card.loyalty_cost_6 !="" then ": ") +(if contains(paragraph_count(card.rule_text_2), match:"••") then split_text(match:"\n", card.rule_text_2).2) +(if contains(paragraph_count(card.rule_text_2), match:"•••") then "\n")) - +"\n---\n(Front): "+strip_card_name(card_name())+"\" - +"\n"+"\" + +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + +"\n "+"\" } write_sacrificer := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name()) + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name())) #+" | ("+strip_card_name(card.name_2)+")" +"\" # Set - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" - # Name of the related card - +"\n "+"\"+strip_card_name(card.name_2)+"\" # Mana Cost - +"\n "+"\"+card.casting_cost+"\" + +"\n "+"\"+card.casting_cost+"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # Loyalty - +(if contains(card.type, match:"Planeswalker") then "\n "+"\"+card.loyalty+"\") + +(if contains(card.type, match:"Planeswalker") then "\n "+"\"+card.loyalty+"\") # P/T - +(if contains(card.type, match:"Creature") then "\n "+"\"+card.pt+"\") + +(if contains(card.type, match:"Creature") then "\n "+"\"+xml_escape(card.pt)+"\") + +"\n "+"\" # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type_2, match:"Instant") or contains(card.type_2, match:"Sorcery") then "3" else if contains(card.type_2, match:"Creature") then "2" else if contains(card.type_2, match:"Land") then "0" else "1") +"\" # Rules Text - +"\n "+"\" - +(if card.special_text or else "" != "" then card.special_text else + +"\n "+"\" + +xml_escape((if card.special_text or else "" != "" then card.special_text else card.loyalty_cost_1 +(if card.loyalty_cost_1 !="" then ": ") +split_text(match:"\n", card.rule_text).0 @@ -716,91 +760,90 @@ script: +(if card.loyalty_cost_3 !="" then ": ") +(if contains(paragraph_count(card.rule_text), match:"••") then split_text(match:"\n", card.rule_text).2) +(if contains(paragraph_count(card.rule_text), match:"•••") then "\n")) - +"\n---\n(Back): "+strip_card_name(card.name_2)+"\" - +"\n"+"\" - +"\n"+"\" + +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" + # Name of the related card + +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + +"\n "+"\" + +"\n "+"\" # Name II - +"\n "+"\" + +"\n "+"\" #+"("+strip_card_name(card_name())+") | " - +strip_card_name(card.name_2) + +xml_escape(strip_card_name(card.name_2)) +"\" # Set II - +"\n "+"\"+set.set_code+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + +"\n "+"\" # Color II - +"\n "+"\" + +"\n "+"\" + card_color_2() +"\" # Mana Cost II - +"\n "+"\"+card.casting_cost_2+"\" + +"\n "+"\"+card.casting_cost_2+"\" # Converted Mana Cost II - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type II - +"\n "+"\"+replace(card.type_2, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type_2, match:"—", replace:"-"))+"\" # P/T II - +(if contains(card.type_2, match:"Creature") then "\n ") - +(if contains(card.type_2, match:"Creature") then "\") - +(if contains(card.type_2, match:"Creature") then card.pt_2) - +(if contains(card.type_2, match:"Creature") then "\") + +(if contains(card.type_2, match:"Creature") then "\n "+"\"+xml_escape(card.pt_2)+"\") + +"\n "+"\" # Tablerow II - +"\n "+"\" + +"\n "+"\" +(if contains(card.type_2, match:"Instant") or contains(card.type_2, match:"Sorcery") then "3" else if contains(card.type_2, match:"Creature") then "2" else if contains(card.type_2, match:"Land") then "0" else "1") +"\" # Rules Text II - +"\n "+"\"+card_rules_text_2() - +"\n---\n(Front): "+strip_card_name(card_name())+"\" - +"\n"+"\" + +"\n "+"\"+xml_escape(card_rules_text_2() + +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + +"\n "+"\" } write_leveler := { - "\n"+"\" + "\n "+"\" # Name - +"\n "+"\"+options.append_String_To_Names+strip_card_name(card_name())+"\" + +"\n "+"\"+xml_escape(options.append_String_To_Names+strip_card_name(card_name()))+"\" # Set - +"\n "+"\"+set.set_code+"\" + + ">"+setcode+"\" + +"\n "+"\" # Color - +"\n "+"\" + +"\n "+"\" + card_color() +"\" # Mana Cost - +"\n "+"\"+card.casting_cost+"\" + +"\n "+"\"+card.casting_cost+"\" # Converted Mana Cost - +"\n "+"\"+card.cmc+"\" - # Converted Mana Cost II - +"\n "+"\"+card.cmc+"\" + +"\n "+"\"+card.cmc+"\" # Type - +"\n "+"\"+replace(card.type, match:"—", replace:"-")+"\" + +"\n "+"\"+xml_escape(replace(card.type, match:"—", replace:"-"))+"\" + +maintype() # P/T - +(if contains(card.type, match:"Creature") then "\n ") - +(if contains(card.type, match:"Creature") then "\") - +(if contains(card.type, match:"Creature") then card.pt) - +(if contains(card.type, match:"Creature") then "\") + +(if contains(card.type, match:"Creature") then "\n "+"\"+xml_escape(card.pt)+"\") + +"\n "+"\" #CIPT + CIPT() # Tablerow - +"\n "+"\" + +"\n "+"\" +(if contains(card.type, match:"Instant") or contains(card.type, match:"Sorcery") then "3" else if contains(card.type, match:"Creature") then "2" else if contains(card.type, match:"Land") then "0" else "1") +"\" # Rules Text - +"\n "+"\" + +"\n "+"\" #Level I - +card_rules_text() + +xml_escape(card_rules_text() # Level II +"\nLEVEL " + card.level_1 +(if card.pt_2 != "" then "\n"+card.pt_2) @@ -808,11 +851,11 @@ script: # Level III +"\nLEVEL " + card.level_2 +(if card.pt_3 != "" then "\n"+card.pt_3) - +"\n"+card.rule_text_3 + +"\n"+card.rule_text_3) +"\" - +"\n"+"\" + +"\n "+"\" } - + write_card := { if is_token() then "" else if not(included_rarity()) then "" else if contains(card.shape, match:"double") and contains(card.type, match:"Planeswalker") and contains(card.type_2, match:"Planeswalker") then write_double_walker() @@ -824,7 +867,7 @@ script: else if contains(card.shape, match:"leveler") then write_leveler() else write_normal() } - + #if the currently exported card is a token, write it as a token write_token_if_token := { if is_token() then write_token() else ""} @@ -833,23 +876,23 @@ script: { write_image_file( card, - directory: "{set.set_code}", - file:"{options.append_String_To_Names+strip_card_name(card_name())+(if is_token() and options.append_Set_Code_To_Tokens then " " + set.set_code else "")+if splitter_name() and is_double() then "_" + card.name_2}.full." + to_lower(options.images_File_Type), + directory: set.set_code, + file: (options.append_String_To_Names+strip_card_name(card_name())+(if is_token() and options.append_Set_Code_To_Tokens then " " + set.set_code else "")+if splitter_name() and is_double() then "_" + strip_card_name(card.name_2)) + "." + to_lower(options.images_File_Type), width: (if contains(card.shape, match:"split") or contains(card.shape, match:"double") then 752 else 375), height: 523 ) } - + #if images are set to be rendered, render all images of rarities that have been selected write_images := if options.export_Images then for each card in filter_list(cards,filter:{included_rarity(card:input)}) do write_image() else "" - + write_cards := to_text(for each card in cards do write_card()) write_all_tokens := to_text(for each card in cards do write_token_if_token()) - + #Main export script - + #tokens in Separate XML - if (options.include_Tokens and options.tokens_In_Separate_XML) then write_text_file(file:set.set_code + " Tokens" + ".xml", to_string("\n\n\n"+write_all_tokens+"\n\n\n")) + if (options.include_Tokens and options.tokens_In_Separate_XML) then write_text_file(file:set.set_code + " Tokens" + ".xml", to_string("\n\n \n"+write_all_tokens+"\n\n \n")) #other cards - to_string("\n\n\n\n"+set.set_code+"\n"+set.title+"\n"+options.cockatrice_Set_Type+"\n\n\n\n"+write_cards+if (options.include_Tokens and not(options.tokens_In_Separate_XML)) then ("\n\nTokens\n"+write_all_tokens)+"\n\n\n") + to_string("\n\n \n \n "+setcode+"\n "+xml_escape(set.title)+"\n "+xml_escape(options.cockatrice_Set_Type)+"\n \n \n \n"+write_cards+if (options.include_Tokens and not(options.tokens_In_Separate_XML)) then ("\n\n Tokens\n"+write_all_tokens)+"\n\n \n") From 66fc659832864feeabb4ecf8dc55b67e868775d7 Mon Sep 17 00:00:00 2001 From: ebbit1q Date: Tue, 24 Jan 2023 01:46:33 +0100 Subject: [PATCH 2/4] update cockatrice exporter to 2.0 move files update icon image --- .../icon.png | Bin 25733 -> 0 bytes .../README.txt | 0 .../export-template | 7 ++++--- .../icon.png | Bin 0 -> 7432 bytes 4 files changed, 4 insertions(+), 3 deletions(-) delete mode 100644 data/magic-cockatrice-cs-ech-1.04.mse-export-template/icon.png rename data/{magic-cockatrice-cs-ech-1.04.mse-export-template => magic-cockatrice-cs-ech-2.0.mse-export-template}/README.txt (100%) rename data/{magic-cockatrice-cs-ech-1.04.mse-export-template => magic-cockatrice-cs-ech-2.0.mse-export-template}/export-template (99%) create mode 100644 data/magic-cockatrice-cs-ech-2.0.mse-export-template/icon.png diff --git a/data/magic-cockatrice-cs-ech-1.04.mse-export-template/icon.png b/data/magic-cockatrice-cs-ech-1.04.mse-export-template/icon.png deleted file mode 100644 index 7c56e0db555940300587e7be1cbb81824a2ce399..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25733 zcmV)dK&QWnP)KB3J+ydlw7F8Zil)s8Nhv6JzYgMxv(Jq9(@P zOJYgHUa){28>lE&svzBE7k2lwneUIeuF*a3YhH~p<$b^T=V6v}=FB|v-1mLm*Ik}~ z|9^bRW1aJou`~^;%22!*`u+jJ=V0goP_+RJZmqhb!@5;>jQV4byL%kascrpNO)Y-d*w8q>v7u?bPk*!GjZc3w_ngKXW92~c<&J{kydExdmlRG$iqPK4Y{D0GCk9{5+!=zqcy{Ht%^ z-{;t1MKV?mg78pit%lyaK)yGOc#2K4!`XD}KX<*d%ZXjDZn$9W$NEQWKepaM>z-NP zcil7l9J=nH!QIv!)VXDy-_(y^=QrVR*4nq<>uc@Hus-Ye_*0+tq4Tdhoz(f)P_tuo z@0uN zJ=}Z-EP8JFrHh_}k8fCX>c=FM zWbWKuXa08Osm(X7JY`xVZQ`m;@QlLX9Lh1AQ%{o2?hc?(UYBlL)n@iL2w=?1?NLB zDY%ixAs866g##g28N5LgM2AM_#fL&$F+aSm084tW*m6l9nECcc4KruJi!-J_@#5R? ze9vjQ=XRX=YWy?2nR##Vo9n~F!=8ELkwf6|eP8(2;|~{Jp1uG4t7o77{`Tb; z;(g0gAG`yq?}d9q=(HTBH$(6g6n+TL9R9C zaL~b-Vd15j^~S8V-kc$qulv^?>yKNqd!K#JhCMgh;p06@Fkt8!8x3fI%%|b4nPpI( z6m3*~5?GT{SraHTj4}Y*Y6^GM4_gqta5vI8LStE@1eUETz86=Fm4f8&Pt*9Z#$3hk zKBsY3`|ro^>g*LVz{22s7D8s1;DyZ2P$t@^oPoK&UAX()yWpYwr(E|?4cxWyqy6u` z4c`6nN4vfItL5*Mm-6TG(n<57W&zx?J5*l+Qx1c0F|=F*&mHlvUIG8e<9~sGj94cb zvrSO_D73u>JNyxfli{ds857N7=bd}3z1vz_uf3|{AqQ?X_LBpC2j6M?*7)z725TJA zdt(2sApRxq#OFh_Mf`fa6)=~P%mqTmCOSOWOh4G5@eqx>Xsp&)(AZN`{C%D8r*Viz zFMJEcS3R0FPSNg?IWn1ce zU5!U++))3&lg@1!JjdH;{Eo)8_1}GT9{vvxE(;Pb)%gb+FVwiW;`e;LclEt1bbgP< z_w@HC+WkG|3SuA^KR^zGTZ6^HjldL+;Td@U)Hxfz|1?~4=RNyg`$u?i;?qBR=ul|= zUCWiN6PquF+$6Z~G^oB4F1-=zPlDHXht}O8?g0<3_f4&gZ{qk55|H&}y2DMNR~ZT` z;i&7NyagP6J1`FVO&PH7fD;Dvf@6<4aKJG~!JfN}K68(&pypfEN7rlw(bMte(X$XQ z;k0-O5C*^0Qo2k(qy-%4JUG!epz#jtag#gY zCkm!#9FgmjU;bH)diq1~Lc3bBiH&7EE{pMji%JLRfK1;y&GX;MZI*-^lTAC?Fd@ zsejCbE zh)#+hE1v}{3+`bV5Cm`QX>Zq~U#j2Hf(g#o_!s^C8l9i4^Y7{0n0j-K*X!?c+O3fT zL!a&%4W;^Ow1qKkY5}rOvRdP(6`y-c<3f!Vge4l~yvG*on>9Y8zaOphNjkSCH}sQ_ z5|7bnAL@9W@0|?s4#YrDenL+OF9_@Lg>8H8yc$lt{or$d)(Abesax9PN6_|hvA%UNa8dBx zL>C8QlY-?M|E$pqZ??{@>HF#Lf=)qaolC<9U3LBgoy+%#bW@*G_Gtv#%8JB(CG6=H2zSZGZgdh*)klfbFpBtG6igLVp+CW_Yp5>|2(lQ zXPgLNKJLSxpx0U5AL+FMPVRBgeJA}GGQ~_j6Tsv5zc6CbUx9BITKP`zeW5rU&RYb_ z&V`X9p{4=OdKKz7hFMEs_N$tgf2k7x7YfK=Y3{?NiMw70TkHBlrfmuovO?+oOBQF^j%4WKp{kSy82m|vJXXwsC`%MLAXN`i2DLdT=Kx^DHZiTMP zJ5B9;BmDTe{mwk*Rao7>_~PpR@I0?Q@d5zFT_AfL6elE8m)`}3WTEHTaNNak(!((I zL>T^Ja{U=5NB*hDzd$;-ekmD8jD=trJbgQSdmt1)g^R9&%uiv++E69TpFJF4=(R)k zU#AJq>T~!rXFLdNf4AS;1MY+JTbvus0&0V;lBI5qA4t=sf+6QMP)bQKL!&Lo9NnO> zxqXx1G5!5wou96AEwJE5otwrLh7V5B`L{Gm@Pg4gmtZ)aLcPW+jds=z$$aSku}0Sd zLQZ$=`?2NtqyB!A&LtogbbhDvT{W6)upoR}<3NoP_*g7lEQn`|7AI_4TRfjO$ZQl` z8m5DOwHqAK`sQ>fVnPTT-t z?Y;X!HPG)ny)W+f5wu-ix;#H0m>gc6fP`Q`qH}}6$@c?6n$$8#0|t#6EjaTuiY5&V zQ8dPtg5tw8uC9|h&w_CAK005s{TSF+@WQuK{h=pHW1U9DQ_=vV*)Bsh3!ty7c}@jM z3L`dD6!eP?C1sgn31%#4ld@VC2wmSabDXU>*K;T!NpuT2C|(@5@DcR;Zm-Mw?E(ic z-t*{#o`K&kx_#RVkAtS2KV98)IY21E&i98QuR!5GxMn=u^E{kz5A3x8{OJq`r$amm z?rq?oaQqW2$X3$i^#?-m9eDF1IA{#C9RnAy0pYXIV=t(loP4foGyqprwem;U_j|i^ z`Q8z5&`!H8Ja7~QgTq~ewSXzXPKnzYo}fn=uQB;Pp%zZCfkt6)$1zO92C`_zx`CZm zIkkZ_ba1EsezwlX>b#pqYkad$#vYEBn6=B_!Mvg7<*@wsNiyY$W!Uj3xaC=R^W6ka-sgG!MviaL zf*49|cLFdK9tdFn!=de`aPcSzXF!jmpjw)}N*X%%96)`i0gKk&8^-)>^ZR#t7s@N* z_sVl1nh;$ZodJvw4@_d&ksw0w-DC_W=*5VQ2^|6V0`xOi=0M3;p;4nXsje5x8Ba0) z#ER?q)C+W&Mq2;}_Wa@n?NX=Of@a@Dxm-czb)t&v*pdnIFreZ-eK;k>kWMU}El=!} znNxLsX#44jM`|>blEsK@IYbr+ViB8mehq+fd@^MSU*pj51sL=CrswRm8N6KnV9G12 zVGi>jNhB@sf|u`?-vfI51XlkNF8&2P{T(P?2`5j6JAMM0W?%>St1aX|^!NrW$Pi)N z@Jju}6|nbIDAmE$(;#ya^f?l$^@6LVX{y!(2yUxx46cUp@9h5GL07^aS8e(3Zf`-f zeK0=S9ViFW6DSobA{^eT-x2l?f1~p~G%6J&kbr~=@R>CV^x}ix>j8wt?OZcj|L?zB z0KA|rcs>O2(#U&-#YlaOEi10mz2b8g498iVyJZ14?dx}F$kwUicPv0YEI4Mznkuei zUq*2vL$kP5qam6FL$rBh-$sGdSaFp|K0}nuM>gJtEQF87hX?n-gEL|0ZcPuo_8oG330~GSnd-=^EIw{yc zeg+7_3CXLBC+qhnCZh!pZ5axLN!FGOeU-dF~=2E#%YJ@83#JNBt8 zz!H?UHKEU4(6$#`^b4rD5|)gD))KtrM9zQM@edS`;bL*(wP5g;P?!mqtqGZ5!a6;n zdgJ8(tF#cSq$#U35xF4%8yr0N$n~3{OH=1xb?yoIZK6-|OMoXrE!~uV_X7Mx=Stp- zP1A~2wIzw`H9B5lr+Ku_o%&(T??9Yhc%|l zu0R}3ULb;Y9mZ?E_Gth8)aTLjeL))hXGf(#P;uU(ajHf^viS9ic{)p@6ku)*>{+pqs~Soq?KUrRuCZ2x_>)2LLQwi{rbbD*>z zT)Go<-4pg-0o$yCS$o5CwxnO{_y-8cC~3gVYtZF(XuJY`xh-%RY_=9uO9NNw1yo5B zS4lHeH3Q@Z*Zw}2fnnFIed5sDpqyp1==Tua9Y0up2?*j16BHeLAqnHA8dgqtY>liG ziTJk~jlGTe?X(-)JKObTjdIEZM|Qp7?F>6kQKwO+J$OauhB#gr4p=((N%In0kVPA} zNZ>zIpsy%rxmMThBbKPA*s_c?wCU;pl6LQfBAPZ0C<-$Dmo$5?3A1I+-Le2Vl|~jW zzC`E0(z)p6R3N_Fe%>TFaomBG5bnW<%s3c!|5}}g2Jmz=^T8>zpcJ;8SQ-SRK46*x z^ROOI5I8>%Hs1zXE`xIiL7)BL=)Ga*70`4aJYneicO73tKsJ+8z0RBjj=VAzjyWlr zp#6G4)vtiJpi0=ZN&%>x7HE~QYOWce%RO~RbQu7>Pv~|{uUjF1Lv%uZO^8PZ566ku zVAe+yZ<;a?E$Tp9tcW>E9Vt6k$(q{>`81v1tx*_0&6zq*qp-9i@@(M=(5QGv;05B; z6{o=)`j|b^f=>f}hD?H-x$()^K?1l$P^C@DiYv8{S58jGdZmbD9sjT|WyK*ui)4v1 z7H}6}t*96+I933*)OON+-=?wcl-r^>{v%&67UYbTn-HzXD^b~dwovH0g2^_+!6VBhy)*laCYC|ZjiZ0AI0FQ*LxB*C${~TY48#Ky?@q&z`X#>}5XyK*t2y0Y1fx*voE{K#0 z#90-ecRa)vKv1M0=e&;qN4*(Mryu1JlwWC1!@pnqQRVht_Ly4kW+K)%$nIQdcc8UI4( z&I~YAGktCZkkHKa@j?!Vnjci}RDC;i-?Z*e-S2?qG@YOa65>cB_a+N;Uy&eZbSGr9 zP&^k-sD?j32Cqzj{I2lSq5Pf4-ytBwHF4pup!XBdvJafq1Hy^Wy8)_{UY$#pHC0+r zIejmu1+91oxlRC`*X=yI^CV!C@EU#yh5qrA#T|ju;@y%&Z#&nqk_IgpX<*8^MxuRf z^3w(FN;mr$vKWpCr|gb%qnsvgr(bm*X0w)xt(q;2TsTAbp*Tt0OW!kVCf_M{Q!;ke zLSN(3Wb9$ht_XS6b;($-cute9yV^Nay52k`MRpO?>E+ZA`2+<$&nF@=in`vq`klaR zouFN+5IipvHCj+?VRc>8zo`JZTZ&kv6lyx{e_^}N)p8QI1K-IU#+}f)y35xY3ZAk>tBi(N#h1fO;dfyI(&Tw`;be#_~wukLEfF)C4ijd5gJHCQ|Y%Z+4 z;Wi0wpL`b_*#+1gwmTYfKLuWdoJ?R&6P%M1TP0pUCn%8f`91(OkJjE&y*ZTrOpnqJ zA)XcI;{AYtW5imSpBJ==*@aTid;7zmW<1!VTbC)uVLp_*Q*f}?N*%DM0N>tyU|mdUJ|1;Ng`>1`)Vnw4|mmZ7FCihQFq04arr z--`t)@m1pZAz}z#0>8JYF^BiMyg+l25A&x$X^ZHwZZE5 z;fVX-_>pj42;CZhE-+E_^xrI4G_zz6x<1ZxYW1;*_oO!jlgXi5*G{nrtcL#5pdK zYCJ8RzyUx&|VmpqTYiB)iy< zjPHqs>nteN*#aitqoba`>;RlJek68jwdT7l7B5uNVoB^zQNCb7knd9|kS>Cbv7K+t zYitFg`E$fP%?h^D??Nu!M@pO9R}ln@r&avjk^G$if+5@z%!gn=?!APN&zYsOLX-lF zoU?VXMj?hsf>@TImJdu4Rg1requzi&&WA^@hbW^M@IOjGHqs4L9S7C*u>2S}t_VRM z`ri*ZEwr3c5pu%1wj4P*%{gI7L#?bdXKs6d;zQh9I2Vea#`hO4fp{Y>N(j%`@r^%d zBFw@VyE~HZ1#TW+DG$!N^@~CpKd`gxE+T#*_Ep3J1#XVuBuCer3tIG$X6+))Hcy)G zLw&wz0YA3=b<;zFvr-Ugq1d5y?A%LW164GZ6e%wYqB*&+WWlsWGz+HZbqa@lro56E zBh#t2xQ1GWYKBsVN)`-5GbMedaUyq-aqim8_U{Q>EVGcO0|YbUzXX4U;!VNG!kz%R z2UUThxKt#;kM#SI6k@qS=bERoebG6|*t!VT*bwq>!*TD!noV%nC$MWB6#BuVjr@({ zO9)7_vMqBzhaCq&^mEv|4yuH~bJA=UfUKSGvHH8{(VQ@LR;D>8K07-aVD-Rq_m<0` z@MQd9VJ47?52h1P;0H-)DzXK!C9vaV=US;HcCKC66wBvuz$tJpk(2x!NHpE+%04Yb zJNtnwlP!{2FvnLiS`Y)ZpvtPdm?^Ub{B|cy^Yf%k6%dt#{)uW;fT3(0GSr94UNb4sOG>@dnqQULwqb#UcmSQW7)%;x# zd*2L8XTu#AL1C5n8#l4|Z;!trARBJ4`?~}>Yz@s9!4dmHcpY>;60$OtSvjLwnb@41 z)|@6hD;_*6jgvDiDW^HRE>hT zotD5#fb4v`nSp6wO#dnZoJPFgskojNe&7J1pk=G#Db3QfdC`kj6x}E5T$W&fNQ#Am z28-qU1eI|IpK9J#$)_mFi4K36j7@WrvCVX)ERq9w8T$%?RFNRoYFUytS*8y1Av){5 zncT2bZ-L0m*{-%z?aTrTnw@#qkEjj?$AQdV>AquEELxzJ00d*{9PA0j)zPBj7SPnM ze00-!0J#eiRTYcXi}XGtS)fSJy=-J6NLv;QSKSmf&Yepv`XT$(_nPZq$G08gOGaxI1+MN_&I503y1|FD+rR6bDZ_(BEvxHMM_GOz}eCQa)xoULmJ zW?I;mLK-J1Lc$BB>=ZJ8A>ot4JU$*IgrlV^pQv(ntz$(m?Em8@QDrUhX2#?h@UcfpdS zt+h)>K<&;oH`VM9@%eEs{sRzjzuNH_yE?_f?2@sw*(CRkasbdZpe$rCm@Q z=WrxnzF4eyP719OXF85gB8K2>-V2U`B{$|DUV0X+-XT7{B?M+=?Ud_1l zQ4b^mm@(CmtJlQp#bt&4vswt5>FsYg@hu=LS~RPP%8DM%xWCo40Oel<2bLd)`NyqV zW5F`$`|U1&?lTtHEjWiUz-p$5cvOj~n<507u(U!>G-6`?|lZ=C@V8NVP0pEN4H3P7Yuy z0BrUv?Yd&iBg-ob(<%Nw9f41|nCUR@=c}iD{0As!!e!-c0kR4RMiRJ4iY}6+vw-A; z1Z+vNQYcxmT{%JNlGwG36kKTrjQKTu@-Q?k1AYlF_om|boPZ1$-8n<1aoB+{_6=Yz z^ymRu`6O9QU`8f2V*#*pE)1GNEn(5jr8*ZR$_is=rO`7l11z|*d5?vSF!Z+k&j!B+ z9h-BDIvfe{I6meefIuk{fpe!!>yFjA)7Q;X3Hk*dO$TcMt<*w$Q3A8XO&t`uPX)y7 zdK~c5^DLBR9j188aL^sD&2op3%JI#tQN{@L6g^|0Gb`()k0h)1=Q8Pjce6i@@oq@QRmKivvY2C z%jCh40Ks2*jN4$>aS0GUa^Zy_Tr zn3ZYIie}8}#xpWa898qm-B3m^G^>ft2oq=OHA*9fHv_C(Sm@LAFwEV&Y32NbVaQ9} zmJiwj;(-i`Zw8{^b`hm|(6qsu)1qBt?sRdt^N~{<-K43PNb@Z} zqWud>ll5dt=S@h)_v9ouN?>QWhTSx?Su?lcsXVlh3tCt$j_-JZSuiRq3uR$G)N?G+ z0(nn@UUD6YBj?8AVgX;1FE?+FE-y=4)_YlP%OM5nbao3^?Bq^eCv8;c6c%ZA<;sPe zLkPhc%nDwHx$&xd=3M|yy^9^1-v+(6aN)Rb?yhdr3 zjM$&-Zl8T0KGOslu??9zje0?;V7Txn(X72VopoW>u8pV9*$;ZX+;Mo%qoKp7+&VQc zLwtDLmE(Yb*W{Dfr*H(>@e56ivvHlwnD(oZCa)DV88lX-pg@~U^n21M)8w=l^&C!J zDM$cb)$`OzP)c4Xh9J)E`m%><;S2wV&q-s?l0Z3WFmU0J?yDrIIa`)uwk*zc(X}N9 z@T7R$qO{HN6)Ot2OETGD$YomH7S0ABiEjf!X{XT23wgq-`9`zHHSG=k@@W z@NmM11%k>MAsRz?2Sm$a`z$zF320etRaRkz6rq?rl3-^wFInAx;T2f-2*~GQ%N8hA z!Dntr7DkEYTYqW75WVsn*!3L<`$5$ikktfdd}D$TnLXRzXhv8!BTSf;gl43{GrBSJ z`Wa(+L8U+w9n=7|^Z+vj}v#`$e?gtERh2ZdDVXz2T6zrCG1F`EctZCiN zL>Sfs$`KAwB zm@6y(Zn{;Z!c<416^C;C!s+(56!uL**K?T8HI3`}zDa*~+(Yx7*0Lw0ML%ZK2ja*1 zRXh)7?cUsD_BF6_%feGl*8mTNBNG9M4QXW=oz9;TNs^HZkd@*qOMpsZ4>Nj?89VXg zbuNgP(fcvWSeye@Q=m8scI^U3Tn`gBhpr6}Pt5|lz}sD*&%qGi1Y5U3M$Szremf)0 zno&R|Bi1E_RP`F=oQ3igGIm}i02#$4LSt1oRd$3t(fs!X{dfT8&TG2m;|b8YfAy%& zTSLzcI{cyg%@B|0?j%H*#zAaJ9OrO9Do4hhnj)+kx-LYtZo!a2FSbgSuS%>^U$I`1 zX~nVnzS6PN+$7g!I7|57<)|pBO$)AEfF{Gov*slJ9kx z71YcaN|_Xr0!i1e?mIO5xDjmA0q%Sj`ZOdg<)W!s$h#}~BpC6BB)M$hWstcQSPdCr zyU?YyzG0czCOwy9LzlkXxtrdf>odPmTb>;PB+txaDSGNM%8B=RjGGCTXA<(wHBMb}sA1baDVt ztX!i~CGzI^9ld*NMnz)RT z!7|Ub|AA0|EfnMmh3!JI456^EeV0(QWZM11Y34TB?rY^{3{3#dPZW+`bs>D%bLFU6 z$HAaO>aHL7EvQ;MGa|Ps#1n%1;|qW=_<;n)k!$%Pp)AZQ`5aFQdVJ)ZBs;%`Y%VBr zn;=2OG*aw9-`~5x#}^%j7;Yx*?kA3$l)u{L{>x!Y;(l0{>d%Uo)ChVQ(nJmVyqkQx zAC}1q3(jm!<5NTsoWoy&Q=srn^w;91Fze~&BWJ$@&Bfw=tFD31DMBZ4YJta28L~xI zyepKV%DCJ@>o#L&+!jX}523D`ai)O+fmx-hWE`-Ti7muJQX2?9+7BoC{&C+RndUV?Jbmni-s}1}+Gua2XH;17z%tQDur> zmT8^ooG6hEedJTPb?1^wO(|9^O?mmU-7~x(rST#;(}A#kx3{180AYF z!o1(CK4rmBSg~25bL0NN^J(&@1CFN8t$17_>$HE72446XDO5vuEAmiKJ);Gm`Yd{% z89_y}mKphKp$qJk4P8188WzAV1EA`?EVSJReJ%zDzXMB_~fw&rEcHq59|LL8b?FlY1t&HYuIHF)j*#KkjnxeCKZAJp;#`{v7wx( zP%k2s<_kMijFR9`3)9zgmZvqN>C)im?O$}@NUSHyZFQ0deJpsFC!n!^VbRJyQ0&`0 zx40Sf{#C~(dM$&RXL75nKLlP5s(2k(7(K@#Ac!7Kbb7%x%?h+F*K>^!^!u(9Lsu=7 z)tb=PWr1c%^R{SyA_-O?h)|Yb7vx)2OH=G30jd!ldy~kH9@3;+>P1deJZ5dzi70OI zl&+U|s)jgiIsW&VIg0-*fyaU;6d`fHFh|;@0PSl8?)B>ph@^0xa^s!^ zDRh@}oi2E@SK~E0j3Ck`BL$zbu!3Hp1S1p@Djov8_ekPIL*LCp^g|f*7=%&s68yo? z*`#tp?K_0F6k52Ua&X+c)~ObLQK2T*dN=3~JTm5do&=)zx+OLsmS7BV z>VhV8fa4d6mvqxa_ETJ9l_1$F1uESfA{1*@a4uCtGQK6&s8JSc6Jg@LwP3qzKKsaW ztrW}FN06aG3uA4iqpuRgS)%!PM$oTO79n(CdXq@cL6;+-JRb%(XCdAkM*S9; znmF91KLfpp(5V;7rgZ1RP^LPVsB?EkmnL;ZTd0MS=0X{JyF0q;G}JC8?VYQSr`s23 zfjHg~c>fMN)inUcGotF^3|KOu_5EdM!|IdDKWaG=x?Ed(Z09>6_x|7?XU_zx>$jr@ z;&(HB`+bGXtJAeY`c zo7f#CO-i^?owt&6*0$y^Rp4Imf@Xmgx)ehw#S}i@{_}237phx-=w8IzCGJ3ZL)dV7 zHnALQzxr7^aq2wkMFd*-VMTp~3u;n95F2F3m2NLkrw4VKy0dYOr46B+e(sV@V|hEH zu9<$a;@nu@bql`)h$jR;iEo2dziqx^^+agPOn>SdDgWwD8>?$GJtJd*5mSdE0=r2d)E+wm{wk(1l4ZCDlX)@>$YA zpVc^n!{hHpnqamzb`_-@!7!^OjaA02W8Vi7yxT~^>U9&Fi962y*NMeDurc_Q*nl3Mr zAnm{9K%23+6v(rhuREQ#EvQnXB*NaZWDWZNE%p6TdLN4=C?AN{-c*9tF(DZ`#D~!V z7!WtG1~857cpIX8JU5yHg`wpuiHXean=fRNmOk5;HIflabo}paPPfW^B9y^`Ai8|wb`1xmez&vhT%Jh zwUB$LbZPc%$Q~Ll%yxpzKH(0Tb%6WhA96d;iI3<6tl|?^18u>nOsV`;=Vjstqgc6ugNr!EEfh!~s?+MC1BPV;W1UiM=+(iJ?Ec%dYpwmTz z=m@OZ;d)j9-`@H$4uJA?tXuv7O4mn0X%!UrD9d zPTE(j*XVS6x94$B0Jmwf58*B}?zAY2k~Z2iovi0`O?q0<=zwygMmNWhg|bCS73ye> z_JNh99l9yF0*Ps}bs?y#E>Qn;0PBx~{A6GtRBaC(G~u<9;93QOYIK2Gu_raUk!n?L z)rd#07RIgC16GNyH2>_9*wBzlmd7-58X%gkbJ;#SU4iLUZ>s6N1!dWs9=%koPn~kI zCP~vjApshq>yDSe^-bu(P~AHo58vT#2sg+a7q&v?_u>8F9uPK#=Y@|z&?B506oCoB zv%ygitQT&}K%gf0A=N+>-arJDgN?PZk1%-XY-9K4b(}}@;2gJCCM4rUQa}Y`aF+@v z_n)DO3=l^95CUyAkC2CW=J(EFHZWnUSL3T7UVhn?aSoy`3+G0=LHQ@Ayc9hI(c42$ zifVyf%HLxg5T%=Tj!lNNVVgC*Yw=z2=iPjrv*kWkm0P#P?LQxzW%C9+B4J`dd$U>Y z9gud;)b-1{&%Cm(^YTIRvJ`Dn=xwqrt-7C9DUw$Gev9U_Rldk-&3EQ7DEvBrb^ij< zn~?ccV)i?zjZLlCsMz{ra^y~pj68#su8rRmZqzAKP)-nW(iW~+rEq~mrbOd zcKxpVOr@q&P{B!ucCMVV;1ri8)m1#8xW!AZnU-ZaR06W4?l&@|G$eH8Uh@4QOf=1I z!4KF5f@j0~xgGc7a11xmWHk2Rcf z+-!M`iI+*!o}&oyT*rkH=Q~dudEian2(C^2?Ny?t2J@eTACI{G*iA(2bH`!GJCwpg+UHXd0!Dd zk6DmFFFtgf#t>ArWT^g3N=2y(@1X|h8r(p4pl_xJeSu7HZ-TZRIS)0@p)&{kV1_CZ z;Oj*T|5e$j!t`ablz~MoViB;Cm8<{?6w;kP02m-ece)nPLMfEH1yzm}DX^CNYUz2? z=HKHrdfNm0R(<7K8}$ zA_LkqPi^w?+T<#<$|-NtdTG&nZdDkeMHwV5dY{FENfuGG0kHk&>LlFkKyeM%KD+IF z>U^4hG`(w$YXLCE^9y(6+%&E&g-c28#LE;1-mTTwJ+=M!y?=$-6FcoM3M0>y^Shle zYKv&lS%O?$oI>H&q9z-hF7A{NXRW$*snh9A@9ISbNit(0SWX+TG-zTWu#`U}ZfxKH zm`i;#72h{x)Vzgy!8-~Wl)tUnei7@i2FhcY40pp?x{i z#a<^a6muNS?5OTDuuo`(;GV;B70TU#y|aAQ*5Cb}oGVpb@kN)i+E;KFa3}ToaA~M- z$P3;t!mNZFyqV^8GM>|(Er4zbYK?9(zyV5^hAJEPLs_ojW0UdQ67<*gV%L`d*SWqy z-w$2S;9Mos%nnd`KM`*O?dSJGF;w#BE^9xg>GsEKoKx|AKbIS|38D^`CLO1^#m$18 zElwV+I0i~{AEe)HGHvN?tCj7%z63RLpDlNdaUi!&pLa#1--~>^v{KUV(c3UM5NM0w z?XeyCci$}se62uT@FffD_*PouZcFd`Goo<3L_UO5cGPz6v%s@ALNX$8D^-8q&tX!a z8Xybd+9WBAZ{Py)CR{F zEb)%?nx#-6tf>2YOg_iQ64=A)ld+SsaJO}Cm@S-Mj7b3G+@-Xiw{DXFr5oM2{=~HG zZ!2D)lkUvAIWXnUg03v|cG8|dH^4Jp>JnMa*Y0}mesXeO*Nbcso7Y1caWj!2!#tnT ztdRuY+aN@jCZnD3K&)Bp1?YwD0;;v!zYixfrgW_Z#)`u&R^8>q>F_R%Hf!nUHf>y) zN#T9x6;L%h=sK)3TMDC`$5OU=u3$Cv7I}>pN}S4`xl}iL*s=TD1F1DgN<{OyV=r zKs_WVYifcW=(E7ZPK9wx%&|JR#dF6-?|(5zqu9E@ZF?H^cl%bpPx}ktdkA}iL#o{%>}tOb=Ix!FNLJG3@&W)Lb646rK1#)1wTz+H!Em`=Y^%` zPLmhiIL<7byO&I_crGhEw*_*_NlFL_c(Z_3oEB6GdRkfOaD#m% zD`d?_+S=Az^2s;KPJy^@HVF(CR{+0CjDr_ctRG0*+uNj@?sLwJCC|x+=Jox;tQlOG zC5;@1x>=>}r*6*}v8tDQn&=ie5>>D3c-?v|Jq5MkGJ z!P|NFhC9Z>jt^DtS8fySh2Z)QXQkSgvBL1a8uqo^HRRxm`IA6L&bDpeMu*6eX4i^) zBOOC!?_@Q){k%9MAhqCz9)`A7gs$2%kwD~FMA6VpUpy4faaYbyc~LzK1)(d z_n32&WU)798!&C^fR8a|y+)^kSg@=a48iQATcdelc%eCxYC2R!sV849(wzivu8n4KD}b3-6699KZvB3Ph|U5B>6PMW)53u%kxz^T*zouj4* zdukCZST59ZMBWW;gr_tLZxOcD{1ls4YC2G)Ux>@s@3XJ9@c1q56 z(DZT$r7K|0&V07Hr8Sl{k~C;+=f-r~c#ZDcWQ^$r?;VWXG{F$bn!^Dm=OTHbdIFux zV=V075k$$`Lg;Ycr{U(ym4oxXCaCNPyx9&fd^_RmRs7w)h@p}Tn|yy>5PlvaWih0*MRuyrM-`uM)M)5scGK(5^XlDnW%<(m>tzArgWLbz zTk^TVU5bd@i`YoX`=JP;6*4gAyCKwm3`>ijr9woGWV!>NcaL?>kgk(vgVKJY)4#i! zvLnBKVK(8OI4@8|HqAl=ZnS16%Y|IRkgn74vAIm_rsBKjD}~_&L9epeCqoC{xLGG# zF26vhyBmZ1h4yd%Ib(dBHtx^aaylyEZ4=zo!M$Y+-Sk{-aysvnb9;&C)`unNAL+fU z@(Y%NNo%&93ni$LvT1J8?H)y zxtoyoT#fZ&>}m7Tt%-~kon2{`$gGl6Oxz8`n#;+Ia*|tR zlILmxcNWyyP7_!qjqt{^?e8aNlWlg$CfGX}RrnHVr$%c&3zX(1txK`S_Coi4kJjit z`P{|D3&fht0;GBDCTkq4QbG|j!(t`61={mt9yto>!O8Pt@uWj z7GjlruZ$bRxr@3rubo>9fCapAVH@(8wQ}6VPPv;`SC$C-?`yZej@t`49+duF&zbI8 zJV&FUzdJd4y9vGLwBE%&h}g!+UFIDS?bv=S&xJW}XA>H8+7UoMh<1ngcMv`dk#{gM z8zOAzn(b5|yZ~(K{dx22({(Or6Pm5EX*au~2Tm8Fop?{I=*8EBu|L#;-b^oI4Y4te zT3|DzS+|rRx!6C|P!bZf($jn+MVRHbXK6Thwg8H6v#j+p0(tp z*140RNRdboJgpaT{J{ca$ZX5%=XC!t3!49KAIgWJ{dA3Wx{gU7`;dZM>1Li{Q6pLG zNC+ma>k+FNNg+gHTOHqt;c-{)6oMF&n&mNeH&5<2ZcXLLx>%!CT2L=JuqF#IQc$i+g7CV0 zftAAk18uw1?_qULq%)8ilzhU_6n|RuoG|S;y|l4nd>4PVRoH} zpi`ujm~{jZf2!~OK>|9{K9vv6n>!?WJvOi3{&8%<(?c4wN*1S=H1IlF$PE&p_3D$c zhnpw}vXre@Ja1n3&Ok6rWnat|*FKX4%mr{_sUj;bm0P5i#5+iNfs6cz?W}v-X<1YY zKx#n*y&_rsNWQOqz34z_x&bn+FzaVo$o7Qye*@ukSo~nJt#DT$@{PF5widLvzDoD0 z)`L6gEE4o^EwOWLTxjHucPR_v3bcI1xkk6!St$1A6FK31B&Y-Ry;l9+E8YhIEhN(0 zLkqsYOGq8qoTKYI)xb`m>04u4z3_B@bmt7&Nw&aMLM3Ug)G|4x!Y|mY+*qBP#c@E< z7D$@6tos`%4SSrP;|f8!8GfF>_mIFB^jTRv*3LeO<7W31Xf zgxT|8$<f7aJ{EY>OF@#sT6lGe{LYbu`%n|RfhMMdG-ev$@(QqX+O^{M zyw#ealr^3s%nP^2GMj_JDr(S3(3=%RdSa7IDoahog<;! zW3cG#EWADg@+GK08m9dKO6S7fd}g{LL4;ILI#t|&EJxW9+{x`f?`+PEBZ*KmdmLq#?tmNo~k%E zTjThKlO0Fv+!0(1L%=OHNX1M46AInyK)S{9oW34@kz(r5`6 z%@_&Gmo)*AG+t!h+G+3J>&}|h3r)U?1uZ`z8SC};F7kaQJ1!uM*`S46E%qlijVR3N zz-1Z$bn==5pvKDff%Jk*GdiMO$?Krx!R$WWfuvu*+;&UE{7J zkiZQPWLqr@e_KN`9;p|9#MorKMEAY;YW~|}rUdjo&G#sGyZ3$`R{ioRJ4p~mC}m{> zS=c5mu-Rh$-jG1gP{4EHWSt8kY~hp_TUO_uxsJrny~qG(|2mb%&UlNuelyx6vDdMuX)ppC$sW9hc=x`#;*wOK_>}P$PHhT#cKMzlC1J9k3?8mS^P!`57 zySuq9h%JhD`Vn?_!A&I79Z6F=ow_VdY5qNQYJurLYh1GqI(4`C^#zrd%ZZ()B+71j z;e%Yd>FXJ~)oFAtliTf>Wis@$z}Pu7`{Gmv$4$&yxdP2`5!1-Rw4q*Hi!9<~Ijs)~ zN-gpNcG~wB90TR@PN>Ez3VZerjDW6s_*8zEYE zp#)?jVd3eT@Hd2she%^=?Tvh#)#)zp5?uE~3a0D-UGOEAEHHazdeX^^&J1vJn`vTi z)#kK(1FYPf+NdQEsK-V#yam~I@>(7HK5i{8fWu% z&PpLE>GMTBXHgcpsLvO*K8t!jZd4u?l0i6 z_o3YmQ?-8KW8uXR3Nzuo=}^8dVd~P|LxnXB67HN-dDabmzjadSskrXDDc&%@)9xSN9Vtd2}x=+z(YR zG2OQ>NcNcbN0DG0B!$_@O&1(j@b(d|XtYmPr~h|7iEGOpzYrvi9B394i(M}xi)t3j zs#;kL=T;AZO4W^@=yJp4X_>gPT4egxMwzB=_Qj=k<&-XKNb^;fpDE}yw13sGv&DBratU#=|ZUA-J0z6l<<8y0;GyR_Ty<#Ph^ zs%~r}*D34)6ZeJEop5*+l$Jw}Jd~tSydQXq4dpbJrNO=3Kvt|rSueCKjqC`l1t_D) zs`pV(HIo8CZo)jXUJa6vWE+_?yQ9IloJ!`36{n+X6e#W_ntzlLKSJ zWVv<_eSB}l^vKE1&y}5K=W4kS$`;1)9oLWe{kXB5<3avC=kiV0SeJ~E z1iqy2l?16ucB-Y&+;h03bySk#Dv9PUZCUX>30TQ-qZzO)hU)LYy|2TVYk}VIxJ%A~ z|8}4Bjxv$8yTG)4;FG;z(j+J?PV&%7(g5CFv?M30qzjk42b|9p($9+3D#_W;=tY+l zNlx3@V))lbbZb_GO%UaJ)X?WI?B;+qBEMO`A2CW^}>Rn(ar& zJ(~5oiF1;1iXe!)iFX~Hj6EHfk(0f(pk*&T_s3d@cWHsX>D_sKzd9PFQD@6C4{%D0 z<2q&s-R#+r%Wapmz;~49eNoq2^hEpLDd;}#)#nE4eGc|^%$^U&mz><{@&jjB*y%Tm zXTfm}m7R0P$t2Jvz4x*dO-ab5Bp0BhKw?Q`O)4n5zml$BQhda%SWB|3rTS#dMKEb6 zSSth5%g|(&vE7mRuYa1Sh2L=?l;4G_yP>rUl+J*$4<&^)Rfj;v-L<_Pf?JN(Y19pS z-vxJM^j?MD_anSiqfBS02Mo1vLurCGS)S)*B3F8gE-knwInhHKld;Z8f^IeGmX#GR zIHhIXT)-RpOw`{+I=DA+qv9r0_2LIhC2lQEwXG(4jGW3b@~Jk`0_o;$i?xt?%W@1C zW-n?%F3`d*8G2|z3|D|`9Xr#erTrXc1r06rp4=s*ldjVw3p>*^d&SWr0d|MS25EF} z|DCq?nV>J2l^UzjWfD$LcM_vbh_^rRW}Fh>q6Ds}WZ7c9MnUk@8CUkHY9VR8lv55lCyP`WrN z<1S9u|4RT$!n|f1N_vr&_>6Zgb?Zm@JQ+EeZmpU21a?zlr*a4qIf-w$=)lejG`=XG zW}@!n`}&XQ=p2_YJ7ok? z64WaxbD$^%>utHyQHsz>;8r+AL;evk=_cs@0ZjQeSB(2ugwoB}sNk6Iv2YR}|RI2x4R;I2o}}C2!4U%i-3fTG*kWLPjrW zUESB_f=cf?+g8Ur@)>TBX53AJu&!QMtpbE*vjX>!b)!17XtE@W$0p;SB#_h0w#brP zEhtg%R2n&X19ZO!$f?b_>4SbhZRamdSXNvjtLu-_|2KHyyW75#KONDxb8ZsBY3KGy zY+3A-%d+$rX5Uc)m+qD=_UBmn0tNdZdS7K{Ah^QQg5i`97dq8zbm5YHL9uYr@yVD% zAVJ)so~xvJC`y5(mP2%WQSYTBsB9mksOKz>*621)1!#I1YOCOyd*G80TK@o33~B${ zBg_AIbk&2^OoOKf!{W7J;$NZkX@XLUn#hb6W~N8Qxdfo-4uxL$a_ZB)5WO*q8>h)s zhI(^3L6lvD&1<9?-_(SsUZ=h{M>O*da^Ba`L~bC6u!ekzPHvDUC$mY{og)?WnxNP` zLpJYir+`{t35wa3T3O7YjtdFmrM2Wv#xwil`*sDN1xBor3y^|}g_ow4cW?i>G}p}k z@6ud1g!48Qg1Xxa3QrS>GGBq<7F}nMv$>U-5IKM=Um>*^zCS}LSEkxRE1nUVO`4vJ zMLnmXmBRukHFdIp-L;R@!wK&h7Hte?h~wlwPh#-b^d`oMUDdYqEaF83az*aAtsa zwRJ#G^Vv-nW1JM&^%A6cvd{xv@8b$lJKwIuFqEp-SSc9tVIn1$mc&XHCD3N2itck} z1fu6FN?{g7CKMa>eiXMVicKp>5!hlB+@NkVSa2BBu7t~vf(4&KVQZM=UI>5l2*1pS zlB1_?eE%Q7tKWz0DRA|76Xz;k7Yf3dMYCLDw~As*N_z1{Vcntxp(wVfI9{LAMA$hk zN&}a)z)CI+l~Zj^(^ZgWV>dq23-G?#9VY7Un&7;kMYEo3mF~CT%Azk2jCAUB|1app z-YY?Aa&u+ZmAEN^18)xSxmkm?n7hbW1G@y&y#O|<_q%k#Sem!5Q!}LTT?b=UDs6IYAHz_pQZURyY2J%+(u;zEMfsv7rRo$VUq z$nq8x`7g@3FN!TJh(0dr^96?w-h{Xcsi7x*@|YIxoxOn^ zba)M}-aMgapV=RZ3YfV~e?beZC{0V+4Dv5PY4so?nUf>cF0*To5%0A~ry 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 Date: Sat, 4 Feb 2023 04:41:23 -0600 Subject: [PATCH 3/4] Update style Fix issue in maintype() Add support for tags and persistent relations Condense some options --- .../export-template | 150 ++++++++++-------- 1 file changed, 83 insertions(+), 67 deletions(-) diff --git a/data/magic-cockatrice-cs-ech-2.0.mse-export-template/export-template b/data/magic-cockatrice-cs-ech-2.0.mse-export-template/export-template index 2da440543..2d7893109 100644 --- a/data/magic-cockatrice-cs-ech-2.0.mse-export-template/export-template +++ b/data/magic-cockatrice-cs-ech-2.0.mse-export-template/export-template @@ -20,28 +20,21 @@ file type: *.xml|*.xml|*.*|*.* option field: type: choice - name: version - choice: CS/ECH 2.0 -option field: - type:choice - name: Usage Guide - choice: https://tinyurl.com/csexporter + name: info + choice: CS/ECH 2.0, guide: https://tinyurl.com/ctexportv2 option field: type: text name: cockatrice Set Type description: The "set type" your set will appear as in Cockatrice. "Custom" should be the default. default: Custom -option field: - type: boolean - name: export Images - description: Whether or not to export images along with the XML. These images are recommended for Cockatrice use. - initial: yes option field: type: choice - name: images File Type - description: Which file extension you want the images exported as. JPG is lower quality but lower file size. + name: export Images + description: Export images along with the XML? Recommended for Cockatrice use. JPG is lower quality but lower file size. + choice: no choice: JPG choice: PNG + initial: no option field: type: boolean name: tokens In Separate XML @@ -57,49 +50,40 @@ option field: name: append String To Names description: Appended to the front of all card names and image names. option field: - type: boolean - name: include Common - description: Whether to include common cards or not. - initial: yes -option field: - type: boolean - name: include Uncommon - description: Whether to include uncommon cards or not. - initial: yes -option field: - type: boolean - name: include Rare - description: Whether to include rare cards or not. - initial: yes -option field: - type: boolean - name: include Mythic - description: Whether to include mythic rare cards or not. - initial: yes -option field: - type: boolean - name: include Basic Land - description: Whether to include basic land rarity cards or not. - initial: yes -option field: - type: boolean - name: include Tokens - description: Whether to include tokens or not. - initial: yes -option field: - type: boolean - name: include Special - description: Whether to include special rarity cards or not. - initial: yes - + type: multiple choice + name: rarities to export + choice: common + choice: uncommon + choice: rare + choice: mythic rare + choice: basic land + choice: special + choice: token + choice: masterpiece + initial: common, uncommon, rare, mythic rare, basic land, special, token, masterpiece +option style: + rarities to export: + render style: checklist + direction: vertical + export Images: + render style: both + choice images: + no: {built_in_image("bool_no")} + JPG: {built_in_image("bool_yes")} + PNG: {built_in_image("bool_yes")} script: splitter_name := {false} ## experimental future thing for splitting dfc images #determine if the card is a type that is a "token" i.e. it should be batched with tokens instead of with other cards is_token := {contains(card.shape, match:"token") or contains(card.shape, match:"emblem") or contains(card.shape, match:"rulestip") } is_double := {contains(card.shape, match:"double") } + + file_type := {if options.export_Images == "PNG" then "png" else "jpg"} #determine if the card is of a rarity that should be included included_rarity := { + (is_token() and chosen(options.rarities_to_export, choice:"token")) or chosen(options.rarities_to_export, choice:card.rarity) + } + included_rarity2 := { (is_token() and options.include_Tokens) or (card.rarity == "basic land" and options.include_Basic_Land) or (card.rarity == "common" and options.include_Common) @@ -114,6 +98,7 @@ script: replace@(match: "’",replace:"'") + #replace bad apostrophe with good apostrophe replace@(match:":", replace:"")+ #remove colons replace@(match:";", replace:"")+ #remove semicolons + replace@(match:"\n", replace:"")+ #remove linebreaks replace@(match:"\\.", replace:"") #remove periods # escape special xml characters @@ -132,9 +117,12 @@ script: #determining what name should be used for the card card_name := { if exporter_name_grabber(exporter_name_filter(card.notes)) != "" then exporter_name_grabber(exporter_name_filter(card.notes)) else card.name } + #surround mana symbols in curly brackets + format_mana := replace@(match:"(CHAOS|[1-9][0-9]+(?:\\/.)?|.\\/.\\/.|.\\/.|[+-]?[^.,: ])", replace:{"\{"+_1+"}"}, in_context:"", input) != "" then " attach=\"attach\"" else ""} + + #helpers to find if persistent is desired for this token relation, and generate the requisite XML + add_persistent := {if filter_text(match:"<(conjure|persistent)>", input) != "" then " persistent=\"persistent\"" else ""} #helper functions for converted_related later - related_entry_regex := "(.+?[^[:space:]]);" + related_entry_regex := "(.+?[^[:space:]])(?:;|\n|$)" #convert the !related command field to XML blocks convert_related := @@ -157,12 +148,25 @@ script: replace@(match:"!",replace: "") + #blank out the command ender #for every other card name, surround it with reverse-related tags and put in relevant attributes - {for each entry in (break_text(match:related_entry_regex, input)) do ("\" + xml_escape(strip_card_name(entry)) + "\\n")} + {for each entry in (break_text(match:related_entry_regex, input)) do ("\" + xml_escape(strip_card_name(entry)) + "\\n")} #remove accidentily created empty XML blocks - remove_empty := replace@(match:"\\", replace:"") + remove_empty := replace@(match:"\<(reverse-)?related>\", replace:"") + + #convert the !token command field to XML blocks + convert_token := + replace@(match: "!tokens? ?\n?", replace:"")+ #blank out the related command itself + replace@(match: "\<",replace:"<") + #replace junk Start of Header characters with proper "less than sign"s + replace@(match: "’",replace:"'") + #replace bad apostrophe with good apostrophe + replace@(match: "",replace:"") + #replace accidentily capital X with lowercase X + replace@(match:"!",replace: "") + #blank out the command ender + + #for every other card name, surround it with reverse-related tags and put in relevant attributes + {for each entry in (break_text(match:related_entry_regex, input)) do ("\" + xml_escape(strip_card_name(entry)) + "\\n")} + filter_related := filter_text@(match:"!relate ?[^!]+!?") + filter_token := filter_text@(match:"!tokens? ?[^!]+!?") #functions for the !tapped command contains_tapped := contains@(match:"!tapped") @@ -186,7 +190,7 @@ script: else if contains(card.type, match:"Instant") then "Instant" else if contains(card.type, match:"Artifact") then "Artifact" else if contains(card.type, match:"Enchantment") then "Enchantment" - else xml_escape(replace(match:"^.* ", replace:"", replace(match:" —.*$", replace:"", card.type))) + else xml_escape(replace(match:"^.* ", replace:"", replace(match:"()? —.*$", replace:"", card.type))) ) +"\" } @@ -254,6 +258,7 @@ script: + CIPT() # Rules Text +"\n "+"\"+xml_escape(card_rules_text())+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } write_token := { @@ -288,7 +293,7 @@ script: + "\n "+"\1\" # Reverse Related #if there is a !related block in the cards notes, set up the reverse-related XML elements - + (if filter_related(card.notes) != "" then remove_empty("\n" + convert_related(filter_related(card.notes)))) + + (if filter_related(card.notes) != "" then remove_empty("\n " + convert_related(filter_related(card.notes)))) +"\n "+"\" } write_flip := { @@ -360,6 +365,7 @@ script: +"\" # Rules Text +"\n "+"\"+xml_escape(card_rules_text()+"\n--- \n"+card_rules_text_2())+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } write_double := { @@ -375,7 +381,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color +"\n "+"\" @@ -403,6 +409,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -417,7 +424,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color II +"\n "+"\" @@ -442,6 +449,7 @@ script: # Rules Text II +"\n "+"\"+xml_escape(card_rules_text_2() +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } @@ -499,6 +507,7 @@ script: +(if card.loyalty_cost_4 !="" then ": ") +(if contains(paragraph_count(card.rule_text), match:"•••") then split_text(match:"\n", card.rule_text).3))) +"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } write_double_walker := { @@ -514,7 +523,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color +"\n "+"\" @@ -557,6 +566,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -570,7 +580,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color II +"\n "+"\" @@ -610,6 +620,7 @@ script: +(if contains(paragraph_count(card.rule_text_2), match:"••") then split_text(match:"\n", card.rule_text_2).2) +(if contains(paragraph_count(card.rule_text_2), match:"•••") then "\n")) +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } write_sparker := { @@ -625,7 +636,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color +"\n "+"\" @@ -653,6 +664,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -666,7 +678,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color II +"\n "+"\" @@ -706,6 +718,7 @@ script: +(if contains(paragraph_count(card.rule_text_2), match:"••") then split_text(match:"\n", card.rule_text_2).2) +(if contains(paragraph_count(card.rule_text_2), match:"•••") then "\n")) +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } write_sacrificer := { @@ -721,7 +734,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+options.append_String_To_Names+strip_card_name(card_name())+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color +"\n "+"\" @@ -764,6 +777,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -778,7 +792,7 @@ script: else if contains(card.rarity,match:"mythic") then "\"mythic\"" else if contains(card.rarity,match:"rare") then "\"rare\"" else "\"\"") - + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + to_lower(options.images_File_Type) + "\" >"+setcode+"\" + + " splitterPath=\""+"/"+strip_card_name(card.name_2)+"." + file_type() + "\" >"+setcode+"\" +"\n "+"\" # Color II +"\n "+"\" @@ -803,6 +817,7 @@ script: # Rules Text II +"\n "+"\"+xml_escape(card_rules_text_2() +"\n---\n(Front): "+strip_card_name(card_name()))+"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } write_leveler := { @@ -854,6 +869,7 @@ script: +(if card.pt_3 != "" then "\n"+card.pt_3) +"\n"+card.rule_text_3) +"\" + + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) +"\n "+"\" } @@ -878,14 +894,14 @@ script: write_image_file( card, directory: set.set_code, - file: (options.append_String_To_Names+strip_card_name(card_name())+(if is_token() and options.append_Set_Code_To_Tokens then " " + set.set_code else "")+if splitter_name() and is_double() then "_" + strip_card_name(card.name_2)) + "." + to_lower(options.images_File_Type), + file: (options.append_String_To_Names+strip_card_name(card_name())+(if is_token() and options.append_Set_Code_To_Tokens then " " + set.set_code else "")+if splitter_name() and is_double() then "_" + strip_card_name(card.name_2)) + "." + file_type(), width: (if contains(card.shape, match:"split") or contains(card.shape, match:"double") then 752 else 375), height: 523 ) } #if images are set to be rendered, render all images of rarities that have been selected - write_images := if options.export_Images then for each card in filter_list(cards,filter:{included_rarity(card:input)}) do write_image() else "" + write_images := if options.export_Images != "no" then for each card in filter_list(cards,filter:{included_rarity(card:input)}) do write_image() else "" write_cards := to_text(for each card in cards do write_card()) write_all_tokens := to_text(for each card in cards do write_token_if_token()) @@ -893,7 +909,7 @@ script: #Main export script #tokens in Separate XML - if (options.include_Tokens and options.tokens_In_Separate_XML) then write_text_file(file:set.set_code + " Tokens" + ".xml", to_string("\n\n \n"+write_all_tokens+"\n\n \n")) + if (chosen(options.rarities_to_export, choice:"token") and options.tokens_In_Separate_XML) then write_text_file(file:set.set_code + " Tokens" + ".xml", to_string("\n\n \n"+write_all_tokens+"\n\n \n")) #other cards - to_string("\n\n \n \n "+setcode+"\n "+xml_escape(set.title)+"\n "+xml_escape(options.cockatrice_Set_Type)+"\n \n \n \n"+write_cards+if (options.include_Tokens and not(options.tokens_In_Separate_XML)) then ("\n\n Tokens\n"+write_all_tokens)+"\n\n \n") + to_string("\n\n \n \n "+setcode+"\n "+xml_escape(set.title)+"\n "+xml_escape(options.cockatrice_Set_Type)+"\n \n \n \n"+write_cards+if (chosen(options.rarities_to_export, choice:"token") and not(options.tokens_In_Separate_XML)) then ("\n\n Tokens\n"+write_all_tokens)+"\n\n \n") From 7723323dc3340e746a2659b60c698396102f3391 Mon Sep 17 00:00:00 2001 From: CajunAvenger Date: Sun, 5 Feb 2023 19:17:08 -0600 Subject: [PATCH 4/4] Finishing touches fixed intending and extra linebreak on related changed name to Cockatrice v2 --- .../README.txt | 0 .../export-template | 40 +++++++++--------- .../icon.png | Bin 3 files changed, 20 insertions(+), 20 deletions(-) rename data/{magic-cockatrice-cs-ech-2.0.mse-export-template => magic-cockatrice-v2.mse-export-template}/README.txt (100%) rename data/{magic-cockatrice-cs-ech-2.0.mse-export-template => magic-cockatrice-v2.mse-export-template}/export-template (95%) rename data/{magic-cockatrice-cs-ech-2.0.mse-export-template => magic-cockatrice-v2.mse-export-template}/icon.png (100%) diff --git a/data/magic-cockatrice-cs-ech-2.0.mse-export-template/README.txt b/data/magic-cockatrice-v2.mse-export-template/README.txt similarity index 100% rename from data/magic-cockatrice-cs-ech-2.0.mse-export-template/README.txt rename to data/magic-cockatrice-v2.mse-export-template/README.txt diff --git a/data/magic-cockatrice-cs-ech-2.0.mse-export-template/export-template b/data/magic-cockatrice-v2.mse-export-template/export-template similarity index 95% rename from data/magic-cockatrice-cs-ech-2.0.mse-export-template/export-template rename to data/magic-cockatrice-v2.mse-export-template/export-template index 2d7893109..380572a20 100644 --- a/data/magic-cockatrice-cs-ech-2.0.mse-export-template/export-template +++ b/data/magic-cockatrice-v2.mse-export-template/export-template @@ -1,9 +1,9 @@ mse version: 0.3.8 short name: Cockatrice -full name: CS/ECH 2.0 +full name: Exporter v2.0 position hint: 007 icon: icon.png -version: 2023-01-22 +version: 2023-02-05 installer group: magic/Export/cockatrice depends on: @@ -21,7 +21,7 @@ file type: *.xml|*.xml|*.*|*.* option field: type: choice name: info - choice: CS/ECH 2.0, guide: https://tinyurl.com/ctexportv2 + choice: Updated 2023/02, guide: https://tinyurl.com/ctexportv2 option field: type: text name: cockatrice Set Type @@ -148,10 +148,10 @@ script: replace@(match:"!",replace: "") + #blank out the command ender #for every other card name, surround it with reverse-related tags and put in relevant attributes - {for each entry in (break_text(match:related_entry_regex, input)) do ("\" + xml_escape(strip_card_name(entry)) + "\\n")} + {for each entry in (break_text(match:related_entry_regex, input)) do ("\n \" + xml_escape(strip_card_name(entry)) + "\")} #remove accidentily created empty XML blocks - remove_empty := replace@(match:"\<(reverse-)?related>\", replace:"") + remove_empty := replace@(match:" \<(reverse-)?related>\", replace:"") #convert the !token command field to XML blocks convert_token := @@ -162,7 +162,7 @@ script: replace@(match:"!",replace: "") + #blank out the command ender #for every other card name, surround it with reverse-related tags and put in relevant attributes - {for each entry in (break_text(match:related_entry_regex, input)) do ("\" + xml_escape(strip_card_name(entry)) + "\\n")} + {for each entry in (break_text(match:related_entry_regex, input)) do ("\n \" + xml_escape(strip_card_name(entry)) + "\")} filter_related := filter_text@(match:"!relate ?[^!]+!?") @@ -258,7 +258,7 @@ script: + CIPT() # Rules Text +"\n "+"\"+xml_escape(card_rules_text())+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } write_token := { @@ -290,10 +290,10 @@ script: # Rules Text +"\n "+"\"+xml_escape(card_rules_text())+"\" # Token - + "\n "+"\1\" + + "\n "+"\1\" # Reverse Related #if there is a !related block in the cards notes, set up the reverse-related XML elements - + (if filter_related(card.notes) != "" then remove_empty("\n " + convert_related(filter_related(card.notes)))) + + (if filter_related(card.notes) != "" then remove_empty(convert_related(filter_related(card.notes)))) +"\n "+"\" } write_flip := { @@ -365,7 +365,7 @@ script: +"\" # Rules Text +"\n "+"\"+xml_escape(card_rules_text()+"\n--- \n"+card_rules_text_2())+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } write_double := { @@ -409,7 +409,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -449,7 +449,7 @@ script: # Rules Text II +"\n "+"\"+xml_escape(card_rules_text_2() +"\n---\n(Front): "+strip_card_name(card_name()))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } @@ -507,7 +507,7 @@ script: +(if card.loyalty_cost_4 !="" then ": ") +(if contains(paragraph_count(card.rule_text), match:"•••") then split_text(match:"\n", card.rule_text).3))) +"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } write_double_walker := { @@ -566,7 +566,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -620,7 +620,7 @@ script: +(if contains(paragraph_count(card.rule_text_2), match:"••") then split_text(match:"\n", card.rule_text_2).2) +(if contains(paragraph_count(card.rule_text_2), match:"•••") then "\n")) +"\n---\n(Front): "+strip_card_name(card_name()))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } write_sparker := { @@ -664,7 +664,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -718,7 +718,7 @@ script: +(if contains(paragraph_count(card.rule_text_2), match:"••") then split_text(match:"\n", card.rule_text_2).2) +(if contains(paragraph_count(card.rule_text_2), match:"•••") then "\n")) +"\n---\n(Front): "+strip_card_name(card_name()))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } write_sacrificer := { @@ -777,7 +777,7 @@ script: +"\n---\n(Back): "+strip_card_name(card.name_2))+"\" # Name of the related card +"\n "+"\"+xml_escape(strip_card_name(card.name_2))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" +"\n "+"\" # Name II @@ -817,7 +817,7 @@ script: # Rules Text II +"\n "+"\"+xml_escape(card_rules_text_2() +"\n---\n(Front): "+strip_card_name(card_name()))+"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } write_leveler := { @@ -869,7 +869,7 @@ script: +(if card.pt_3 != "" then "\n"+card.pt_3) +"\n"+card.rule_text_3) +"\" - + (if filter_token(card.notes) != "" then remove_empty("\n " + convert_token(filter_token(card.notes)))) + + (if filter_token(card.notes) != "" then remove_empty(convert_token(filter_token(card.notes)))) +"\n "+"\" } diff --git a/data/magic-cockatrice-cs-ech-2.0.mse-export-template/icon.png b/data/magic-cockatrice-v2.mse-export-template/icon.png similarity index 100% rename from data/magic-cockatrice-cs-ech-2.0.mse-export-template/icon.png rename to data/magic-cockatrice-v2.mse-export-template/icon.png