--- loncom/homework/cleanxml/xml_to_loncapa.pm 2016/01/06 16:44:32 1.5 +++ loncom/homework/cleanxml/xml_to_loncapa.pm 2016/11/10 21:53:56 1.10 @@ -1,7 +1,7 @@ # The LearningOnline Network # convert_file takes a well-formed XML file content and converts it to LON-CAPA syntax. # -# $Id: xml_to_loncapa.pm,v 1.5 2016/01/06 16:44:32 damieng Exp $ +# $Id: xml_to_loncapa.pm,v 1.10 2016/11/10 21:53:56 damieng Exp $ # # Copyright Michigan State University Board of Trustees # @@ -38,14 +38,16 @@ use warnings; use XML::LibXML; -my @loncapa_block = ('parameter','location','answer','foil','image','polygon','rectangle','text','conceptgroup','itemgroup','item','label','data','function','array','unit','answergroup','functionplotresponse','functionplotruleset','functionplotelements','functionplotcustomrule','essayresponse','hintpart','formulahint','numericalhint','reactionhint','organichint','optionhint','radiobuttonhint','stringhint','customhint','mathhint','formulahintcondition','numericalhintcondition','reactionhintcondition','organichintcondition','optionhintcondition','radiobuttonhintcondition','stringhintcondition','customhintcondition','mathhintcondition','imageresponse','foilgroup','datasubmission','textfield','hiddensubmission','radiobuttonresponse','rankresponse','matchresponse','import','style','script','window','block','library','notsolved','part','postanswerdate','preduedate','problem','problemtype','randomlabel','bgimg','labelgroup','randomlist','solved','while','tex','print','web','gnuplot','curve','Task','IntroParagraph','ClosingParagraph','Question','QuestionText','Setup','Instance','InstanceText','Criteria','CriteriaText','GraderNote','languageblock','translated','lang','instructorcomment','dataresponse','togglebox','standalone','comment','drawimage','allow','displayduedate','displaytitle','responseparam','organicstructure','scriptlib','parserlib','drawoptionlist','spline','backgroundplot','plotobject','plotvector','drawvectorsum','functionplotrule','functionplotvectorrule','functionplotvectorsumrule','axis','key','xtics','ytics','title','xlabel','ylabel','hiddenline','dtm','stringresponse','optionresponse','numericalresponse','formularesponse','mathresponse','organicresponse','reactionresponse','customresponse','externalresponse', 'hint', 'hintgroup'); +# LON-CAPA block elements that cannot be found within startouttext/endouttext +my @loncapa_block = ('parameter','location','answer','foil','image','polygon','rectangle','text','conceptgroup','itemgroup','item','label','data','function','array','unit','answergroup','functionplotresponse','functionplotruleset','functionplotelements','functionplotcustomrule','essayresponse','hintpart','formulahint','numericalhint','reactionhint','organichint','optionhint','radiobuttonhint','stringhint','customhint','mathhint','formulahintcondition','numericalhintcondition','reactionhintcondition','organichintcondition','optionhintcondition','radiobuttonhintcondition','stringhintcondition','customhintcondition','mathhintcondition','imageresponse','foilgroup','datasubmission','textfield','hiddensubmission','radiobuttonresponse','rankresponse','matchresponse','import','style','script','window','block','library','notsolved','part','postanswerdate','preduedate','problem','problemtype','randomlabel','bgimg','labelgroup','randomlist','solved','while','tex','print','web','gnuplot','curve','Task','IntroParagraph','ClosingParagraph','Question','QuestionText','Setup','Instance','InstanceText','Criteria','CriteriaText','GraderNote','languageblock','instructorcomment','dataresponse','togglebox','standalone','comment','drawimage','allow','displayduedate','displaytitle','responseparam','organicstructure','scriptlib','parserlib','drawoptionlist','spline','backgroundplot','plotobject','plotvector','drawvectorsum','functionplotrule','functionplotvectorrule','functionplotvectorsumrule','axis','key','xtics','ytics','title','xlabel','ylabel','hiddenline','dtm','stringresponse','optionresponse','numericalresponse','formularesponse','mathresponse','organicresponse','reactionresponse','customresponse','externalresponse', 'hint', 'hintgroup'); -my @loncapa_inline = ('display','m','lm','chem','num','parse','algebra','displayweight','displaystudentphoto'); # not textline +# LON-CAPA elements that can be found within startouttext/endouttext: +my @loncapa_in_text = ('display','m','lm','chem','num','parse','algebra','displayweight','displaystudentphoto','translated','lang'); # not textline # HTML elements that trigger the addition of startouttext/endouttext -my @html_trigger = ('header','footer','aside','h1','h2','h3','h4','h5','h6','li','dd','dt','tbody','tr','caption','thead','tfoot','td','th','span','a','em','strong','b','i','sup','sub','pre','code','kbd','samp','cite','q','tt','ins','del','var','small','big','br','hr','address','blockquote','img','figure','figcaption','object','param','embed','applet','video','source','audio','map','area','canvas','form','input','select','optgroup','option','textarea','fieldset','legend','button','iframe','section','div','p','ul','ol','dl','table'); +my @html_trigger = ('header','footer','aside','h1','h2','h3','h4','h5','h6','li','dd','dt','tbody','tr','caption','thead','tfoot','td','th','span','a','em','strong','b','i','sup','sub','pre','code','kbd','samp','cite','q','tt','ins','del','var','small','big','br','hr','address','blockquote','figure','figcaption','object','param','embed','applet','video','source','audio','map','area','canvas','form','input','select','optgroup','option','textarea','fieldset','legend','button','iframe','section','div','p','ul','ol','dl','table'); -my @simple_data = ('polygon', 'rectangle', 'vector', 'value', 'answer', 'title', 'data', 'function', 'xlabel', 'ylabel', 'tic', 'parserlib', 'scriptlib', 'import', 'tex', 'text', 'image', 'display', 'm', 'lm', 'num', 'algebra', 'chem', 'parse', 'title', 'style', 'script', 'ins', 'del', 'label', 'option', 'textarea', 'legend' ); +my @simple_data = ('polygon', 'rectangle', 'vector', 'value', 'answer', 'title', 'data', 'function', 'xlabel', 'ylabel', 'tic', 'parserlib', 'scriptlib', 'import', 'tex', 'text', 'image', 'display', 'm', 'lm', 'num', 'algebra', 'chem', 'parse', 'title', 'style', 'script', 'ins', 'del', 'label', 'option', 'textarea', 'legend','comment'); my @inline_responses = ('stringresponse','optionresponse','numericalresponse','formularesponse','mathresponse','organicresponse','reactionresponse','customresponse','externalresponse'); @@ -81,7 +83,7 @@ sub node_to_string { if (defined $parent->parentNode) { $grandparent_name = $parent->parentNode->nodeName; } - my @no_escape = ('m', 'script', 'display', 'parse', 'answer'); + my @no_escape = ('m', 'script', 'style', 'display', 'parse', 'answer'); if (string_in_array(\@no_escape, $parent_name) && ($parent_name ne 'answer' || (defined $grandparent_name && @@ -145,6 +147,11 @@ sub add_outtext { return; } convert_paragraphs($node); + if ($node->nodeName eq 'hintgroup' && !defined $node->firstChild) { + # empty hintgroup: colorful editor needs start/end outtext + add_endouttext($node, undef); + add_startouttext($node, $node->firstChild); + } my $next; my $in_outtext = 0; for (my $child=$node->firstChild; defined $child; $child=$next) { @@ -178,7 +185,7 @@ sub inside_outtext { return 1; } } - if ($node->nodeType == XML_ELEMENT_NODE && string_in_array(\@loncapa_inline, $node->nodeName)) { + if ($node->nodeType == XML_ELEMENT_NODE && string_in_array(\@loncapa_in_text, $node->nodeName)) { return 1; } return 0; @@ -255,6 +262,21 @@ sub add_endouttext { } else { $parent->appendChild($endouttext); } + # replace spaces afterwards by a \n + indentation + my $next = $endouttext->nextSibling; + if (defined $next && $next->nodeType == XML_TEXT_NODE) { + my $v = $next->nodeValue; + if ($v =~ /^ /) { + $v =~ s/^ +//; + if ($parent->firstChild->nodeType == XML_TEXT_NODE && + $parent->firstChild->nodeValue =~ /^\n +$/) { + $v = $parent->firstChild->nodeValue.$v; + } else { + $v = "\n".$v; + } + $next->setData($v); + } + } } # Convert paragraph children when one contains an inline response into content +
@@ -289,6 +311,9 @@ sub convert_paragraphs { # we only add a br if there is something after my $br = $doc->createElement('br'); $parent->insertBefore($br, $next); + # add another br to make up for the p margin + $br = $doc->createElement('br'); + $parent->insertBefore($br, $next); } } }