Diff for /loncom/publisher/testbankimport.pm between versions 1.14 and 1.15

version 1.14, 2008/06/05 01:24:59 version 1.15, 2008/06/17 13:00:19
Line 34  use Apache::lonnet; Line 34  use Apache::lonnet;
 use HTML::Entities();  use HTML::Entities();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::lonupload;  use Apache::lonupload;
   use Apache::londocs;
 use File::Basename();  use File::Basename();
 use LONCAPA();  use LONCAPA();
   use File::MMagic;
   use XML::DOM;
   use RTF::HTMLConverter;
   use HTML::TokeParser;
   
 # ---------------------------------------------------------------- Display Control  # ---------------------------------------------------------------- Display Control
 sub display_control {  sub display_control {
Line 56  sub calculate_page($$) { Line 61  sub calculate_page($$) {
     return 0 if $dir eq 'BackToStart';      return 0 if $dir eq 'BackToStart';
 }  }
   
   sub jscript_zero {
       my ($webpath,$jsref) = @_;
       my $start_page =
           &Apache::loncommon::start_page('Create Testbank directory',undef,
                                          {'only_body'   => 1,
                                           'js_ready'    => 1,});
       my $end_page =
           &Apache::loncommon::end_page({'js_ready' => 1,});
       my %lt = &Apache::lonlocal::texthash(
                                            loca => 'Location',
                                            newd => 'New Directory',
                                            ente => 'Enter the name of the new directory where you will save the converted testbank questions',
                                            go  => 'Go',
                                           );
       $$jsref = <<"END_SCRIPT";
   function createWin() {
       document.info.newdir.value = "";
       newWindow = window.open("","CreateDir","HEIGHT=400,WIDTH=750,scrollbars=yes")
       newWindow.document.open()
       newWindow.document.write('$start_page')
       newWindow.document.write("<img border='0' src='/adm/lonInterFace/author.jpg' alt='[Author Header]'>\\n")
       newWindow.document.write("<h3>$lt{'loca'}: <tt>$webpath</tt></h3><h3>$lt{'newd'}</h3>\\n")
       newWindow.document.write("<form name='fileaction' action='/adm/cfile' method='post'>\\n")
       newWindow.document.write("$lt{'ente'}.<br /><br />")
       newWindow.document.write("<input type='hidden' name='filename' value='$webpath'>")
       newWindow.document.write("<input type='hidden' name='action' value='newdir'>")
       newWindow.document.write("<input type='hidden' name='callingmode' value='testbank'>")
       newWindow.document.write("$webpath<input type='text' name='newfilename' value=''/>")
       newWindow.document.write("<input type='button' value='$lt{'go'}' onClick='document.fileaction.submit();' /></form>")
       newWindow.document.write('$end_page')
       newWindow.document.close()
       newWindow.focus()
   }
   
   END_SCRIPT
       return;
   }
   
   
 # ---------------------------------------------------------------- Jscript One  # ---------------------------------------------------------------- Jscript One
   
 sub jscript_one {  sub jscript_one {
Line 89  END_SCRIPT Line 133  END_SCRIPT
     if (exists($env{'form.blocks'}) ) {      if (exists($env{'form.blocks'}) ) {
         $$jsref .= qq|          $$jsref .= qq|
     document.forms.display.blocks.value = $env{'form.blocks'}\n|;      document.forms.display.blocks.value = $env{'form.blocks'}\n|;
     } elsif (exists($env{'form.qnumformat'}) ) {      }
       if (exists($env{'form.qnumformat'}) ) {
         $$jsref .= <<"TO_HERE";          $$jsref .= <<"TO_HERE";
     for (iter=0; iter<document.forms.display.qnumformat.length; iter++) {      for (iter=0; iter<document.forms.display.qnumformat.length; iter++) {
         if(document.forms.display.qnumformat.options[iter].value == "$env{'form.qnumformat'}") {          if(document.forms.display.qnumformat.options[iter].value == "$env{'form.qnumformat'}") {
Line 243  function colSet(caller) { Line 288  function colSet(caller) {
     }      }
     else {      else {
         if ((poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MC") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MA") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "Ord")) {          if ((poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MC") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MA") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "Ord")) {
             poolForm.elements[caller*5+4].options[0] = new Option("Please Select","-1",true,true)              poolForm.elements[caller*5+4].options[0] = new Option("Select","-1",true,true)
             poolForm.elements[caller*5+4].options[1] = new Option("a.","lcperiod",false,false)              poolForm.elements[caller*5+4].options[1] = new Option("a.","lcperiod",false,false)
             poolForm.elements[caller*5+4].options[2] = new Option("A.","ucperiod",false,false)              poolForm.elements[caller*5+4].options[2] = new Option("A.","ucperiod",false,false)
             poolForm.elements[caller*5+4].options[3] = new Option("(a)","lcparen",false,false)              poolForm.elements[caller*5+4].options[3] = new Option("(a)","lcparen",false,false)
Line 268  function colSet(caller) { Line 313  function colSet(caller) {
     }      }
     else {      else {
         if ((poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MA") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "FIB"))  {          if ((poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "MA") || (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "FIB"))  {
             poolForm.elements[caller*5+5].options[0] = new Option("Please Select","-1",true,true)              poolForm.elements[caller*5+5].options[0] = new Option("Select","-1",true,true)
             poolForm.elements[caller*5+5].options[1] = new Option("single answer","single",false,false)              poolForm.elements[caller*5+5].options[1] = new Option("single answer","single",false,false)
             poolForm.elements[caller*5+5].options[2] = new Option("comma","comma",false,false)              poolForm.elements[caller*5+5].options[2] = new Option("comma","comma",false,false)
             poolForm.elements[caller*5+5].options[3] = new Option("space","space",false,false)              poolForm.elements[caller*5+5].options[3] = new Option("space","space",false,false)
Line 277  function colSet(caller) { Line 322  function colSet(caller) {
         }          }
         else {          else {
             if (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "Ord") {              if (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "Ord") {
                 poolForm.elements[caller*5+5].options[0] = new Option("Please Select","-1",true,true)                  poolForm.elements[caller*5+5].options[0] = new Option("Select","-1",true,true)
                 poolForm.elements[caller*5+5].options[1] = new Option("comma","comma",false,false)                  poolForm.elements[caller*5+5].options[1] = new Option("comma","comma",false,false)
                 poolForm.elements[caller*5+5].options[2] = new Option("space","space",false,false)                  poolForm.elements[caller*5+5].options[2] = new Option("space","space",false,false)
                 poolForm.elements[caller*5+5].options[3] = new Option("new line","line",false,false)                  poolForm.elements[caller*5+5].options[3] = new Option("new line","line",false,false)
Line 285  function colSet(caller) { Line 330  function colSet(caller) {
             }              }
             else {               else { 
                 if (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "TF") {                  if (poolForm.elements[caller*5+3].options[poolForm.elements[caller*5+3].selectedIndex].value == "TF") {
                     poolForm.elements[caller*5+5].options[0] = new Option("Please Select","-1",true,true)                      poolForm.elements[caller*5+5].options[0] = new Option("Select","-1",true,true)
                     poolForm.elements[caller*5+5].options[1] = new Option("True or False","word",false,false)                      poolForm.elements[caller*5+5].options[1] = new Option("True or False","word",false,false)
                     poolForm.elements[caller*5+5].options[2] = new Option("true or false","word",false,false)                      poolForm.elements[caller*5+5].options[2] = new Option("true or false","word",false,false)
                     poolForm.elements[caller*5+5].options[3] = new Option("TRUE or FALSE","word",false,false)                      poolForm.elements[caller*5+5].options[3] = new Option("TRUE or FALSE","word",false,false)
Line 343  TO_HERE Line 388  TO_HERE
 # ---------------------------------------------------------------- Jscript Three  # ---------------------------------------------------------------- Jscript Three
   
 sub jscript_three {  sub jscript_three {
     my ($fullpath,$jsref) = @_;      my ($webpath,$jsref) = @_;
     my $source = '';      my $source = '';
     if (exists($env{'form.go'}) ) {      if (exists($env{'form.go'}) ) {
         $source = $env{'form.go'};          $source = $env{'form.go'};
     }      }
   
     my %body_layout = ('rightmargin'  => "0",  
        'leftmargin'   => "0",  
        'marginwidth'  => "0",  
        'topmargin'    => "0",  
        'marginheight' => "0");  
   
     my $start_page =   
  &Apache::loncommon::start_page('Create Testbank directory',undef,  
        {'only_body'   => 1,  
  'add_entries' => \%body_layout,  
  'js_ready'    => 1,});  
     my $end_page =   
  &Apache::loncommon::end_page({'js_ready' => 1,});  
     $$jsref = <<"END_OF_ONE";      $$jsref = <<"END_OF_ONE";
 function verify() {  
     if ((document.forms.dataForm.newdir.value == '')  || (!document.forms.dataForm.newdir.value)) {  
         alert("Step 4: You must choose a destination directory for the import")   
         return false  
     }  
     return true  
 }   
   
 function nextPage() {  function nextPage() {
     if (verify()) {      if (verify()) {
         document.forms.dataForm.go.value="NextPage"          document.forms.dataForm.go.value="NextPage"
         document.forms.dataForm.submit()          document.forms.dataForm.submit();
     }      }
 }  }
   
 function backPage() {  function backPage() {
     document.forms.dataForm.go.value="PreviousPage"      document.forms.dataForm.go.value="PreviousPage"
     document.forms.dataForm.submit()      document.forms.dataForm.submit()
 }  }
   
 function createWin() {  
     document.dataForm.newdir.value = "";  
     newWindow = window.open("","CreateDir","HEIGHT=400,WIDTH=750,scrollbars=yes")  
     newWindow.document.open()  
     newWindow.document.write('$start_page')  
     newWindow.document.write("<img border='0' src='/adm/lonInterFace/author.jpg' alt='[Author Header]'>\\n")  
     newWindow.document.write("<table border='0' cellspacing='0' cellpadding='0' width='430' bgcolor='#CCFFDD'>\\n")  
     newWindow.document.write("<tr><td width='2'>&nbsp;</td><td width='3'>&nbsp;</td>\\n")  
     newWindow.document.write("<td><h3>Location: <tt>$fullpath</tt></h3><h3>New Directory</h3></td></tr>\\n")  
     newWindow.document.write("<tr><td width='2'>&nbsp;</td><td width='3'>&nbsp;</td>\\n")  
     newWindow.document.write("<td><form name='fileaction' action='/adm/cfile' method='post'>\\n")  
     newWindow.document.write("<font face='arial,helvetica,sans-serif'>Enter the name of the new directory where you will save the converted testbank questions<br /><br />")  
     newWindow.document.write("<input type='hidden' name='filename' value='$fullpath'>")     
     newWindow.document.write("<input type='hidden' name='action' value='newdir'>")  
     newWindow.document.write("<input type='hidden' name='callingmode' value='testbank'>")  
     newWindow.document.write("$fullpath<input type='text' name='newfilename' value=''/>")  
     newWindow.document.write("<input type='button' value='Go' onClick='document.fileaction.submit();' />")  
     newWindow.document.write("</td></tr>\\n")  
     newWindow.document.write("</table>")  
     newWindow.document.write('$end_page')  
     newWindow.document.close()  
     newWindow.focus()  
 }  
 END_OF_ONE  END_OF_ONE
     if ($source eq "PreviousPage") {       if ($source eq "PreviousPage") { 
         $$jsref .= qq|            $$jsref .= qq|  
Line 412  function setElements() { Line 414  function setElements() {
     var iter = 0      var iter = 0
     var selParam = 0      var selParam = 0
         |;          |;
         foreach my $item (keys %env) {          foreach my $item (keys(%env)) {
             if ($item =~ m/^form\.(\w+)$/) {              if ($item =~ m/^form\.(probfile_\d+)$/) {
                 my $name = $1;                   my $name = $1; 
                 my $value = $env{"form.$name"};                  my $value = $env{"form.$name"};
                 unless ($value eq "") {                  if ($value ne '') {
                     if ($name eq "newdir") {                   $$jsref .= qq(    document.dataForm.$name.value = "$value"\n);
                      $$jsref .= qq(    document.forms.dataForm.$name.value = "$value"\n);  
                     }  
                 }                  }
             }              }
         }          }
         $$jsref .= "}";          $$jsref .= "}";
     }      }
 }      $$jsref .= '
   
   function verify() {
   ';
       my $blocks = 0;
       if ( exists( $env{'form.blocks'}) ) {
           $blocks = $env{'form.blocks'};
       }
       my $numitems = 0;
       for (my $i=0; $i<$blocks; $i++) {
           my $count = 0;
           if (($env{"form.start_$i"} ne '') && ($env{"form.end_$i"} ne '')) {
               $count = $env{"form.end_$i"} - $env{"form.start_$i"} +1;
           }
           $numitems += $count;
       }
       if ($numitems > 0) {
           my $maxnum = $numitems - 1;
           my %lt = &Apache::lonlocal::texthash(
                                                 fnmb => 'File names must be unique',
                                                 isum => 'is used more than once',
                                               );
           $$jsref .= qq|
       for (var j=$maxnum; j>0;  j--) {
           var currname = document.dataForm.elements['probfile_'+j].value;
           for (var k=j-1; k>=0; k--) {
               var comparename = document.dataForm.elements['probfile_'+k].value;
               if (currname == comparename) {
                   alert("$lt{fnmb} - "+currname+" $lt{isum}");
                   return false;
               }
           }
       }
   |;
       }
       $$jsref .= '
       return true;
   }
   ';
       $$jsref .= &Apache::loncommon::check_uncheck_jscript();
       return;
   }
   
 # ---------------------------------------------------------------- Jscript Four  # ---------------------------------------------------------------- Jscript Four
 sub jscript_four {  sub jscript_four {
     my ($jsref,$fullpath) = @_;      my ($jsref,$webpath) = @_;
     $$jsref = qq|         $$jsref = qq|   
 function backtoStart() {  function backtoStart() {
     document.location.href="$fullpath"      document.location.href="$webpath"
 }  }
 function backpage() {  function backPage() {
     document.forms.verify.go.value="PreviousPage"      document.forms.verify.go.value="PreviousPage"
     document.forms.verify.submit()      document.forms.verify.submit();
 }  }
     |;      |;
 }  }
   
 # ---------------------------------------------------------------- Display Zero  # ---------------------------------------------------------------- Display Zero
 sub display_zero {  sub display_zero {
     my ($r,$uname,$fn,$page,$fullpath) = @_;      my ($r,$uname,$fn,$page,$webpath) = @_;
     $r->print(qq|      my $go_default = 'NextPage'; 
 <table border='0' cellspacing='0' cellpadding='0' width='100%'>  
        <tr>  
         <td>&nbsp;</td>  
         <td colspan='2'><font face='arial,helvetica,sans-serif'>   
 The <b>Testbank Upload</b> utility can be used by LON-CAPA authors to convert <i>multiple choice</i>, <i>multiple answer correct</i>, <i>fill-in-the-blank</i>, <i>ordering/ranking</i>, <i>true/false</i> and <i>essay</i> questions from a plain text testbank file to LON-CAPA problem files.  Five requirements must be met to ensure that you will succeed in converting your plain text file of testbank questions to functioning LON-CAPA problems.  
         <ol>  
          <li>The questions and answers you upload must be in plain text format.  Any header lines should occur before the text containing the questions and answers.</li>  
          <li>All questions (including question text and all foils) must occur before any of the answers.  Each question should begin on a new line, and should start with the question number. Questions should be numbered sequentially using a number followed immediately by a space, a period, or enclosed in parentheses, i.e., 1 , 1., (1), 1), or (1 .</li>  
          <li><i>Multiple choice</i> and <i>multiple answer correct</i> questions should consist of: (i) the question number followed by (ii) the question text beginning on the same line and (iii) two or more foils, with each foil beginning on a new line and prefixed by a unique letter, or Roman numeral, listed in alphabetic or numeric order, beginning at a (alphabetic) or i (Roman numeral), followed by a period, or enclosed in parentheses, i.e., a., (a), i., or (i).</li>  
          <li>One or more correct answers should be provided for all questions (although blank answers may be provided for <i>essay</i> questions).  Answers should be numbered sequentially, using the same scheme as used for the questions, and must occur after <b>all</b> the questions.          
          <li>If <i>fill-in-the-blank</i> or <i>multiple answer</i> questions have more than one correct answer, each answer should appear in a comma-, tab-, space-, or new line-delimited list. For a <i>ranking/ordering</i> question, the "answer" should contain the foil identifiers correctly ordered in a similarly delimited list. If two or more foils have the same ranking, they should occur together, with an equals sign separating equally ranked foils [e.g., (b),(e)=(a),(d),(c)].</li>   
         </ol>  
 Five steps are involved in the import process.  
         <ol>  
          <li>Upload your text file to the server.|);  
   
     if ($fn eq '') {      if ($fn eq '') {
         $r->print("<b>Incomplete</b>. Please return to the <a href='$fullpath'>construction space menu<a> to upload a file");          $r->print('<b>'.&mt('Incomplete file upload').'</b> '.&mt('Return to the [_1]construction space menu[_2] to upload a file','<a href="'.$webpath.'">','</a>'));
     } else {      }
         $r->print(" <b>Completed</b> - successful upload of <i>$fn</i>");      $r->print(&mt('The <b>Testbank Upload</b> utility can be used by LON-CAPA authors to generate LON-CAPA problem files from a testbank file of questions/answers.').'<br />'.
     }                 &mt('The following question types can be converted:').'
     $r->print(qq|</li>                <ul>
          <li>Provide information about the question format - i.e.,  question numbering style, and the number of blocks of questions of each question type.</li>                  <li>'.&mt('multiple choice').'</li>
          <li>Provide information about the questions in each block, including question type, start and end question numbers for each block, and foil labelling style and answer format where required.</li>                  <li>'.&mt('multiple answer correct').'</li>
          <li>Create a new directory where you will save the converted testbank questions.</li>                   <li>'.&mt('fill-in-the-blank').'</li>
          <li>Complete the import of questions to the selected pool.</li>                  <li>'.&mt('ordering/ranking').'</li>
         </ol>                  <li>'.&mt('true/false').'</li>
         </font>                  <li>'.&mt('essay').'</li>
         </td>                </ul>
        </tr>                '.&mt('The file of questions (in plain text, RTF or HTML format) must meet certain requirements for the conversion process to generate functioning LON-CAPA problems.').&Apache::loncommon::help_open_topic('Testbank_Formatting').'<br />'.
        </table>                &mt('Five steps are involved in the conversion process.').'
        <br />          <ol>
        <br />           <li>'.&mt('Optionally create a new sub-directory where the converted testbank questions will be saved.').'</li>
        <form name="info" method="post">           <li>'.&mt('Provide information about the question format - i.e.,  question numbering style, and the number of blocks of questions of each question type.').'</li>
        <input type="hidden" name="uploaduname" value="$uname">           <li>'.&mt('Provide information about the questions in each block, including question type, start and end question numbers for each block, and foil labelling style and answer format where required.').'</li>
        <input type="hidden" name="filename" value="$fn">           <li>'.&mt('Review the identified questions, choose which to convert, and (optionally) override the default filename to be used for each problem file.').'</li> 
        <input type="hidden" name="page" value="$page">           <li>'.&mt('Complete the import of questions.').'</li>
        <input type="hidden" name="phase" value="three">          </ol><form name="info" method="post" action="/adm/testbank">'.
        <input type="hidden" name="go" value="NextPage">          &topic_bar(1,&mt('Optional: create a sub-directory in which the testbank questions will be saved')).
        <table border="0" width="100%">          &mt('By default, LON-CAPA problems generated from the testbank file will be stored in the current directory.').' '.&mt('To store them in a new sub-directory:'). 
         <tr>         ' <input type="button" name="createdir" value="'.&mt('Create sub-directory').'" onClick="javascript:createWin()">'.
          <td align='left'>         &page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath).'
           <input type="button" name="goback" value="Exit Now" onClick="javascript:location.href='$fullpath'">         </form>');
          </td>  
          <td align='right'>  
           <input type="button" name="nextpage" value="Continue to step 2" onClick="javascript:submit()">  
          </td>  
         </tr>  
        </table>  
        </form>   
     |);    
 }  }
   
   
 # ---------------------------------------------------------------- Display One  # ---------------------------------------------------------------- Display One
   
 sub display_one {  sub display_one {
     my ($r,$uname,$fn,$page,$textref) = @_;      my ($r,$uname,$fn,$page,$textref,$header) = @_;
     $r->print(qq|      my %topics;
    <form method='post' name='display'>      $topics{2} = &mt('Select the format of the question number - e.g., 1,  1., 1), (1 or (1) - ').'&nbsp;
    <table border='0' cellspacing='0' cellpadding='3' width='100%'>                 <select name="qnumformat">
     <tr bgcolor='#ccddaa'>                    <option value = "-1" selected>'.&mt('Select').'</option>
      <td>&nbsp;</td>                     <option value="number">1</option>
      <td align='left'>                    <option value="period">1.</option>
        <h3><font face='arial,helvetica,sans-serif'>Step 2: Identification of blocks of questions</b>&nbsp;</font></h3>                    <option value="paren">(1)</option>
      </td>                    <option value="leadparen">(1</option>
     </tr>                    <option value="trailparen">1)</option>
     <tr>                   </select>'."\n";
      <td colspan='2'>&nbsp;</td>      $topics{3} = &mt('Indicate the number of blocks of different question types in the testbank file.').'&nbsp;&nbsp;<input type="text" name="blocks" value="" size="5" />';
     </tr>      $r->print('<h3>'.&mt('Identification of blocks of questions').'</h3>'."\n".
     <tr>                '<form method="post" name="display" action="/adm/testbank">'."\n".
      <td colspan='2'>                &show_uploaded_data($textref,$header)."\n".
       <table border="0" cellspacing="0" cellpadding="2">                &topic_bar(2,$topics{2}).'<p>'.
        <tr>                &mt('A number in the specified format should appear at the start of each question.').'<br />'.
         <td>&nbsp;</td>                &mt('For multiple choice questions, the question number must begin the line that contains the question text; foils (starting (a), (i) etc.) should occur on subsequent lines.').'<br />'."\n".
         <td colspan='2'>                &mt('Correct answers should be numbered in the same way as the questions and should appear after <b>all</b> the questions (including question text and possible foils for all questions).').'<br />'."\n".
          <font face='arial,helvetica,sans-serif'><b>Testbank data uploaded to the server:</b></font>                &mt('Each numbered question must have a corresponding numbered answer, although the answer itself may be blank for essay questions.').'<br /><br />'."\n".
        </td>                &mt('For example, you would select <b>1.</b> if your testbank file contained the following questions:').'<br /><blockquote>'.
       </tr>  '<pre>
       <tr>   1. '.&mt('The capital of the USA is ...').'
        <td colspan='3'>&nbsp;</td>   (a) Washington D.C.
       </tr>   (b) New York
       <tr>   (c) Los Angeles
        <td>&nbsp;</td>  
        <td colspan='2'>   2. '.&mt('The capital of Canada is ...').'
          <textarea name="rawdata" cols="70" rows="6" wrap="virtual" align="center">   (a) Toronto
     |);   (b) Vancouver
     foreach my $line (@{$textref}) {   (c) Ottawa
         $line =~ s/\n//g;  
         $r->print("$line\n");   3. '.&mt('Describe an experiment you could conduct to measure c, the speed of light in a vacuum.').'
     }   1. (a)
     $r->print(qq|   2. (c)
        </textarea>   3.
       </td>  </pre>'.
      </tr>               '</blockquote></p>'.
      <tr>               &topic_bar(3,$topics{3}).'<p>'.
       <td colspan='3'>&nbsp;</td>               &mt('For example, you would enter <b>6</b> if your testbank file contained the following sequence of questions:').'</p><blockquote>'.
      </tr>               &mt('10 multiple choice questions').'<br />'.
      <tr>               &mt('5 essay questions').'<br />'.
      <tr>               &mt('5 fill-in-the-blank questions').'<br />'.
       <td colspan='3'>&nbsp;</td>               &mt('5 multiple answer questions').'<br />'.
      </tr>               &mt('4 multiple choice questions').'<br />'.
      <tr bgcolor='#ccddaa'>               &mt('3 essay questions').'</blockquote></p><p>'.
       <td>&nbsp;</td>               &mt('You will indicate the question type and the question number range for each of the blocks on the next page.').'</p><br />'.
       <td align='left' valign='middle'><img src="/res/adm/pages/bl_step1.gif">&nbsp;&nbsp;               &page_footer($env{'form.newdir'},$uname,$fn,$page).'
       </td>   </form>');
       <td>      return;
        <font face='arial,helvetica,sans-serif'><b>  
 Select the format of the question number</b> [e.g., 1,  1., 1), (1 or (1)].&nbsp;  
                  <select name="qnumformat">  
                   <option value = "-1" selected>Please Select  
                   <option value="number">1  
                   <option value="period">1.  
                   <option value="paren">(1)  
                   <option value="leadparen">(1  
                   <option value="trailparen">1)  
                  </select>  
        </font>  
       </td>  
      </tr>  
      <tr>  
       <td colspan='3'>&nbsp;</td>  
      </tr>  
      <tr>  
       <td>&nbsp;</td>  
       <td colspan='2'><font face='arial,helvetica,sans-serif'>  
 A number in the specified format should appear at the start of each question. For multiple choice questions, the question number must begin the line that contains the question text; foils (starting (a), (i) etc.) should occur on subsequent lines. Correct answers should be numbered in the same way as the questions and should appear after <b>all</b> the questions (including question text and possible foils for all questions). Each numbered question must have a corresponding numbered answer, although the answer itself may be blank for essay questions.</td>  
      </tr>  
      <tr>  
       <td colspan="3">&nbsp;</td>  
      </tr>  
      <tr>  
       <td>&nbsp;</td>  
       <td colspan='2'>  
        <font face='arial,helvetica,sans-serif'>  
         For example, you would select <b>1.</b> if your text file contained the following questions:<br><br>  
  1. The capital of the USA is ..<br />  
  &nbsp;&nbsp;(a) Washington D.C.<br />  
  &nbsp;&nbsp;(b) New York<br />  
  &nbsp;&nbsp;(c) Los Angeles<br />  
  <br />  
  2. The capital of Canada is ..<br />  
  &nbsp;&nbsp;(a) Toronto<br />  
  &nbsp;&nbsp;(b) Vancouver<br />  
  &nbsp;&nbsp;(c) Ottawa<br />  
 <br />  
  3. Describe an experiment you could conduct to measure c, the speed of light in a vacuum. <br /><br />  
  1. (a)<br />  
  2. (c)<br />  
  3. <br />  
       </td>  
      <tr>  
       <td colspan="3">&nbsp;</td>  
      </tr>  
      <tr bgcolor='#ccddaa'>  
       <td>&nbsp;</td>  
       <td><img src='/res/adm/pages/bl_step2.gif' align='left' valign='middle'>&nbsp;&nbsp;  
       </td>  
       <td>  
        <font face='arial,helvetica,sans-serif'><b>  
 Please indicate the number of blocks of different question types in the text file.</b>&nbsp;&nbsp;  
          <input type="text" name="blocks" value="" size="5">  
       </td>  
      </tr>  
      <tr>  
       <td colspan="3">&nbsp;</td>  
      </tr>  
      <tr>  
       <td>&nbsp;</td>  
       <td colspan='2'>  
        <font face='arial,helvetica,sans-serif'>  
         For example, you would enter <b>6</b> if your text file contained the following sequence of questions:<br><br>  
  10 multiple choice questions<br>  
   5 essay questions<br>  
   5 fill-in-the-blank questions<br>  
   5 multiple answer questions<br>  
   4 multiple choice questions<br>  
   3 essay questions<br>  
       </font>  
       </td>  
      </tr>  
      <tr>  
       <td colspan='3'>&nbsp;</td>  
      </tr>  
      <tr>  
        <td>&nbsp;</td>  
        <td colspan='2'><font face='arial,helvetica,sans-serif'>You will indicate the question type and the question number range for each of the blocks on the next page.</font></td>  
      </tr>  
      <tr>  
       <td colspan='3'>&nbsp;</td>  
      </tr>  
      <tr>  
       <td colspan='3'>  
        <table border='0' width="100%" cellspacing='0' cellpadding='2'>  
         <tr>  
          <td align='left'>  
           <input type="button" name="backpage" value="Go back to step 1" onClick="javascript:backPage()">  
          </td>  
          <td align='right'>  
           <input type="button" name="nextpage" value="Continue to step 3" onClick="javascript:nextPage()">  
          </td>  
         </tr>  
        </table>  
        <input type="hidden" name="page" value ="$page">  
        <input type="hidden" name="go" value="">  
        <input type="hidden" name="uploaduname" value="$uname">  
        <input type="hidden" name="filename" value="$fn">  
        <input type="hidden" name="phase" value="three">  
       </td>  
      </tr>  
     </table>  
    </td>  
   </tr>  
  </table>  
  </form>  
     |);  
 }  }
   
 # ---------------------------------------------------------------- Display Two  # ---------------------------------------------------------------- Display Two
   
 sub display_two {  sub display_two {
     my ($r,$uname,$fn,$page,$textref,$qcount) = @_;      my ($r,$uname,$fn,$page,$textref,$header,$qcount) = @_;
     my $blocks = $env{'form.blocks'};      my $blocks = $env{'form.blocks'};
     my $qnumformat = $env{'form.qnumformat'};      my $qnumformat = $env{'form.qnumformat'};
     my @types = ("MC","MA","TF","Ess","FIB","Ord");      my @types = ("MC","MA","TF","Ess","FIB","Ord");
Line 686  sub display_two { Line 592  sub display_two {
              leadparen => "(1",               leadparen => "(1",
              trailparen => "1)",               trailparen => "1)",
              );               );
     my @bgcolors = ('#ffffff','#eeeeee');  
     my $bl1st = '';      my $bl1st = '';
     my $bl1end = '';      my $bl1end = '';
     if ($blocks == 1) {      if ($blocks == 1) {
         $bl1st = '1';          $bl1st = '1';
         $bl1end = $qcount;          $bl1end = $qcount;
     }      }
     $r->print(<<"END_OF_FUNC");      my $steptitle = &mt('Information about question types and formats in each block.');
  <h3><font face='arial,helvetica,sans-serif'>Step 3: Classification of blocks</b>&nbsp;</font></h3>      $r->print('<h3>'.&mt('Classification of blocks').'</h3>'.
 <form method='post' name='display'>                '<form method="post" name="display" action="/adm/testbank"><p>'.
    <table border='0' cellspacing='0' cellpadding ='0'>                &mt('You indicated that <b>all</b> questions (and the corresponding answer(s) for each question) begin with a number in the following format: [_1].','<b>'.$qnumtypes{$qnumformat}.'</b>').'</p><p>'.
     <tr>                &mt('A total of <b>[quant,_1,question]</b> and <b>[quant,_2,answer]</b> were found in the file you uploaded.',$qcount,$qcount).' '.
      <td colspan='2'>&nbsp;</td>                &mt('If this total does not match the number you expect, examine your original testbank file to verify that each question <i>and</i> each answer begins with a number in the specified format.').' '.
     </tr>                &mt('If necessary use an editor to edit your testbank file of questions, and click "Previous Page" on this page and the "Exit Now" on the preceding page, so you can upload your file again.').'</p><p>'.
     <tr>                &mt('You also indicated that the <b>[quant,_1,question]</b> can be divided into <b>[quant,_2,block]</b> of questions of a particular question type.',$qcount,$blocks).'</p><p>'.
      <td colspan='2'>                &mt('Provide additional information below, about the types of questions you have uploaded, and, if applicable, the format of answers and "foils" for specific types of questions.').'</p>'.
       <table border="0" cellspacing="0" cellpadding="0">                &show_uploaded_data($textref,$header).
        <tr>                &topic_bar(4,$steptitle).'<p>'.
         <td>&nbsp;</td>                &mt('For <i>each</i> of the [_1] question blocks, specify the question numbers of the first and last questions in the block (e.g., 1 and 10), and the question type of the questions in the block.','<b>'.$blocks.'</b>').' '.
         <td><font face='arial,helvetica,sans-serif'>                &mt('If required, provide additional information about foil formats and answer formats for the question types you select.').'</p><p>'.
           You indicated that <b>all</b> questions (and the corresponding answer(s) for each question) begin with a number in the following format:  <b>$qnumtypes{$qnumformat}</b>.<br><br>A total of <b>$qcount</b> questions and <b>$qcount</b> corresponding answers were found in the file you uploaded. If this questions total does not match the number you expect, please examine your original text file to verify that each question <i>and</i> each answer begins with a number in the specified format. If necessary use a text editor to edit your text file of questions, and click "Return to step 2" on this page and the "Return to Step 1" on the preceding page, so you can upload your text file again.<br><br>                &Apache::loncommon::start_data_table().
           You also indicated that the <b>$qcount</b> questions can be divided into <b>$blocks</b> blocks of questions of a particular question type.</font>                &Apache::loncommon::start_data_table_header_row().
         </td>                '<th>'.&mt('Block').'</th>'."\n".
        </tr>                '<th>'.&mt('First number').'</th>'."\n".
        <tr>                '<th>'.&mt('Last number').'</th>'."\n".
         <td colpsan='2'>&nbsp;</td>                '<th>'.&mt('Question type').'</th>'."\n".
        </tr>                '<th>'.&mt('Foil format').'</th>'."\n".
        <tr>                '<th>'.&mt('Answer format').'</th>'."\n".
         <td>&nbsp;</td>                &Apache::loncommon::end_data_table_header_row());
         <td><font face='arial,helvetica,sans-serif'>  
           Please provide additional information below ,about the types of questions you have uploaded, and, if applicable, the format of answers and &quot;foils&quot; for specific types of questions.  
         </td>  
        </tr>  
        <tr>  
         <td colpsan='2'>&nbsp;</td>  
        </tr>  
        <tr>  
         <td>&nbsp;</td>  
         <td>  
 <font face='arial,helvetica,sans-serif'>The following data were uploaded to the server</font><br>  
 <textarea name="rawdata" cols="70" rows="6" wrap="virtual" align="center">  
 END_OF_FUNC  
     foreach my $line (@{$textref}) {  
         $line =~ s/\n//g;  
         $r->print("$line\n");  
     }  
     $r->print(qq|   
 </textarea>  
       </td>  
      </tr>  
      <tr>  
       <td colspan='2'>&nbsp;</td>  
      </tr>  
      <tr bgcolor='#ccddaa'>  
       <td><img src='/res/adm/pages/bl_step3.gif' align='left' valign='middle'>  
       </td>  
       <td width='100%' align='left'>&nbsp;&nbsp;  
        <font size='+1' face='arial,helvetica,sans-serif'><b>Information about question types and formats in each block.</b></font>  
       </td>  
      </tr>  
      <tr>  
       <td colspan='2'>&nbsp;</td>  
      </tr>  
      <tr>  
       <td>&nbsp;</td>  
       <td><font face='arial,helvetica,sans-serif'>For <i>each</i> of the <b>$blocks</b> question blocks, please specify the question numbers of the first and last questions in the block (e.g., 1 and 10), and the question type of the questions in the block. Please provide additional information about foil formats and answer formats if required for the question type you selected.</font>  
       </td>  
      </tr>  
      <tr>  
       <td colspan='2'>&nbsp;</td>  
      </tr>  
      <tr>  
       <td>&nbsp;</td>  
       <td>  
        <table border="0" cellspacing="0" cellpadding="0" bgcolor="#000000" align="left">  
         <tr>  
          <td>  
           <table border="1" valign="top" align="center" width='100%'>  
            <tr bgcolor="#eef6f6" align="left">  
             <td>  
              <table border='0' cellspacing='1' cellpadding='1' align='left' width='100%'>  
               <tr bgcolor='#CCDDAA' align='center' valign='middle'>  
                <td align="center" valign="middle" height='10'><font face='arial,helvetica,sans-serif'>  
                 &nbsp;<b>Block</b>&nbsp;</font>  
                </td>  
                <td align="center" valign="middle" height='10'><font face='arial,helvetica,sans-serif'>&nbsp;  
                 &nbsp;<b>First&nbsp;number</b>&nbsp;</font>  
                </td>  
                <td align="center" valign="middle" height='10'><font face='arial,helvetica,sans-serif'>&nbsp;  
                 &nbsp;<b>Last&nbsp;number</b>&nbsp;</font>  
                </td>  
                <td align="center" valign="middle" height='10'><font face='arial,helvetica,sans-serif'>&nbsp;  
                 &nbsp;<b>Question&nbsp;type</b>&nbsp;</font>  
                </td>  
                <td align="center" valign="middle" height='10'><font face='arial,helvetica,sans-serif'>&nbsp;  
                 &nbsp;<b>Foil&nbsp;format</b>&nbsp;</font>  
                </td>  
                <td align="center" valign="middle" height='10'><font face='arial,helvetica,sans-serif'>&nbsp;  
                 &nbsp;<b>Answer&nbsp;format</b>&nbsp;</font>  
                </td>  
               </tr>  
     |);  
     for (my $i=0; $i<$blocks; $i++) {      for (my $i=0; $i<$blocks; $i++) {
         my $iter = $i+1;          my $iter = $i+1;
         my $rowcol = $i%2;          $r->print(&Apache::loncommon::start_data_table_row().
         $r->print(qq|                   '<td valign="top">&nbsp;'.$iter.'&nbsp;</td>'."\n".
  <tr bgcolor="$bgcolors[$rowcol]">                   '<td valign="top">&nbsp;<input type="text" name="start_'.$i.'" value="'.$bl1st.'" size="5" />&nbsp;</td>'."\n".
   <td align="left">                   '<td valign="top">&nbsp;<input type="text" name="end_'.$i.'" value="'.$bl1end.'" size="5">&nbsp;</td>'."\n".
    <font face='arial,helvetica,sans-serif'>&nbsp;$iter.</font>                   '<td valign="top">
   </td>     <select name="qtype_'.$i.'" onChange="colSet('.$i.')">
   <td align="left">&nbsp;      <option value= "-1" selected>'.&mt('Select').'</option>'."\n");
    <input type="text" name="start_$i" value="$bl1st" size="5">&nbsp;  
   </td>  
   <td align="left">&nbsp;  
    <input type="text" name="end_$i" value="$bl1end" size="5">&nbsp;  
   </td>  
   <td align="left">  
    <font face='arial,helvetica,sans-serif'>  
    <select name="qtype_$i" onChange="colSet($i)">  
     <option value= "-1" selected>Please Select  
         |);  
         foreach my $qtype (@types) {          foreach my $qtype (@types) {
             $r->print(qq|<option value="$qtype">$typenames{$qtype}|);              $r->print('<option value="'.$qtype.'">'.$typenames{$qtype}.'</option>'."\n");
         }          }
         $r->print(qq|          $r->print('   </select>
    </select>  
    </font>  
   </td>    </td>
   <td align="left">&nbsp;    <td align="left" valign="top">&nbsp;
     <select name="foilformat_$i">      <select name="foilformat_'.$i.'">
      <option value="-1">&lt;--- Set type&nbsp;        <option value="-1">&lt;--- Set type&nbsp; 
     </select>&nbsp;      </select>&nbsp;
   </td>    </td>
   <td align="left">&nbsp;    <td align="left" valign="top">&nbsp;
     <select name="ansr_$i">      <select name="ansr_'.$i.'">
      <option value="-1">&lt;--- Set type&nbsp;       <option value="-1">&lt;--- Set type&nbsp;
     </select>      </select>
   </td>    </td>'.
  </tr>                       &Apache::loncommon::end_data_table_row()); 
         |);  
     }      }
     $r->print(qq|      $r->print(&Apache::loncommon::end_data_table().'</p><ul><li>'.
        </table>                &mt('For <i>multiple choice</i>, <i>multiple correct answer</i> and <i>ranking</i> type questions, you must use the <b>Foil format</b> column to choose the format of the identifier used for each of the possible answers (e.g., (a), a, a., i, (i) etc.) provided for a given question stem.').'</li><li>'.
       </td>               &mt('For <i>multiple correct answer</i> and <i>fill-in-the-blank</i> questions with more than one correct answer you must use the <b>Answer format</b> column to choose the separator used between the answers, e.g., if the correct answers for question 28. were listed as:[_1] you would choose "comma", or if they were listed as:[_2] you would choose "new line".','<blockquote><pre>28. (a),(d),(e)</pre></blockquote>','<blockquote><pre>
      </tr>  28. (a)
     </table>      (d)
    </td>      (e)
   </tr>  </pre></blockquote>').'</li><li>'.
  </table>               &mt('For <i>true/false</i> questions you must use the <b>Answer format</b> column to choose how the correct answer - True or False, is displayed in the text file (e.g., T or F, true or false etc.).').'</li><li>'.
 </td>              &mt('For <i>ranking</i> questions you must use the <b>Answer format</b> column to choose the separator used between the (ranked) answers.').'</li></ul>
 </tr>  <input type="hidden" name="blocks" value="'.$blocks.'" />
 <tr>  <input type="hidden" name="qnumformat" value="'.$qnumformat.'" />'.
  <td colspan="2">&nbsp;</td>             &page_footer($env{'form.newdir'},$uname,$fn,$page).'
 </tr>  </form>');
 <tr>      return;
  <td>&nbsp;</td>  }
  <td>  
 <font face='arial,helvetica,sans-serif'>For <i>multiple choice</i>, <i>multiple correct answer</i> and <i>ranking</i> type questions, you must use the <b>Foil format</b> column to choose the format of the identifier used for each of the possible answers (e.g., (a), a, a., i, (i) etc.) provided for a given question stem. For <i>multiple correct answer</i> and <i>fill-in-the-blank</i> questions with more than one correct answer you must use the <b>Answer format</b> column to choose the separator used between the answers, e.g., if the correct answers for question 28. were listed as: 28. (a),(d),(e) you would choose &quot;comma&quot;, or if they were listed as:</font><br><table border='0'><tr><td><font face='arial,helvetica,sans-serif'>28.&nbsp</font></td><td><font face='arial,helvetica,sans-serif'>(a)</font></td></tr><tr><td>&nbsp;</td><td><font face='arial,helvetica,sans-serif'>(d)</font></td></tr><tr><td>&nbsp;</td><td><font face='arial,helvetica,sans-serif'>(e)</font></td></tr></table>  
 <font face='arial,helvetica,sans-serif'>you would choose &quot;new line&quot;. For <i>true/false</i> questions you must use the <b>Answer format</b> column to choose how the correct answer - True or False, is displayed in the text file (e.g., T or F, true or false etc.). For <i>ranking</i> questions you must use the <b>Answer format</b> column to choose the separator used between the (ranked) answers.</font><br><br>  
       </td>  
      </tr>  
      <tr>  
       <td colspan='2'>&nbsp;</td>  
      </tr>  
      <tr>  
       <td colspan='2'>  
 <input type="hidden" name="blocks" value="$blocks">  
 <input type="hidden" name="qnumformat" value="$qnumformat">  
    <table border='0' width="100%" cellspacing='0' cellpadding='2'>  
     <tr>  
      <td align='left'>  
       <input type="button" name="backpage" value="Go back to step 2" onClick="javascript:backPage()">  
      </td>  
      <td align='right'>  
       <input type="button" name="nextpage" value="Continue to step 4" onClick="javascript:nextPage()">  
      </td>  
     </tr>  
    </table>  
    <input type="hidden" name="page" value ="$page">  
    <input type="hidden" name="go" value="">  
    <input type="hidden" name="uploaduname" value="$uname">  
    <input type="hidden" name="filename" value="$fn">  
    <input type="hidden" name="phase" value="three">  
    </form>  
   </td>  
  </tr>  
 </table>  
 </td>  
 </tr>  
 </table>  
     |);  
 }   
 # ---------------------------------------------------------------- Display Three  # ---------------------------------------------------------------- Display Three
 sub display_three {   sub display_three {
     my ($r,$uname,$fn,$page,$textref,$qcount) = @_;      my ($r,$uname,$fn,$page,$textref,$res,$header,$urlpath,$qcount) = @_;
     my $qnumformat = $env{'form.qnumformat'};      my $qnumformat = $env{'form.qnumformat'};
     my $filename = $env{'form.filename'};      my $filename = $env{'form.filename'};
     my $source = $env{'form.go'};      my $source = $env{'form.go'};
     my $blocks = $env{'form.blocks'};      my $blocks = $env{'form.blocks'};
     my @items = ();      my ($alphabet,$romans) = &get_constants();
     my @bgcolors = ('#ffffff','#eeeeee');  
     my @types = ("MC","MA","TF","Ess","FIB","Ord");  
     my @alphabet = ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");  
     my @romans = ("i","ii","iii","iv","v","vi","vii","viii","ix","x","xi","xii","xiii","xiv","xv","xvi","xvii","xviii","xix","xx","xxi","xxii","xxiii","xxiv","xxv","xxvi");  
     my @start = ();      my @start = ();
     my @end = ();      my @end = ();
     my @nums = ();      my @nums = ();
Line 898  sub display_three { Line 678  sub display_three {
     my @ansrtypes = ();      my @ansrtypes = ();
     my %multparts = ();      my %multparts = ();
     my $numitems = 0;      my $numitems = 0;
       my %lt = &Apache::lonlocal::texthash (
                                             crt  => 'Create?',
                                             typ  => 'Type',
                                             fnam => 'File Name',
                                             ques => 'Question',
                                             answ => 'Answer',
                                             chka => 'check all',
                                             unch => 'uncheck all',
                                            );
     for (my $i=0; $i<$blocks; $i++) {      for (my $i=0; $i<$blocks; $i++) {
         if (($env{"form.start_$i"} ne '') && ($env{"form.end_$i"} ne '')) {          if (($env{"form.start_$i"} ne '') && ($env{"form.end_$i"} ne '')) {
             $start[$i] = $env{"form.start_$i"};              $start[$i] = $env{"form.start_$i"};
Line 919  sub display_three { Line 708  sub display_three {
         }          }
         $numitems += $nums[$i];          $numitems += $nums[$i];
     }      }
       my ($items,$ids,$footer) = &file_split(\@start,\@end,\@nums,$qnumformat,\@foilformats,$textref,\%multparts,$numitems,\@qtype,$blocks);
     my $import = join//,@{$textref};      my ($showheader,$showcss);
     @items = &file_split(\@start,\@end,\@nums,$qnumformat,\@foilformats,$textref,\%multparts,$numitems,\@qtype,$blocks);      if ($res eq 'application/rtf' || $res eq 'text/html') {
     $r->print(<<"END_OF_ONE");          if ($header ne '') {
  <h3><font face='arial,helvetica,sans-serif'>Step 4: Review and selection of destination directory</b>&nbsp;</font></h3>              $showheader = &HTML::Entities::decode($header);
 <form name="dataForm" method="post">              if ($res eq 'text/html') {
 <table border='0' bgcolor='#CCFFDD' cellspacing='0' cellpadding ='0'>                  $showheader = &build_image_url($urlpath,$showheader);
       <tr>              }
        <td colspan='2'>          }
         <table border='0' cellspacing='0' cellpadding='0'>      }
        <tr>      $r->print('<h3>'.&mt('Review and selection of problems to convert').'</h3>'."\n".
         <td colspan='2'>&nbsp;</td>                '<form name="dataForm" method="post" action="/adm/testbank">'."\n".
        </tr>                &mt('Based on your previous responses your data have been split into a total of [quant,_1,question].',$numitems).
        <tr>                &topic_bar(5,&mt('Choose which problems to convert and names to use for individual problem files')));
         <td>&nbsp;</td>                if ($showheader) {
         <td><font face='arial,helvetica,sans-serif'><b>                    $r->print($showheader.'<br />');
 Based on your previous responses your data have been split into a total of $numitems questions.</b>                 }
         </td>                $r->print('<input type="button" value="'.$lt{'chka'}.'" onclick="javascript:checkAll(document.dataForm.createprob)" /> &nbsp;
       </tr>  <input type="button" value="'.$lt{'unch'}.'" onclick="javascript:uncheckAll(document.dataForm.createprob)" /><br /><br />'.
       <tr>                &Apache::loncommon::start_data_table().
         <td colspan='2'>&nbsp;</td>                &Apache::loncommon::start_data_table_header_row(). 
       </tr>                '<th>'.#'.</th>'.
       <tr>                '<th>'.$lt{'crt'}.'</th>'.
        <td>&nbsp;</td>                '<th>'.$lt{'typ'}.'</th>'.
      <td width="80%" bgcolor="#000000" align="left">                '<th>'.$lt{'fnam'}.'</th>'.
      <table width="100%" border="0" cellpadding="1" cellspacing="0">                '<th>'.$lt{'ques'}.'</th>'.
       <tr>                '<th>'.$lt{'answ'}.'</th>'.
        <td width="100%" bgcolor="#000000">                &Apache::loncommon::end_data_table_header_row());
         <table border="0" cellspacing="0" cellpadding="1" width="100%">      my $idx;
          <tr>      if ($numitems =~ /^\d+$/ && $numitems > 0) {
           <td width="100%" bgcolor="#000000">          $idx = int(log($numitems)/log(10));
            <table border="0" cellpadding="0" cellspacing="1" bgcolor="#ffffff" width="100%">          $idx ++;
             <tr>      }
              <td bgcolor="#CCFFDD" width="100%">      if ($idx<3) {
               <table border='0' cellspacing='1' cellpadding='2' align='left' width= '100%'>          $idx = 3;
                <tr><td bgcolor="#CCDDAA" align="center" width='3%'><font face='arial,helvetica,sans-serif'><b>#</b></font></td><td bgcolor="#CCDDAA" align="center" width='5%'><font face='arial,helvetica,sans-serif'><b>Type</b></font></td><td bgcolor="#CCDDAA" align="center" width='60%'><font face='arial,helvetica,sans-serif'><b>Question</b></font></td><td bgcolor="#CCDDAA" align="center" width='32%'><font face='arial,helvetica,sans-serif'><b>Answer</b></font></td></tr>      }
 END_OF_ONE  
     for (my $j=0; $j<$numitems; $j++) {      for (my $j=0; $j<$numitems; $j++) {
         my $qnum = $j+1;          my $qnum = $ids->[$j]; 
         my $rowcol = $j%2;          my $libfile = 'question_';
         $rowcol = @bgcolors[$rowcol];          my $leading = 0;
           while (($idx - length($qnum) - $leading) > 0) {   
               $libfile .= '0';
               $leading ++;
           }
           $libfile .= $qnum.'.problem';
         for (my $i=0; $i<$blocks; $i++) {          for (my $i=0; $i<$blocks; $i++) {
             if ($nums[$i] > 0) {              if ($nums[$i] > 0) {
                 if (($j+1 >= $start[$i]) && ($j+1 <= $end[$i])) {                   if (($j+1 >= $start[$i]) && ($j+1 <= $end[$i])) { 
                     if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA")) {                       if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA")) { 
                         for (my $k=0; $k<@{$multparts{$j}}; $k++) {                          for (my $k=0; $k<@{$multparts{$j}}; $k++) {
                             if ($k == 0) {                              if ($k == 0) {
                                 $r->print(qq|<tr><td bgcolor="$rowcol" valign='top'><font face='arial,helvetica,sans-serif'>$qnum.</font></td><td bgcolor="$rowcol" valign='top'><font face='arial,helvetica,sans-serif'><b>$qtype[$i]</b></font></td><td bgcolor="$rowcol" valign='top'><font face='arial,helvetica,sans-serif'>$multparts{$j}[$k]<br><br>\n|);                                  my $showqn = $multparts{$j}[$k];
                             } else {                                   if (($res eq 'application/rtf') || ($res eq 'text/html')) {
                                       $showqn = &HTML::Entities::decode($showqn);
                                       if ($res eq 'text/html') {
                                           $showqn = &build_image_url($urlpath,$showqn);
                                       }
                                   }
                                   $r->print(&Apache::loncommon::start_data_table_row().
                                             '<td valign="top">'.$qnum.'.</td>'."\n".
                                             '<td valign="top"><input name="createprob" type="checkbox" "checked="checked" value="'.$j.'" /></td>'."\n".
                                             '<td valign="top"><b>'.$qtype[$i].'</b></td>'."\n".
                                             '<td valign="top"><input type="textbox" name="probfile_'.$j.'" value="'.$libfile.'" size="20" /></td>'.
                                             '<td valign="top">'.$showqn.'<br /><br />'."\n");
                               } else {
                                 my $foiltag = '';                                  my $foiltag = '';
                                 if ($foilformats[$i] eq "lcperiod") {                                  if ($foilformats[$i] eq "lcperiod") {
                                     $foiltag = $alphabet[$k-1].'.';                                       $foiltag = $alphabet->[$k-1].'.'; 
                                 } elsif ($foilformats[$i] eq "lcparen") {                                  } elsif ($foilformats[$i] eq "lcparen") {
                                     $foiltag = '('.$alphabet[$k-1].')';                                      $foiltag = '('.$alphabet->[$k-1].')';
                                 } elsif ($foilformats[$i] eq "lconeparen") {                                  } elsif ($foilformats[$i] eq "lconeparen") {
                                     $foiltag = $alphabet[$k-1].')';                                      $foiltag = $alphabet->[$k-1].')';
                                 } elsif ($foilformats[$i] eq "lcdotparen") {                                  } elsif ($foilformats[$i] eq "lcdotparen") {
                                     $foiltag = $alphabet[$k-1].'.)';                                      $foiltag = $alphabet->[$k-1].'.)';
                                 } elsif ($foilformats[$i] eq "ucperiod") {                                  } elsif ($foilformats[$i] eq "ucperiod") {
                                     $foiltag = $alphabet[$k-1].'.';                                      $foiltag = $alphabet->[$k-1].'.';
                                     $foiltag =~ tr/a-z/A-Z/;                                      $foiltag =~ tr/a-z/A-Z/;
                                 } elsif ($foilformats[$i] eq "ucparen") {                                  } elsif ($foilformats[$i] eq "ucparen") {
                                     $foiltag = '('.$alphabet[$k-1].')';                                      $foiltag = '('.$alphabet->[$k-1].')';
                                     $foiltag =~ tr/a-z/A-Z/;                                      $foiltag =~ tr/a-z/A-Z/;
                                 } elsif ($foilformats[$i] eq "uconeparen") {                                  } elsif ($foilformats[$i] eq "uconeparen") {
                                     $foiltag = $alphabet[$k-1].')';                                      $foiltag = $alphabet->[$k-1].')';
                                     $foiltag =~ tr/a-z/A-Z/;                                      $foiltag =~ tr/a-z/A-Z/;
                                 } elsif ($foilformats[$i] eq "ucdotparen") {                                  } elsif ($foilformats[$i] eq "ucdotparen") {
                                     $foiltag = $alphabet[$k-1].'.)';                                      $foiltag = $alphabet->[$k-1].'.)';
                                     $foiltag =~ tr/a-z/A-Z/;                                      $foiltag =~ tr/a-z/A-Z/;
                                 } elsif ($foilformats[$i] eq "romperiod") {                                  } elsif ($foilformats[$i] eq "romperiod") {
                                     $foiltag = $romans[$k-1].'.';                                      $foiltag = $romans->[$k-1].'.';
                                 } elsif ($foilformats[$i] eq "romparen") {                                  } elsif ($foilformats[$i] eq "romparen") {
                                     $foiltag = '('.$romans[$k-1].')';                                      $foiltag = '('.$romans->[$k-1].')';
                                 } elsif ($foilformats[$i] eq "romoneparen") {                                  } elsif ($foilformats[$i] eq "romoneparen") {
                                     $foiltag = $romans[$k-1].')';                                      $foiltag = $romans->[$k-1].')';
                                 } elsif ($foilformats[$i] eq "romdotparen") {                                  } elsif ($foilformats[$i] eq "romdotparen") {
                                     $foiltag = $romans[$k-1].'.)';                                      $foiltag = $romans->[$k-1].'.)';
                                   }
                                   my $showfoil = $multparts{$j}[$k];
                                   if ($res eq 'application/rtf' || $res eq 'text/html') {
                                       $showfoil = &HTML::Entities::decode($showfoil);
                                       if ($res eq 'text/html') {
                                           $showfoil = &build_image_url($urlpath,$showfoil);
                                       }
                                 }                                   } 
                                 $r->print(qq|$foiltag $multparts{$j}[$k]<br>\n|);                                  $r->print("$foiltag $showfoil<br />\n");
                             }                              }
                         }                          }
                         $r->print(qq|<br></font></td><td bgcolor="$rowcol" valign='top'><font face='arial,helvetica,sans-serif'>$items[$j+$numitems]</font></td></tr>|);                          my $showfoil = $items->[$j+$numitems];
                           if ($res eq 'application/rtf' || $res eq 'text/html') {
                               $showfoil = &HTML::Entities::decode($showfoil);
                               $showfoil =~ s/<\/?[^>]+>//g;
                           }
   
                           $r->print('<br /></td><td valign="top">'.$showfoil.'</td>'.
                                     &Apache::loncommon::end_data_table_row());
                     } else {                      } else {
                         $r->print(qq|<tr><td bgcolor="$rowcol" valign="top"><font face='arial,helvetica,sans-serif'>$qnum.</font></td><td bgcolor="$rowcol" valign="top"><font face='arial,helvetica,sans-serif'><b>$qtype[$i]</b></font></td><td bgcolor="$rowcol" valign="top"><font face='arial,helvetica,sans-serif'>$items[$j]</font></td><td bgcolor="$rowcol" valign="top"><font face='arial,helvetica,sans-serif'>$items[$j+$numitems]</font></td></tr>|);                          my $showfoil = $items->[$j+$numitems];
                           if ($res eq 'application/rtf' || $res eq 'text/html') {
                               $showfoil = &HTML::Entities::decode($showfoil);
                               $showfoil =~ s/<\/?[^>]+>//g;
                           }
                           $r->print(&Apache::loncommon::start_data_table_row().
                                     '<td valign="top">'.$qnum.'</td>'."\n".
                                     '<td valign="top"><input name="createprob" type="checkbox" "checked="checked" value="'.$j.'" /></td>'."\n".
                                     '<td valign="top"><b>'.$qtype[$i].'</b></td>'."\n".
                                     '<td valign="top"><input type="textbox" name="probfile_'.$j.'" value="'.$libfile.'" size="20" /></td>'."\n".
                                     '<td valign="top">'.$items->[$j].'</td>'."\n".
                                     '<td valign="top">'.$showfoil.'</td>'."\n".
                                     &Apache::loncommon::end_data_table_row());
                     }                      }
                     last;                      last;
                 }                  }
             }              }
         }          }
     }      }
     $r->print(qq|      $r->print(&Apache::loncommon::end_data_table().'</p><p>'."\n".
               </table>                '<input type="hidden" name="qnumformat" value="'.$qnumformat.'" />'."\n".
               </td>                '<input type="hidden" name="blocks" value="'.$blocks.'" />');
               </tr>  
               </table>  
              </td>  
             </tr>  
            </table>  
           </td>  
          </tr>  
         </table>  
        </td>  
       </tr>  
       <tr>  
        <td colspan='2'>&nbsp;</td>  
       </tr>  
       <tr bgcolor='#ccddaa'>  
        <td width='30' align='top'><img src='/res/adm/pages/bl_step4.gif'>  
        </td>  
        <td width='100%' align='left'>&nbsp;&nbsp;  
         <font size='+1' face='arial,helvetica,sans-serif'><b>Create a directory to save your testbank questions.</b></font>  
        </td>  
       </tr>  
       <tr>  
        <td colspan='2'>&nbsp;</td>  
       </tr>  
       <tr>  
        <td>&nbsp;</td>  
        <td>  
         <font face='Arial,Helvetica,sans-serif'>  
 Please choose a destination LON-CAPA directory in which to save your uploaded questions.&nbsp;&nbsp;  
        <input type="button" name="createdir" value="Create Directory" onClick="javascript:createWin()"><input type="hidden" name="newdir" value=""></font></td>  
       </tr>  
       <tr>  
        <td colspan='2'>&nbsp;</td>  
       </tr>  
       <tr>  
        <td>&nbsp;</td>  
        <td><font face='arial,helvetica,sans-serif'>If you are satisfied with the questions and answers extracted from your uploaded text file, as shown above, and you have created a destination directory click the "Continue to step 5" button to convert the questions in your testbank to LON-CAPA problem files.</font></td>  
       </tr>  
       <tr>  
        <td colspan='2'>  
           <input type='hidden' name="go" value="">  
           <input type='hidden' name="qnumformat" value="$qnumformat">  
           <input type='hidden' name="blocks" value="$blocks">  
           <input type="hidden" name="uploaduname" value="$uname">  
           <input type="hidden" name="filename" value="$fn">  
           <input type='hidden' name="page" value="$page">  
           <input type="hidden" name="phase" value="three">  
     |);  
     for (my $i=0; $i<$blocks; $i++) {      for (my $i=0; $i<$blocks; $i++) {
         $r->print(qq|          $r->print('
           <input type='hidden' name="start_$i" value="$start[$i]">            <input type="hidden" name="start_'.$i.'" value="'.$start[$i].'" />
           <input type='hidden' name="end_$i" value="$end[$i]">            <input type="hidden" name="end_'.$i.'" value="'.$end[$i].'" />
           <input type='hidden' name="qtype_$i" value="$qtype[$i]">            <input type="hidden" name="qtype_'.$i.'" value="'.$qtype[$i].'" />');
         |);  
         if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "Ord")) {          if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "Ord")) {
             $r->print(qq|              $r->print('
           <input type='hidden' name="foilformat_$i" value="$foilformats[$i]">            <input type="hidden" name="foilformat_'.$i.'" value="'.$foilformats[$i].'" />');
             |);  
         }          }
         if (($qtype[$i] eq "MA") || ($qtype[$i] eq "FIB") || ($qtype[$i] eq "TF") || ($qtype[$i] eq "Ord")) {          if (($qtype[$i] eq "MA") || ($qtype[$i] eq "FIB") || ($qtype[$i] eq "TF") || ($qtype[$i] eq "Ord")) {
             $r->print(qq|              $r->print('
           <input type='hidden' name="ansr_$i" value="$ansrtypes[$i]">            <input type="hidden" name="ansr_'.$i.'" value="'.$ansrtypes[$i].'" />');
             |);          }
         }      }
     }      $r->print('</p>'.&page_footer($env{'form.newdir'},$uname,$fn,$page).'
     $r->print(qq|                </form>');
        </td>  
       </tr>  
       <tr>  
        <td colspan='2'>&nbsp;<br /><br /></td>  
       </tr>  
       <tr>  
        <td colspan='2'>  
         <table border='0' cellspacing='0' cellpadding='0' width="100%">  
          <tr>  
           <td align='left'>  
            <input type="button" name="backpage" value="Go back to step 3" onClick="javascript:backPage()">  
           </td>  
           <td align='right'>  
            <input type="button" name="nextpage" value="Continue to step 5" onClick="javascript:nextPage()">  
           </td>  
          </tr>  
         </table>  
        </td>  
       </tr>  
      </table>  
     </td>  
    </tr>  
   </table>  
 </form>  
     |);  
 }  }
   
 # ---------------------------------------------------------------- Final Display  # ---------------------------------------------------------------- Final Display
 sub final_display {  sub final_display {
     my ($r,$uname,$fn,$page,$textref) = @_;      my ($r,$uname,$fn,$page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) = @_;
     my $qnumformat = $env{'form.qnumformat'};      my $qnumformat = $env{'form.qnumformat'};
     my $blocks = $env{'form.blocks'};      my $blocks = $env{'form.blocks'};
     my $newdir = $env{'form.newdir'};  
     my $linkdir = $newdir;  
     if ($linkdir =~ m#^/home/$uname/public_html/(.+)$#) {  
         $linkdir = '/priv/'.$uname.'/'.$1;  
     }  
     my $question_id = '';      my $question_id = '';
     my @question_title = ();      my @question_title = ();
     my @question_status  = ();      my @question_status  = ();
Line 1126  sub final_display { Line 878  sub final_display {
     my @ansrtypes = ();      my @ansrtypes = ();
     my %multparts = ();      my %multparts = ();
     my $numitems = 0;      my $numitems = 0;
       my @createprobs = &Apache::loncommon::get_env_multiple('form.createprob');
     for (my $i=0; $i<$blocks; $i++) {      for (my $i=0; $i<$blocks; $i++) {
         $start[$i] = $env{"form.start_$i"};          $start[$i] = $env{"form.start_$i"};
         $end[$i] = $env{"form.end_$i"};          $end[$i] = $env{"form.end_$i"};
Line 1146  sub final_display { Line 899  sub final_display {
         $numitems += $nums[$i];          $numitems += $nums[$i];
     }      }
   
     my @bgcolors = ('#ffffff','#eeeeee');      my %answers;
       my ($items,$ids,$footer) = &file_split(\@start,\@end,\@nums,$qnumformat,\@foilformats,$textref,\%multparts,$numitems,\@qtype,$blocks);
     my $import = join/'\s'/,@{$textref};  
     my %answers = ();  
     my @items = &file_split(\@start,\@end,\@nums,$qnumformat,\@foilformats,$textref,\%multparts,$numitems,\@qtype,$blocks);  
   
 # Converting MC and MA answer to number, and splitting answers for FIB, and ordering for Ord.  # Converting MC and MA answer to number, and splitting answers for FIB, and ordering for Ord.
   my @alphabet = ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");      my ($alphabet,$romans) = &get_constants();
     my @romans = ("i","ii","iii","iv","v","vi","vii","viii","ix","x","xi","xii","xiii","xiv","xv","xvi","xvii","xviii","xix","xx","xxi","xxii","xxiii","xxiv","xxv","xxvi");  
     my %patterns = (      my %patterns = (
          comma => ',',           comma => ',',
          space => '\s+',           space => '\s+',
Line 1165  sub final_display { Line 914  sub final_display {
         if ($nums[$i] > 0) {          if ($nums[$i] > 0) {
             if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "FIB") || ($qtype[$i] eq "Ord")) {              if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "FIB") || ($qtype[$i] eq "Ord")) {
                 for (my $k=$numitems+$start[$i]-1; $k<$numitems+$end[$i]; $k++) {                  for (my $k=$numitems+$start[$i]-1; $k<$numitems+$end[$i]; $k++) {
                     @{$answers{$k}} = ();                      my $qnum = $k - $numitems;
                       next if (!grep(/^$qnum$/,@createprobs));
                       if (($res eq 'application/rtf') || ($res eq 'text/html')) {
                           $items->[$k] = &HTML::Entities::decode($items->[$k]);
                       }
                       @{$answers{$qnum}} = ();
                     if ($qtype[$i] eq "MC") {                      if ($qtype[$i] eq "MC") {
                         $items[$k] =~ tr/A-Z/a-z/;                          $items->[$k] =~ tr/A-Z/a-z/;
                         $items[$k] =~ s/\W//g;                          $items->[$k] =~ s/<\/?[^>]+>//g;
                           $items->[$k] =~ s/\W//g;
                         if ($foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "lconeparen" || $foilformats[$i] eq "lcdotparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod" || $foilformats[$i] eq "uconeparen" || $foilformats[$i] eq "ucdotparen") {                          if ($foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "lconeparen" || $foilformats[$i] eq "lcdotparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod" || $foilformats[$i] eq "uconeparen" || $foilformats[$i] eq "ucdotparen") {
                             for (my $j=0; $j<@alphabet; $j++) {                              for (my $j=0; $j<@{$alphabet}; $j++) {
                                 if ($alphabet[$j] eq $items[$k]) {                                  if ($alphabet->[$j] eq $items->[$k]) {
                                     push @{$answers{$k}}, $j;                                      push @{$answers{$qnum}}, $j;
                                     last;                                      last;
                                 }                                  }
                             }                              }
                         } elsif (($foilformats[$i] eq "romparen") || ($foilformats[$i] eq "romperiod") || ($foilformats[$i] eq "romoneparen") || ($foilformats[$i] eq "romdotparen")) {                          } elsif (($foilformats[$i] eq "romparen") || ($foilformats[$i] eq "romperiod") || ($foilformats[$i] eq "romoneparen") || ($foilformats[$i] eq "romdotparen")) {
                             for (my $j=0; $j<@romans; $j++) {                              for (my $j=0; $j<@{$romans}; $j++) {
                                 if ($romans[$j] eq $items[$k]) {                                  if ($romans->[$j] eq $items->[$k]) {
                                     push @{$answers{$k}}, $j;                                      push @{$answers{$qnum}}, $j;
                                     last;                                      last;
                                 }                                  }
                             }                              }
                         }                          }
                     } elsif (($qtype[$i] eq "MA") || ($qtype[$i] eq "Ord")) {                      } elsif (($qtype[$i] eq "MA") || ($qtype[$i] eq "Ord")) {
                         $items[$k] =~ tr/A-Z/a-z/;                          $items->[$k] =~ tr/A-Z/a-z/;
                         my @corrects = split/$patterns{$ansrtypes[$i]}/,$items[$k];                          $items->[$k] =~ s/<\/?[^>]+>//g;
                           my @corrects = split/$patterns{$ansrtypes[$i]}/,$items->[$k];
                         foreach my $correct (@corrects) {                          foreach my $correct (@corrects) {
                             my @tied;                              my @tied;
                             if ($qtype[$i] eq "Ord") {                              if ($qtype[$i] eq "Ord") {
Line 1202  sub final_display { Line 958  sub final_display {
                                 $correct =~s/\W//g;                                  $correct =~s/\W//g;
                             }                              }
                             if ($foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod") {                              if ($foilformats[$i] eq "lcperiod" || $foilformats[$i] eq "lcparen" || $foilformats[$i] eq "ucparen" || $foilformats[$i] eq "ucperiod") {
                                 if (($qtype[$i] eq "Ord") && (@tied > 0)) {                                   if (($qtype[$i] eq "Ord") && (@tied > 0)) {
                                     my @ties;                                      my @ties;
                                     foreach my $tie (@tied) {                                      foreach my $tie (@tied) {
                                         for (my $j=0; $j<@alphabet; $j++) {                                          for (my $j=0; $j<@{$alphabet}; $j++) {
                                             if ($alphabet[$j] eq $tie) {                                              if ($alphabet->[$j] eq $tie) {
                                                 push(@ties,$j);                                                  push(@ties,$j);
                                                 last;                                                  last;
                                             }                                              }
                                         }                                          }
                                     }                                      }
                                     my $ans = join('=',@ties);                                      my $ans = join('=',@ties);
                                     push(@{$answers{$k}},$ans);                                      push(@{$answers{$qnum}},$ans);
                                 } else {                                  } else {
                                     for (my $j=0; $j<@alphabet; $j++) {                                      for (my $j=0; $j<@{$alphabet}; $j++) {
                                         if ($alphabet[$j] eq $correct) {                                          if ($alphabet->[$j] eq $correct) {
                                             push @{$answers{$k}}, $j;                                              push @{$answers{$qnum}}, $j;
                                             last;                                              last;
                                         }                                          }
                                     }                                      }
Line 1226  sub final_display { Line 982  sub final_display {
                                 if (($qtype[$i] eq "Ord") && (@tied > 0)) {                                  if (($qtype[$i] eq "Ord") && (@tied > 0)) {
                                     my @ties;                                      my @ties;
                                     foreach my $tie (@tied) {                                      foreach my $tie (@tied) {
                                         for (my $j=0; $j<@romans; $j++) {                                          for (my $j=0; $j<@{$romans}; $j++) {
                                             if ($romans[$j] eq $tie) {                                              if ($romans->[$j] eq $tie) {
                                                 push(@ties,$j);                                                  push(@ties,$j);
                                                 last;                                                  last;
                                             }                                              }
                                         }                                          }
                                     }                                      }
                                     push(@{$answers{$k}},join('=',@ties));                                      push(@{$answers{$qnum}},join('=',@ties));
                                 } else {                                  } else {
                                     for (my $j=0; $j<@romans; $j++) {                                      for (my $j=0; $j<@{$romans}; $j++) {
                                         if ($romans[$j] eq $correct) {                                          if ($romans->[$j] eq $correct) {
                                             push @{$answers{$k}}, $j;                                              push @{$answers{$qnum}}, $j;
                                             last;                                              last;
                                         }                                          }
                                     }                                      }
Line 1245  sub final_display { Line 1001  sub final_display {
                             }                              }
                         }                          }
                     } elsif ($qtype[$i] eq "FIB") {                      } elsif ($qtype[$i] eq "FIB") {
                         @{$answers{$k}} = split/$patterns{$ansrtypes[$i]}/,$items[$k];                          $items->[$k] =~ s/<\/?[^>]+>//g;
                         for (my $j=0; $j<@{$answers{$k}}; $j++) {                          @{$answers{$qnum}} = split/$patterns{$ansrtypes[$i]}/,$items->[$k];
                             $answers{$k}[$j] =~ s/^\s+//;                          for (my $j=0; $j<@{$answers{$qnum}}; $j++) {
                             $answers{$k}[$j] =~ s/\s+$//;                              $answers{$qnum}[$j] =~ s/^\s+//;
                               $answers{$qnum}[$j] =~ s/\s+$//;
                               if ($j==0) {
                                   $answers{$qnum}[$j] =~ s/^<[^>]+>//;
                               } elsif ($j == @{$answers{$qnum}}-1) {
                                   $answers{$qnum}[$j] =~ s/<\/[^>]+>$//;
                               }
                         }                          }
                     }                      }
                 }                  }
             }              }
         }          }
     }      }
     my $pooltarget = '';      my $state;
     my $pooldesc = '';  
     my @newquestions = ();      $r->print('<form name="verify" method="post" action="/adm/testbank">'."\n".
     my $numquestions = 0;                '<input type="hidden" name="blocks" value="'.$blocks.'" />'."\n".
     my %qtype = ();                '<input type="hidden" name="qnumformat" value="'.$qnumformat.'" />'."\n");
     my %qtext = ();      for (my $i=0; $i<$blocks; $i++) {
     my %qflag = ();         $r->print('<input type="hidden" name="start_'.$i.'" value="'.$start[$i].'" />
              <input type="hidden" name="end_'.$i.'" value="'.$end[$i].'" />
     $r->print(<<"END_OF_BLOCK");             <input type="hidden" name="qtype_'.$i.'" value="'.$qtype[$i].'" />
         <form name="verify" method="post">             <input type="hidden" name="foilformat_'.$i.'" value="'.$foilformats[$i].'" />
         <table border='0' cellspacing='0' cellpadding='0' width="100%">             <input type="hidden" name="ansr_'.$i.'" value="'.$ansrtypes[$i].'" />'."\n");
          <tr>      }
           <td colspan='2'  align='left'>&nbsp;      for (my $i=0; $i<$numitems; $i++) {
           </td>          $r->print('<input type="hidden" name="probfile_'.$i.'" value="'.$env{'form.probfile_'.$i}.'" />'."\n");
          </tr>      }
          <tr bgcolor='#ccddaa'>      $r->print(&topic_bar(6,&mt('Result of conversion of testbank questions to LON-CAPA problems')));
           <td align='top'>&nbsp;      my $destdir = $dirpath;
           </td>      if ($destdir ne '' && $subdir ne '') {
           <td valign='middle'><img src='/res/adm/pages/bl_step5.gif'>&nbsp;&nbsp;          $subdir .= '/';
            <font size='+1' face='arial,helvetica,sans-serif'>&nbsp;<b>Result of conversion of tesbank questions to LON-CAPA problems.</b></font>          $destdir .= $subdir; 
           </td>      }
          </tr>      if (@createprobs == 0) {
          <tr>          $state = 'unchecked';
           <td colspan='2'>&nbsp;</td>          $r->print('<p>'.&mt('No questions were selected for conversion.').'</p>'.
          </tr>                    &page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).'</form>');
 END_OF_BLOCK      } elsif (($destdir ne '') && (-e $destdir)) {
     if ($newdir ne "") {          my (@qn_file,@result,@numid);
         my @qn_file = ();  
         my $qcount = 0;          my $qcount = 0;
           my $itemcount = 0;
         for (my $i=0; $i<$blocks; $i++) {          for (my $i=0; $i<$blocks; $i++) {
             if ($nums[$i] > 0) {              if ($nums[$i] > 0) {
                 if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "FIB") || ($qtype[$i] eq "Ord")) {                  if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "FIB") || ($qtype[$i] eq "Ord")) {
                     for (my $j=$start[$i]-1; $j<$end[$i]; $j++) {                      for (my $j=$start[$i]-1; $j<$end[$i]; $j++) {
                           $numid[$qcount] = $ids->[$itemcount];
                           $itemcount ++;
                           next if (!grep(/^$qcount$/,@createprobs));
                           my $libfile = &probfile_name($j);
                         my $answer = $j + $numitems;                          my $answer = $j + $numitems;
                         my $numans = scalar(@{$answers{$answer}});                          my $numans = scalar(@{$answers{$qcount}});
                         my $foilcount = 0;                          my $foilcount = 0;
                         if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "Ord")) {                           if (($qtype[$i] eq "MC") || ($qtype[$i] eq "MA") || ($qtype[$i] eq "Ord")) { 
                             $foilcount = @{$multparts{$j}};                              $foilcount = @{$multparts{$j}};
                             $foilcount --;                              $foilcount --;
                         }                          }
                         $qn_file[$qcount] = &create_mcq($newdir,\@{$multparts{$j}},\@{$answers{$answer}},$qtype[$i],$j);                          ($result[$qcount],$qn_file[$qcount]) = &create_mcq($destdir,$subdir,\@{$multparts{$j}},\@{$answers{$qcount}},$qtype[$i],$libfile,$res,$header,$footer,$js,$css);
                         $qcount ++;                          $qcount ++;
                         push @newquestions, $question_id;  
                     }                      }
                 } elsif ($qtype[$i] eq "TF") {                  } elsif ($qtype[$i] eq "TF") {
                     for (my $j=$start[$i]-1; $j<$end[$i]; $j++) {                      for (my $j=$start[$i]-1; $j<$end[$i]; $j++) {
                           $numid[$qcount] = $ids->[$itemcount];
                           $itemcount ++;
                           next if (!grep(/^$qcount$/,@createprobs));
                           my $libfile = &probfile_name($j);
                         my $answer = $j + $numitems;                          my $answer = $j + $numitems;
                         $items[$answer] =~ s/^\s+//;                          $items->[$answer] =~ s/^\s+//;
                         $items[$answer] =~ s/\s+$//;                          $items->[$answer] =~ s/\s+$//;
                         $items[$answer] =~ s/\W//g;                          $items->[$answer] =~ s/\W//g;
                         $items[$answer] =~ tr/A-Z/a-z/;                          $items->[$answer] =~ tr/A-Z/a-z/;
                         my $answer_id = '';                          my $answer_id = '';
                         if ($ansrtypes[$i] eq 'word' ) {                          if ($ansrtypes[$i] eq 'word' ) {
                             if ($items[$answer] =~ m/true/) {                              if ($items->[$answer] =~ m/true/) {
                                 $answer_id = 0;                                  $answer_id = 0;
                             } else {                              } else {
                                 $answer_id = 1;                                  $answer_id = 1;
                             }                              }
                         } elsif ($ansrtypes[$i] eq 'lett') {                          } elsif ($ansrtypes[$i] eq 'lett') {
                             if ($items[$answer] =~ m/^t/) {                              if ($items->[$answer] =~ m/^t/) {
                                 $answer_id = 0;                                  $answer_id = 0;
                             } else {                              } else {
                                 $answer_id = 1;                                  $answer_id = 1;
                             }                              }
                         }                          }
                         $qn_file[$qcount] = create_ess($newdir,$answer_id,$items[$j],$items[$answer],$qtype[$i],$j);                          ($result[$qcount],$qn_file[$qcount]) = &create_ess($destdir,$subdir,$answer_id,$items->[$j],$items->[$answer],$qtype[$i],$libfile,$res,$header,$footer,$js,$css);
                         push @newquestions, $question_id;  
                         $qcount ++;                          $qcount ++;
                     }                      }
                 } elsif ($qtype[$i] eq "Ess") {                  } elsif ($qtype[$i] eq "Ess") {
                     for (my $j=$start[$i]-1; $j<$end[$i]; $j++) {                      for (my $j=$start[$i]-1; $j<$end[$i]; $j++) {
                           $numid[$qcount] = $ids->[$itemcount];
                           $itemcount ++;
                           next if (!grep(/^$qcount$/,@createprobs));
                           my $libfile = &probfile_name($j);
                         my $answer = $j + $numitems;                          my $answer = $j + $numitems;
                         my $answer_id = '';                          my $answer_id = '';
                         $qn_file[$qcount] = create_ess($newdir,$answer_id,$items[$j],$items[$answer],$qtype[$i],$j);                          ($result[$qcount],$qn_file[$qcount]) = &create_ess($destdir,$subdir,$answer_id,$items->[$j],$items->[$answer],$qtype[$i],$libfile,$res,$header,$footer,$js,$css);
                         push @newquestions, $question_id;  
                         $qcount ++;                          $qcount ++;
                     }                      }
                 }                  }
             }              }
         }          }
         $r->print(qq|<tr><tr><td>&nbsp;</td><td><font face='arial,helvetica,sans-serif'>Individual problem files have been created from the problems included in the textbank file:          my ($successes,$failures,$existing);
        <ul>|);  
         for (my $i=0; $i<@qn_file; $i++) {          for (my $i=0; $i<@qn_file; $i++) {
             my $display = $i+1;              if ($result[$i] eq 'ok') {
             $r->print(qq|                  $successes .= '<b>'.$numid[$i].':&nbsp;<a href="'.$webpath.$qn_file[$i].'">'.
        <li><b><a href="$linkdir/$qn_file[$i]">Problem $display file</a></b></li>                            $qn_file[$i].'</a></b><br />'."\n";
             |);              } elsif ($result[$i] eq 'failed') {
         }                  $failures .= $numid[$i].':&nbsp;'.$qn_file[$i].'<br />'."\n";
         $r->print(qq|              } elsif ($result[$i] eq 'exists') {
        </ul></font></td></tr>                  $existing .= '<b>'.$numid[$i].':&nbsp;<a href="'.$webpath.$qn_file[$i].'">'.
        <tr><td>&nbsp;</td>                            $qn_file[$i].'</a></b><br />'."\n";
            <td><font face='arial,helvetica,sans-serif'>The problems must be published before they can be used in a course.</font></td>              }
         |);          }
           if ($successes) {
               $r->print('<p>'.&mt('Individual problem files have been created from the following problems included in the testbank file:').'<br />'.$successes.'</p><p>'.
                        &mt('The problems must be published before they can be used in a course').'</p>');
           }
           if ($failures) {
               $r->print('<p>'.&mt('An error occurred when opening files for the following problems, so they have not been created:').'<br />'.$failures.'</p>');
           }
           if ($existing) {
               $r->print('<p>'.&mt('The following files already existed, and were not overwritten so these problems generated from the testbank have not been saved:').'<br />'.$existing.'</p>');
               $state = 'existing';
           }
           $r->print(&page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).'</form>');
     } else {      } else {
         $r->print(qq|          $state = 'nodir';
          <tr>          $r->print('<p>'.&mt('No destination directory was available so import of questions could not proceed.').'</p>'.
           <td>&nbsp;</td>                    &page_footer($env{'form.newdir'},$uname,$fn,$page,$webpath,$subdir,$state).'</form>');
           <td><font face='arial,helvetica,sans-serif'>No destination file was selected or created, so import of your questions could not proceed.        }
           Please return to the previous page and select a valid file into which to import the questions. </font>  
            <input type="hidden" name="go" value="">  
            <input type="hidden" name="page" value="$page">  
            <input type="hidden" name="uploaduname" value="$uname">  
            <input type="hidden" name="filename" value="$fn">  
            <input type='hidden' name="page" value="$page">  
            <input type="hidden" name="phase" value="three">  
            <input type="hidden" name="qnumformat" value="$qnumformat">  
            <input type="hidden" name="newdir" value="$newdir">  
         |);  
         for (my $i=0; $i<$blocks; $i++) {  
            $r->print(qq|  
            <input type="hidden" name="start_$i" value="$start[$i]">  
            <input type="hidden" name="end_$i" value="$end[$i]">  
            <input type="hidden" name="qtype_$i" value="$qtype[$i]">  
            <input type="hidden" name="foilformat_$i" value="$foilformats[$i]">  
            <input type="hidden" name="ansr_$i" value="$ansrtypes[$i]">  
             |);  
         }  
         $r->print(<<"END_OF_FAIL");  
           </td>  
          </tr>  
          <tr>  
           <td colspan='2'>  
            <table border='0' width='100%'>  
             <tr>  
              <td align='right'>  
               <input type="button" name="backpage" value="Return to step 3" onClick="javascript:backPage()">  
              </td>  
             </tr>  
            </table>  
           </td>  
          </tr>  
         </table>  
        </td>  
       </tr>  
      </table>  
     </td>  
    </tr>  
   </table>  
  </form>  
 END_OF_FAIL  
     return;      return;
   }  }
   $r->print(<<"END_OF_BODY");  
              </table>  sub show_uploaded_data {
             </td>      my ($textref,$header) = @_;
            </tr>      my $output = '<p><b>'.&mt('Testbank data uploaded to the server').'</b></p><p>'."\n".
           </table>                   '<textarea name="rawdata" cols="70" rows="6" wrap="virtual" align="center">'."\n";
         </td>      if ($header ne '') {
        </tr>          $output .= $header."\n";
        <tr>      }
         <td colspan='2'>&nbsp;      if (ref($textref) eq 'ARRAY') {
          <input type="hidden" name="go" value="">          foreach my $line (@{$textref}) {
          <input type="hidden" name="page" value="$page">             $line =~ s/\n//g;
          <input type="hidden" name="uploaduname" value="$uname">             if ($line ne '') {
          <input type="hidden" name="filename" value="$fn">                 $output .= $line."\n";
          <input type='hidden' name="page" value="$page">             }
          <input type="hidden" name="phase" value="one">          }
          <input type="hidden" name="qnumformat" value="$qnumformat">       }
          <input type="hidden" name="newdir" value="$newdir">      $output .= '</textarea></p>';
         </td>      return $output;
        </tr>  }
        <tr>  
         <td colspan='2'>  sub page_footer {
          <table border='0' width='100%'>      my ($newdir,$uname,$fn,$page,$webpath,$subdir,$state) = @_;
           <tr>      my $prevval = &mt('Previous Page');
            <td align='left'>      my $nextval = &mt('Next Page');
              <input type='button' name='backtostart' value='Back to start page' onClick='javascript:backtoStart()'>      my $prevclick = 'javascript:backPage();';
            </td>      my $nextclick = 'javascript:nextPage();';
           </tr>      my $go = ''; 
          </table>      if ($page == 0) {
         </td>          $go = 'NextPage';
        </tr>          $prevval = &mt('Exit Now');
       </table>          $prevclick = 'javascript:location.href='."'$webpath';";
      </td>          $nextclick = 'javascript:submit();'
     </tr>      } elsif ($page == 3) {
    </table>          $nextval = &mt('Complete Testbank Conversion');
   </td>      } elsif ($page == 4) {
  </tr>          if (($state ne 'existing') && ($state ne 'unchecked')) {
 </table>              my $destdir = $webpath;
 </form>              if ($subdir ne '') {
 END_OF_BODY                  $destdir = $webpath.$subdir;
               }
               $prevval = &mt('Back to Directory');
               $prevclick = 'javascript:location.href='."'$destdir';";
          }
       }
       my $output = '
          <input type="hidden" name="newdir" value="'.&HTML::Entities::encode($newdir,'<>&"').'" />
          <input type="hidden" name="uploaduname" value="'.$uname.'" />
          <input type="hidden" name="filename" value="'.$fn.'" />
          <input type="hidden" name="page" value="'.$page.'" />
          <input type="hidden" name="phase" value="three" />
          <input type="hidden" name="go" value="'.$go.'" />';
       if ($page ne '') {
           $output .= '
          <table border="0">
           <tr>
            <td>
             <input type="button" name="backpage" value="'.$prevval.'" onclick="'.$prevclick.'" />
            </td>';
           if ($page < 4)  {
               $output .= '
            <td>&nbsp;</td>
            <td>
             <input type="button" name="nextpage" value="'.$nextval.'" onclick="'.$nextclick.'">
            </td>';
           }
           $output .= '    </tr>
          </table>
   ';
       }
       return $output;
 }  }
   
 sub question_count {  sub question_count {
Line 1461  sub question_count { Line 1232  sub question_count {
     return $qcount;      return $qcount;
 }  }
   
   sub get_constants {
       my @alphabet = ("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z");
       my @romans = ("i","ii","iii","iv","v","vi","vii","viii","ix","x","xi","xii","xiii","xiv","xv","xvi","xvii","xviii","xix","xx","xxi","xxii","xxiii","xxiv","xxv","xxvi");
       return (\@alphabet,\@romans);
   }
   
 sub file_split {  sub file_split {
     my ($startsref,$endsref,$numsref,$qnumformat,$foilsref,$textref,$multpartsref,$numitems,$qtyperef,$blocks) = @_;      my ($startsref,$endsref,$numsref,$qnumformat,$foilsref,$textref,$multpartsref,$numitems,$qtyperef,$blocks) = @_;
     my $text_in = join "\n", @{$textref};      my $text_in = join "\n", @{$textref};
     $text_in = "\n ".$text_in;      $text_in = "\n ".$text_in;
     my $dignum = length($numitems);      my $dignum = length($numitems);
     my $numpat;      my ($qpatst,$qpatend,$numpat,@questions,@qids);
       my $numpat = '\d{1';
     if ($dignum > 1) {      if ($dignum > 1) {
         $numpat = ','.$dignum.'}';          $numpat .= ','.$dignum.'}';
     } else {      } else {
         $numpat = '}';          $numpat .= '}';
     }      }
     my $qpattern ='';  
     if ($qnumformat eq "period") {      if ($qnumformat eq "period") {
         $qpattern = '\d{1'.$numpat.'\.';           $qpatend = '\.'; 
     } elsif ($qnumformat eq "paren") {      } elsif ($qnumformat eq "paren") {
         $qpattern = '\(\d{1'.$numpat.'\)';          $qpatst = '\(';
     } elsif ($qnumformat eq "number") {          $qpatend = '\)';
         $qpattern = '\d{1'.$numpat;  
     } elsif ($qnumformat eq "leadparen") {      } elsif ($qnumformat eq "leadparen") {
         $qpattern = '\(\d{1'.$numpat;          $qpatst = '\(';
     } elsif ($qnumformat eq "trailparen") {      } elsif ($qnumformat eq "trailparen") {
         $qpattern = '\d{1'.$numpat.'\)';          $qpatend = '\)';
     }      }
     my @questions = split/[\r\n\f]+\s*$qpattern\s*/,$text_in;      my @lines = split/[\r\n\f]+\s*$qpatst($numpat)$qpatend\s*/,$text_in;
 # my @questions = split/\n\s\d{1,3}\.\s/,$text_in;  # my @questions = split/\n\s\d{1,3}\.\s/,$text_in;
     shift @questions;      shift(@lines);
       for (my $i=0; $i<@lines; $i++) {
           if ($i%2) {
               push(@questions,$lines[$i]);
           } else {
               push(@qids,$lines[$i]);
           }
       }
     my %multparts = ();      my %multparts = ();
     for (my $i=0; $i<$blocks; $i++) {      for (my $i=0; $i<$blocks; $i++) {
         if (${$numsref}[$i] > 0) {          if (${$numsref}[$i] > 0) {
Line 1527  sub file_split { Line 1310  sub file_split {
                 }                  }
             }              }
         }          }
     }          }
       my ($lastanswer,$footer) = ($questions[-1] =~ /^([,\r\n\f\t\s().A-Za-z]+)(.+)$/);
       if ($footer ne '') {
           $questions[-1] = $lastanswer;
       }
     %{$multpartsref} = %multparts;      %{$multpartsref} = %multparts;
     return @questions;      return (\@questions,\@qids,$footer);
 }  }
     
 # create_mcq builds an MC, MA, Ord or FIB question  # create_mcq builds an MC, MA, Ord or FIB question
   
 sub create_mcq {  sub create_mcq {
     my ($newdir,$qstnref,$answerref,$qtype,$qnum) = @_;      my ($destdir,$subdir,$qstnref,$answerref,$qtype,$libfile,$res,$header,$footer,$js,$css) = @_;
     $qnum ++;  
     if (length($qnum) == 1) {  
         $qnum = "00".$qnum;  
     } elsif (length($qnum) == 2) {  
         $qnum = "0".$qnum;  
     }  
     my $qstn = ${$qstnref}[0];      my $qstn = ${$qstnref}[0];
     my $numfoils = scalar(@{$qstnref}) - 1;       my $numfoils = scalar(@{$qstnref}) - 1; 
     my $datestamp = localtime;      my $datestamp = localtime;
     my $timestamp = time;      my $timestamp = time;
     my $libfile = 'question_'.$qnum;  
     $libfile .= '.problem';  
     my $numansrs = scalar(@{$answerref});      my $numansrs = scalar(@{$answerref});
     my $output = qq|<problem>      my $output = '<problem>
  <startouttext />$qstn<endouttext />   <startouttext />';
     |;      if ($res eq 'application/rtf' || $res eq 'text/html') {
             if ($header ne '') {
               $output .= &HTML::Entities::decode($header);
           }
           if ($js ne '') {
               $output .= &HTML::Entities::decode($js);
           }
           if ($css ne '') {
               $output .= &HTML::Entities::decode($css);
           }
           $qstn = &HTML::Entities::decode($qstn);
       }
       $output .= $qstn.'<endouttext />'."\n";
     if ($qtype eq "MA") {      if ($qtype eq "MA") {
         $output .= qq|          $output .= qq|
    <optionresponse max="$numfoils" randomize="yes">     <optionresponse max="$numfoils" randomize="yes">
Line 1565  sub create_mcq { Line 1356  sub create_mcq {
             } else {              } else {
                 $output .= "False\" location=\"random\"";                  $output .= "False\" location=\"random\"";
             }              }
             $output .= "\><startouttext />".${$qstnref}[$k+1]."<endouttext /></foil>\n";              my $showfoil = ${$qstnref}[$k+1];
               if ($res eq 'application/rtf' || $res eq 'text/html') {
                   $showfoil = &HTML::Entities::decode($showfoil);
               }
               $output .= "\><startouttext />$showfoil<endouttext /></foil>\n";
         }          }
         chomp($output);          chomp($output);
         $output .= qq|          $output .= qq|
     </foilgroup>      </foilgroup>
    </optionresponse>     </optionresponse>|;
   </problem>  
         |;  
     }      }
     if ($qtype eq "MC") {      if ($qtype eq "MC") {
         $output .= qq|          $output .= qq|
Line 1591  sub create_mcq { Line 1384  sub create_mcq {
             } else {              } else {
                 $output .= "random\"";                  $output .= "random\"";
             }              }
             $output .= "\><startouttext />".${$qstnref}[$k+1]."<endouttext /></foil>\n";              my $showfoil = ${$qstnref}[$k+1];
               if ($res eq 'application/rtf' || $res eq 'text/html') {
                   $showfoil = &HTML::Entities::decode($showfoil);
               }
               $output .= "\><startouttext />$showfoil<endouttext /></foil>\n";
         }          }
         chomp($output);          chomp($output);
         $output .= qq|          $output .= qq|
     </foilgroup>      </foilgroup>
    </radiobuttonresponse>     </radiobuttonresponse>|;
   </problem>  
         |;  
     }      }
   
     if ($qtype eq "Ord") {      if ($qtype eq "Ord") {
         $output .= qq|          $output .= qq|
    <rankresponse max="$numfoils" randomize="yes">     <rankresponse max="$numfoils" randomize="yes">
Line 1626  sub create_mcq { Line 1420  sub create_mcq {
                     $num ++;                      $num ++;
                 }                  }
             }              }
             $output .= "   <foil location=\"random\" name=\"foil".$k."\" value=\"".$ansval."\"><startouttext />".${$qstnref}[$k+1]."<endouttext /></foil>\n";              my $showfoil = ${$qstnref}[$k+1];
               if ($res eq 'application/rtf' || $res eq 'text/html') {
                   $showfoil = &HTML::Entities::decode($showfoil);
               }
               $output .= "   <foil location=\"random\" name=\"foil".$k."\" value=\"".$ansval."\"><startouttext />$showfoil<endouttext /></foil>\n";
         }          }
         chomp($output);          chomp($output);
         $output .= qq|          $output .= qq|
     </foilgroup>      </foilgroup>
    </rankresponse>     </rankresponse>|;
   </problem>  
         |;  
     }      }
      
     if ($qtype eq "FIB") {      if ($qtype eq "FIB") {
         my $numerical = 1;          my $numerical = 1;
         for (my $i=0; $i<@{$answerref}; $i++) {          for (my $i=0; $i<@{$answerref}; $i++) {
Line 1667  sub create_mcq { Line 1462  sub create_mcq {
  <responseparam type="tolerance" default="$tol%" name="tol" description="Numerical Tolerance" />   <responseparam type="tolerance" default="$tol%" name="tol" description="Numerical Tolerance" />
  <responseparam name="sig" type="int_range,0-16" default="0,15" description="Significant Figures" />   <responseparam name="sig" type="int_range,0-16" default="0,15" description="Significant Figures" />
  <textline />   <textline />
 </numericalresponse>  </numericalresponse>|;
 </problem>  
 |;  
         } else {          } else {
             if (@{$answerref} == 1) {              if (@{$answerref} == 1) {
                 $output .= qq|                  $output .= qq|
 <stringresponse answer="$$answerref[0]" type="ci">  <stringresponse answer="$$answerref[0]" type="ci">
 <textline>  <textline>
 </textline>  </textline>
 </stringresponse>  </stringresponse>|;
 </problem>  
 |;  
             } else {              } else {
                 for (my $i=0; $i<@{$answerref}; $i++) {                  for (my $i=0; $i<@{$answerref}; $i++) {
                     ${$answerref}[$i] =~ s/\|/\|/g;                      ${$answerref}[$i] =~ s/\|/\|/g;
Line 1689  sub create_mcq { Line 1480  sub create_mcq {
 <stringresponse answer="$regexpans" type="re">  <stringresponse answer="$regexpans" type="re">
 <textline>  <textline>
 </textline>  </textline>
 </stringresponse>  </stringresponse>|;
 </problem>  
 |;  
             }              }
         }          }
     }      }
     open(PROB,">$newdir/$libfile");      if ($footer ne '') {
     print PROB $output;          $output .= '<startouttext />'.&HTML::Entities::decode($footer).'<endouttext />';
     close PROB;      }
     return $libfile;      $output .= qq|
     </problem>
   |;
       my $result;
       if (-e $destdir.$libfile) {
           $result = 'exists';
       } else {
           if (open(PROB,">$destdir$libfile")) {
               print PROB $output;
               close(PROB);
               $result = 'ok';
           } else {
               $result = 'failed';
           } 
       }
       return ($result,$subdir.$libfile);
 }  }
   
 # create_ess builds an essay or True/False question  # create_ess builds an essay or True/False question
   
 sub create_ess {  sub create_ess {
     my ($newdir,$answer_id,$qstn,$answertxt,$qtype,$qnum) = @_;      my ($destdir,$subdir,$answer_id,$qstn,$answertxt,$qtype,$libfile,$res,$header,
     $qnum ++;          $footer,$js,$css) = @_;
     if (length($qnum) == 1) {      my $output = '<problem>
         $qnum = "00".$qnum;   <startouttext />';
     } elsif (length($qnum) == 2) {      if ($res eq 'application/rtf' || $res eq 'text/html') {
         $qnum = "0".$qnum;          if ($header ne '') {
     }              $output .= &HTML::Entities::decode($header);
     my $libfile = 'question_'.$qnum;          }
     $libfile .= '.problem';          if ($js ne '') {
     my $output = qq|<problem>              $output .= &HTML::Entities::decode($js);
  <startouttext />$qstn<endouttext />|;          }
           if ($css ne '') {
               $output .= &HTML::Entities::decode($css);
           }
           $qstn = &HTML::Entities::decode($qstn);
           $answertxt = &HTML::Entities::decode($answertxt);
       }
       $output .= $qstn.'<endouttext />';
     my $answer = '';      my $answer = '';
     my $answerlog = '';      my $answerlog = '';
     if ($qtype eq "Ess") {      if ($qtype eq "Ess") {
         $output .= qq|          $output .= '
    <essayresponse>     <essayresponse>
    <textfield></textfield>     <textfield></textfield>
    </essayresponse>     </essayresponse>
    <postanswerdate>     <postanswerdate>
     <startouttext />      <startouttext />
    $answertxt     '.$answertxt
     <endouttext />     .'<endouttext />
    </postanswerdate>     </postanswerdate>';
   </problem>|;  
     } elsif ($qtype eq "TF") {      } elsif ($qtype eq "TF") {
          $answer = $answer_id;           $answer = $answer_id;
          $output .= qq|           $output .= qq|
Line 1748  sub create_ess { Line 1557  sub create_ess {
          } else {           } else {
               $output .= "False";                $output .= "False";
          }           }
          $output .= qq|<endouttext /></foil>           $output .= '<endouttext /></foil>
     </foilgroup>      </foilgroup>
    </radiobuttonresponse>     </radiobuttonresponse>';
   </problem>|;  
      }       }
      open(PROB,">$newdir/$libfile");       if ($footer ne '') {
      print PROB $output;          $output .= '
      close PROB;  <startouttext />'.&HTML::Entities::decode($footer).'<endouttext />';
      return $libfile;       }
        $output .= '
     </problem>
   ';
        my $result;
        if (-e $destdir.$libfile) {
            $result = 'exists';
        } else {
            if (open(PROB,">$destdir$libfile")) {
                print PROB $output;
                close(PROB);
            } else {
                $result = 'failed';
            }
        }
        return ($result,$subdir.$libfile);
   }
   
   sub probfile_name {
       my ($j) = @_;
       my $libfile = &HTML::Entities::decode($env{'form.probfile_'.$j});
       my $qnum = $j + 1;
       if ($libfile eq '') {
           if (length($qnum) == 1) {
               $qnum = "00".$qnum;
           } elsif (length($qnum) == 2) {
               $qnum = "0".$qnum;
           }
           $libfile = 'testbank_question_'.$qnum;
           $libfile .= '.problem';
       }
       return $libfile;
 }  }
   
 sub file_error {  sub file_error {
     my ($r,$uname,$fn,$current_page);      my ($r,$uname,$fn,$current_page);
     $r->print("No data here");      $r->print("No data here");
 }   }
   
   sub parse_datafile {
       my ($r,$uname,$filename,$pathname,$dirpath,$urlpath,$page_name,$subdir) = @_;
       my ($badfile,$res,%allfiles,%codebase);
       my $mm = new File::MMagic;
       my ($text,$header,$css,$js);
       if (-e "$dirpath") {
           $res = $mm->checktype_filename($dirpath.$filename);
           if ($env{'form.phase'} eq 'three') {          
               if ($res eq 'text/plain') {
                   open(TESTBANK,"<$dirpath$filename");
                   @{$text} = <TESTBANK>;
                   close(TESTBANK);
               } elsif ($res eq 'application/rtf') {
                   my $html = '';
   #                my $image_uri = '..'.$pathname;
                   my $image_uri = $pathname;
                   if ($page_name eq 'Target') {
                       $image_uri = $urlpath;
                   }
                   $image_uri =~ s/\/$//;
                   my $image_dir;
                   if ($page_name eq 'Blocks') {
                       $image_dir = $dirpath;
                       $image_dir =~ s/\/$//;
                   } else {
                       $image_dir = $r->dir_config('lonDaemons').'/tmp/'.
                                    $env{'user.name'}.'_'.$env{'user.domain'}.
                                    '_rtfupload_'.$filename.'_'.time.'_'.$$;
                      if (!-e $image_dir) {
                          mkdir($image_dir,0755);
                      }
                   }
                   my $parser = RTF::HTMLConverter->new (
                                     in                => $dirpath.$filename,
                                     out               => \$html,
                                     DOMImplementation => 'XML::DOM',
                                     image_uri         => $image_uri,
                                     image_dir         => $image_dir,
                                );
                   $parser->parse();
                   utf8::decode($html);
                   ($text,$header,$css,$js) = 
                       &parse_htmlcontent($res,$subdir,$html);
               } elsif ($res eq 'text/html') {
                   ($text,$header,$css,$js) = 
                       &parse_htmlcontent($res,$subdir,undef,$dirpath.$filename);
               } else {
                   $badfile = 1;
               }
           }
       }
       return ($res,$badfile,$text,$header,$css,$js,\%allfiles,\%codebase);
   }
   
   sub parse_htmlcontent {
       my ($res,$subdir,$html,$fullpath) = @_;
       my ($p,$fh);
       if ($res eq 'application/rtf') {
           $p = HTML::TokeParser->new( \$html );
       } elsif ($res eq 'text/html') {
           open($fh, "<:utf8", $fullpath);
           $p = HTML::TokeParser->new( $fh );
       }
       my ($current_tag,$line,@text,$header,$css,$js,$have_header,$delayed);
       while (my $token = $p->get_token) {
           if (ref($token) eq 'ARRAY') {
               if ($token->[0] eq 'S') {
                   if ($delayed ne '') {
                       $line.= $delayed;
                       $delayed = '';
                   }
                   $current_tag = $token->[1];
                   next if ($token->[1] eq 'html' || $token->[1] eq 'head' || $token->[1] eq 'body' || $token->[1] eq 'meta' || $token->[1] eq 'title');
                   if ($token->[1] eq 'p') {
                       $line =~ s/^[\s\240]*(.*?)[\s\240]*$/$1/;
                       if (!$have_header) {
                           $header = $line;
                           if ($header ne '') {
                               $header =~ s/\s*[\n\r\f]+/\n/gs;
                           }
                           $have_header = 1;
                       } else {
                           push(@text,$line);
                       }
                       $line = '';
                   } elsif ($current_tag eq 'style') {
                       $css .= $token->[4];
                   } elsif ($current_tag eq 'script') {
                       $js .= $token->[4];
                   } else {
                       my $contents = $token->[4];
                       if ($subdir ne '') {
                           if (($token->[1] eq 'img') && ($token->[2]->{'src'} ne '')) {
                               $contents =~ s/(src=\s*["']?)/$1..\//i;
                           }
                       }
                       if (($line eq '') && ($current_tag eq 'font')) {
                           $delayed = &HTML::Entities::encode($contents,'<>&"');
                       } else {
                           $line .= &HTML::Entities::encode($contents,'<>&"');
                       }
                   }
               } elsif ($token->[0] eq 'T') {
                   if ($current_tag ne 'html' && $current_tag ne 'head' && $current_tag ne 'body' && $current_tag ne 'meta' && $current_tag ne 'title') {
                       if ($current_tag eq 'style') { 
                          $css .=  $token->[1];
                       } elsif ($current_tag eq 'script') {
                          $js .=  $token->[1];
                       } else {
                           if ($delayed ne '') {
                               my ($id,$rest) = ($token->[1] =~ /^(\s*\(*[A-Za-z0-9]+\)*\.*\s+)(.+)$/s);
                               if ($id ne '') {
                                   $line .= $id.$delayed.$rest;
                               } else {
                                   $line .= $token->[1].$delayed;
                               }
                               $delayed = '';
                           } else {
                               $line .= $token->[1];
                           }
                       }
                   }
               } elsif ($token->[0] eq 'E') {
                   next if ($token->[1] eq 'html' || $token->[1] eq 'head' || $token->[1] eq 'body' || $token->[1] eq 'meta' || $token->[1] eq 'title' || $token->[1] eq 'p');
                   if ($token->[1] eq 'style') {
                       $css .= $token->[2];
                   } elsif ($token->[1] eq 'script') {
                       $js .= $token->[2];
                   } else {
                       $line .= &HTML::Entities::encode($token->[2],'<>&"');
                   }
                   $current_tag = '';
               }
           }
       }
       if ($line ne '') {
           if ($line ne '') {
               $line =~ s/\s*[\n\r\f]+/\n/gs;
           }
           $line =~ s/^[\s\240]*(.*?)[\s\240]*$/$1/;
           push(@text,$line);
       }
       if ($res eq 'text/html') {
           close($fh);
       }
       return (\@text,$header,$css,$js);
   }
   
   sub build_image_url {
       my ($urlpath,$item) = @_;
       $item =~ s/(<img[^>]+src=["']?\s*)(\.?\.?\/?)/$1$urlpath/gsi;
       return $item; 
   }
   
   sub print_header {
       my ($uname,$udom,$javascript,$loadentries,$title) = @_;
       my $output = &Apache::loncommon::start_page($title,$javascript,
                                                {'add_entries' => $loadentries});
       if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {
           $output .= '<h3><span class="LC_error">'.&mt('Co-Author').': '.$uname.
                      &mt(' at ').$udom.'</span></h3>';
       }
       return $output;
   }
   
   sub topic_bar {
       my ($imgnum,$title) = @_;
       my $output = '
   <div class="LC_topic_bar">
       <img alt="'.&mt('Step [_1]',$imgnum).
                 ' "src="/res/adm/pages/bl_step'.$imgnum.'.gif" />&nbsp;'.$title.'
   </div>
   ';
       return $output;
   }
   
 # ---------------------------------------------------------------- Main Handler  # ---------------------------------------------------------------- Main Handler
 sub handler {  sub handler {
Line 1773  sub handler { Line 1788  sub handler {
     my $page_name = '';      my $page_name = '';
     my $current_page = '';      my $current_page = '';
     my $qcount = '';      my $qcount = '';
 #      my $title = 'Upload testbank questions to Construction Space';
 # phase two: re-attach user  
 #  
     if ($env{'form.uploaduname'}) {      if ($env{'form.uploaduname'}) {
         $env{'form.filename'}='/priv/'.$env{'form.uploaduname'}.'/'.          $env{'form.filename'}='/priv/'.$env{'form.uploaduname'}.'/'.
             $env{'form.filename'};              $env{'form.filename'};
Line 1784  sub handler { Line 1798  sub handler {
         &Apache::loncacc::constructaccess($env{'form.filename'},          &Apache::loncacc::constructaccess($env{'form.filename'},
                                           $r->dir_config('lonDefDomain'));                                            $r->dir_config('lonDefDomain'));
     unless (($uname) && ($udom)) {      unless (($uname) && ($udom)) {
         $r->log_reason($uname.' at '.$udom.          $r->log_reason($uname.':'.$udom.' trying to convert testbank file '.
                        ' trying to publish file '.$env{'form.filename'}.                         $env{'form.filename'}.' - not authorized',$r->filename);
                        ' - not authorized',  
                        $r->filename);  
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
                                                                                
     my $fn;      my ($fn,$filename);
     my $badfile = 0;  
     if ($env{'form.filename'}) {      if ($env{'form.filename'}) {
         $fn=$env{'form.filename'};          $fn=$env{'form.filename'};
         $fn=~s/^http\:\/\/[^\/]+\///;          $fn=~s/^http\:\/\/[^\/]+\///;
Line 1804  sub handler { Line 1815  sub handler {
                        ' unspecified filename for upload', $r->filename);                         ' unspecified filename for upload', $r->filename);
         return HTTP_NOT_FOUND;          return HTTP_NOT_FOUND;
     }      }
     my $pathname = &File::Basename::dirname($fn);  
     my $fullpath = '/priv/'.$uname.$pathname;  
     unless ($pathname eq '/') {  
         $fullpath .= '/';  
     }  
   
     my $dirpath = '/home/'.$uname.'/public_html';  
   
     my @text = ();  
     if ($env{'form.phase'} eq 'three') {      
         if (-e "$dirpath$fn") {  
             open(TESTBANK,"<$dirpath$fn");  
             @text = <TESTBANK>;  
             close(TESTBANK);  
         } else {  
             $badfile = 1;    
         }  
     }  
           
 # ----------------------------------------------------------- Start page output  # ----------------------------------------------------------- Start page output
     &Apache::loncommon::content_type($r,'text/html');      &Apache::loncommon::content_type($r,'text/html');
     $r->send_http_header;      $r->send_http_header;
   
     my %loadentries;      my ($filename,$pathname) = &File::Basename::fileparse($fn);
       my $webpath = '/priv/'.$uname.$pathname;
       my $urlpath = '/~'.$uname.$pathname;
       my $dirpath = '/home/'.$uname.'/public_html'.$pathname;
       my ($res,$subdir,$badfile,$textref,$header,$css,$js,%loadentries);
   
     if ($env{'form.phase'} eq 'three') {      if ($env{'form.phase'} eq 'three') {
         $current_page = &display_control();          $current_page = &display_control();
         my @PAGES = ('Welcome','Blocks','Format','Target','Confirmation');          my @pages = ('Welcome','Blocks','Format','Target','Confirmation');
         $page_name = $PAGES[$current_page];          $page_name = $pages[$current_page];
           if ($env{'form.newdir'} ne '') {
         if ($page_name eq 'Blocks') {              if ($env{'form.newdir'} =~ /^\Q$dirpath\E(.+)$/) {
     $loadentries{'onload'} = "setElements()";                  $subdir = $1;
               }
           }
           ($res,$badfile,$textref,$header,$css,$js) = 
               &parse_datafile($r,$uname,$filename,$pathname,$dirpath,$urlpath,
                               $page_name,$subdir);
           if ($page_name eq 'Welcome') {
                &jscript_zero($webpath,\$javascript);
           } elsif ($page_name eq 'Blocks') {
               if ($env{'form.go'} eq "PreviousPage") {
           $loadentries{'onload'} = "setElements()";
               }
             &jscript_one(\$javascript);              &jscript_one(\$javascript);
         } elsif ($page_name eq 'Format') {           } elsif ($page_name eq 'Format') {
             $qcount = question_count($env{'form.qnumformat'},\@text);              if ($env{'form.go'} eq "PreviousPage") {
                   $loadentries{'onload'} = "setElements()";
               }
               $qcount = question_count($env{'form.qnumformat'},$textref);
      &jscript_two(\$javascript,$qcount);       &jscript_two(\$javascript,$qcount);
          } elsif ($page_name eq 'Target') {          } elsif ($page_name eq 'Target') {
              if ($env{'form.go'} eq "PreviousPage") {               if ($env{'form.go'} eq "PreviousPage") {
                  $loadentries{'onload'} = "setElements()";                   $loadentries{'onload'} = "setElements()";
       }        }
      &jscript_three($fullpath,\$javascript);       &jscript_three($webpath,\$javascript);
         } elsif ($page_name eq 'Confirmation') {          } elsif ($page_name eq 'Confirmation') {
     &jscript_four(\$javascript,$fullpath);       &jscript_four(\$javascript,$webpath);
           }
           $javascript = "<script type=\"text/javascript\">\n//<!--\n".
                 $javascript."\n// --></script>\n";
           if ($res eq 'application/rtf' || $res eq 'text/html') {
               if ($page_name eq 'Target') {
                   $javascript .= $js.$css;
               }
         }          }
     }      }
   
     $javascript = "<script type=\"text/javascript\">\n//<!--\n".      $r->print(&print_header($uname,$udom,$javascript,\%loadentries,$title));
  $javascript."\n// --></script>\n";  
   
     $r->print(&Apache::loncommon::start_page('Upload testbank questions to Construction Space',  
      $javascript,  
      {'add_entries' => \%loadentries}));  
   
     if (($uname ne $env{'user.name'}) || ($udom ne $env{'user.domain'})) {  
         $r->print('<h3><font color=red>'.&mt('Co-Author').': '.$uname.  
                   &mt(' at ').$udom.'</font></h3>');  
     }  
   
     if ($env{'form.phase'} eq 'three') {      if ($env{'form.phase'} eq 'three') {
           if ($env{'form.action'} eq 'upload_embedded') {
               $r->print(&Apache::lonupload::phasethree($r,$fn,$uname,$udom,'testbank'));
           }
         if ($badfile) {          if ($badfile) {
             &file_error($r,$uname,$fn,$current_page);              &file_error($r,$uname,$fn,$current_page);
         } else {                  } else {        
             &display_zero ($r,$uname,$fn,$current_page,$fullpath) if $page_name eq 'Welcome';              &display_zero ($r,$uname,$fn,$current_page,$webpath) if $page_name eq 'Welcome';
             &display_one ($r,$uname,$fn,$current_page,\@text) if $page_name eq 'Blocks';              &display_one ($r,$uname,$fn,$current_page,$textref,$header) if $page_name eq 'Blocks';
             &display_two ($r,$uname,$fn,$current_page,\@text,$qcount) if $page_name eq 'Format';              &display_two ($r,$uname,$fn,$current_page,$textref,$header,$qcount) if $page_name eq 'Format';
             &display_three ($r,$uname,$fn,$current_page,\@text,$qcount) if $page_name eq 'Target';              &display_three ($r,$uname,$fn,$current_page,$textref,$res,$header,$urlpath,$qcount) if $page_name eq 'Target';
             &final_display ($r,$uname,$fn,$current_page,\@text) if $page_name eq 'Confirmation';              &final_display ($r,$uname,$fn,$current_page,$textref,$res,$header,$css,$js,$webpath,$dirpath,$subdir) if $page_name eq 'Confirmation';
         }          }
     } elsif ($env{'form.phase'} eq 'two') {      } elsif ($env{'form.phase'} eq 'two') {
         my $flag = &Apache::lonupload::phasetwo($r,$fn,$uname,$udom,'testbank');          my ($result,$flag) = &Apache::lonupload::phasetwo($r,$fn,$uname,$udom,'testbank');
           $r->print($result);
         if ($flag eq 'ok') {          if ($flag eq 'ok') {
             my $current_page = 0;              my $current_page = 0;
             &display_zero($r,$uname,$fn,$current_page,$fullpath);              my $js;
               &jscript_zero($webpath,\$js);
               $js = '<script type="text/javascript">'."\n$js\n".'</script>';
               $r->print($js);
               &display_zero($r,$uname,$fn,$current_page,$webpath);
           } elsif ($flag eq 'embedded') {
               $r->print($js.'<form name="testbankForm" method="post" action="/adm/testbank">'.
                         &page_footer('',$uname,$fn).'</form>');
         }          }
     } else {      } else {
         &Apache::lonupload::phaseone($r,$fn,$uname,$udom,'testbank');          &Apache::lonupload::phaseone($r,$fn,$uname,$udom,'testbank');
Line 1883  sub handler { Line 1903  sub handler {
     $r->print(&Apache::loncommon::end_page());      $r->print(&Apache::loncommon::end_page());
     return OK;      return OK;
 }  }
   
 1;  1;
 __END__  __END__
   

Removed from v.1.14  
changed lines
  Added in v.1.15


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>