// save as e.g. E:\env\htmlval\cache.js and include in batch target options user functions file
    /*********************
     * Set $cachefolder in onBeforeMainStart() to the folder to use to store data (it must end in a backslash)
     *********************/

    function onBeforeMainStart() {
     $cachefolder='C:\\htmlvalcache\\';
    }

    function onTargetCanAdd() {
     if !$otca_add return;

     $cachefile=$cachefolder+replaceRegEx($otca_target,'[^a-zA-Z0-9\.\-\_]','_');
    // ProgressMessage('$cachefile: '+$cachefile);
     $cfinfo=getFileInfo($cachefile,1);

     if $cfinfo.isSet() {
      $tinfo=getFileInfo($otca_target,1);

      if $tinfo.isSet() {
       $otca_add=false;

       if $tinfo.lastwrite_year>$cfinfo.lastwrite_year { $otca_add=true; }
       else { if $tinfo.lastwrite_year==$cfinfo.lastwrite_year {
       if $tinfo.lastwrite_month>$cfinfo.lastwrite_month { $otca_add=true; }
       else { if $tinfo.lastwrite_month==$cfinfo.lastwrite_month {
       if $tinfo.lastwrite_day>$cfinfo.lastwrite_day { $otca_add=true; }
       else { if $tinfo.lastwrite_day==$cfinfo.lastwrite_day {
       if $tinfo.lastwrite_hour>$cfinfo.lastwrite_hour { $otca_add=true; }
       else { if $tinfo.lastwrite_hour==$cfinfo.lastwrite_hour {
       if $tinfo.lastwrite_min>$cfinfo.lastwrite_min { $otca_add=true; }
       }}}}}}}}
      }
     }
    }

function onTargetProcessed() {
 $cachefile=$cachefolder+replaceRegEx(getValueString(5),'[^a-zA-Z0-9\.\-\_]','_');

 if getValueInt(1) || getValueInt(2) { // if has errors or warnings
  deleteFile($cachefile);
 }
 else {
//  writeFile($cachefile,'',2); // create an empty file
  writeFile($cachefile,getValueString(5),2); // for debugging
 }
}