"Fossies" - the Fresh Open Source Software Archive

Member "highlight-3.57-x64/plugins/outhtml_codefold.lua" (12 May 2020, 9694 Bytes) of package /windows/www/highlight-3.57-x64.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Lua source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "outhtml_codefold.lua": 3.53_vs_3.54.

    1 
    2 Description="Adds code folding for C style languages, Pascal, Lua and Ruby and more to HTML output (not compatible with inline CSS or ordered list output)."
    3 
    4 Categories = {"format", "html", "usability" }
    5 
    6 function syntaxUpdate(desc)
    7 
    8   if (HL_OUTPUT ~= HL_FORMAT_HTML and HL_OUTPUT ~= HL_FORMAT_XHTML) then
    9     return
   10   end
   11 
   12   MIN_FOLD_LINE_NUM=1    -- change to control folding of small blocks
   13   ADD_BLOCK_RESIZE=false -- set to true if pre block should  keep its initial size after folding
   14   -- see themeUpdate below for CSS modifications
   15 
   16   function init()
   17     pID=0      -- a sequential counter to generate HTML IDs
   18     pCount=0   -- parenthesis counter to keep track of opening and closing pairs
   19     openPID={} -- save opening IDs as they are needed again for the close tag IDs
   20     currentLineNumber=0 -- remember the current line number
   21     notEmbedded=false   -- disable plugin for nested code snippets (like JS in HTML)
   22   end
   23 
   24   init()
   25 
   26   -- move DecorateLineBegin and DecorateLineEnd defined below HERE if anchors
   27   -- should be added even if syntax is not foldable
   28 
   29   function DecorateLineBegin(lineNumber)
   30 
   31     --TODO we need an initialization hook:
   32     if lineNumber==1 then
   33       init()
   34       notEmbedded=true
   35     end
   36     -- the line number does not increase for wrapped lines (--wrap, --wrap-simple)
   37     if (tonumber(currentLineNumber)==lineNumber) then
   38       return
   39     end
   40     currentLineNumber = string.format("%d", lineNumber)
   41     return '<span id="x_'..currentLineNumber..'" class="hl fld">'
   42   end
   43 
   44   function DecorateLineEnd(lineNumber)
   45     if (tonumber(currentLineNumber)==lineNumber) then
   46       return
   47     end
   48     return '</span>'
   49   end
   50 
   51 
   52   function Set (list)
   53     local set = {}
   54     for _, l in ipairs(list) do set[l] = true end
   55     return set
   56   end
   57 
   58   local foldable = Set { "C and C++", "C#", "Java", "Javascript", "ASCEND",
   59     "Ceylon", "Crack", "Not eXactly C", "Rust", "TTCN3", "Yang", "(G)AWK", "D",
   60     "Dart", "Nemerle", "Perl", "PHP", "Microsoft PowerShell", "Pike", "Scala",
   61     "Swift", "Kotlin", "Pascal", "Ruby", "Lua", "Go", "AutoHotKey", "TypeScript",
   62     "R", "Bash" }
   63 
   64   if not foldable[desc] then
   65     return
   66   end
   67 
   68   --default for curly braces
   69   blockBegin = Set { "{" }
   70   blockEnd = Set { "}" }
   71   blockStates = Set{ HL_OPERATOR }
   72 
   73   -- FIX conditional modifiers: add global desc var
   74   langDesc = desc
   75 
   76   --delimiters for other languages
   77   if desc=="Pascal" then
   78     blockBegin["begin"] = true
   79     --blockBegin["asm"] = true --issue with embedded syntax
   80     blockBegin["repeat"] = true
   81     blockBegin["case"] =  true
   82     blockBegin["record"] =  true
   83     blockEnd["end"] = true
   84     blockEnd["until"] = true
   85     blockStates[HL_KEYWORD] = true
   86     blockStates[HL_BLOCK_COMMENT] = true
   87     blockStates[HL_OPERATOR] = false
   88   elseif desc=="C#" then
   89     blockBegin["region"] = true
   90     blockEnd["endregion"] = true
   91     blockStates[HL_PREPROC] = true
   92   elseif desc=="Lua" then
   93     blockBegin["then"] = true
   94     blockBegin["do"] = true
   95     blockBegin["function"] = true
   96     blockEnd["elseif"] = true
   97     blockEnd["end"] = true
   98     blockStates[HL_KEYWORD] = true
   99   elseif desc=="Bash" then
  100     blockBegin["then"] = true
  101     blockBegin["do"] = true
  102     blockBegin["case"] = true
  103     blockEnd["fi"] = true
  104     blockEnd["else"] = true
  105     blockEnd["done"] = true
  106     blockEnd["esac"] = true
  107     blockStates[HL_KEYWORD] = true
  108   elseif desc=="Ruby" then
  109     blockBegin["do"] = true
  110     blockBegin["def"] = true
  111     blockBegin["class"] = true
  112     blockBegin["begin"] = true
  113     blockBegin["case"] = true
  114     blockBegin["while"] = true
  115     blockBegin["module"] = true
  116     blockBegin["if"] = true
  117     blockBegin["unless"] = true
  118     blockBegin["until"] = true
  119     blockEnd["end"] = true
  120     blockStates[HL_KEYWORD] = true
  121 
  122     -- fix  self.class == other.class && @ops == other.ops
  123     Identifiers=[[ [a-zA-Z_\.][\w\-]* ]]
  124     table.insert( Keywords,
  125                   { Id=3, List={".class"}
  126                   } )
  127   end
  128 
  129     HeaderInjection=[=[
  130   <script type="text/javascript">
  131   /* <![CDATA[ */
  132   var beginOfBlock = [];
  133   var endOfBlock = {};
  134   var foldedLines = {};
  135 
  136   function make_handler (elem) {
  137     return function (event) {
  138       hlToggleFold(elem)
  139     };
  140   }
  141   function hlAddEOB(openId, eob)  {
  142     if (eob==beginOfBlock[openId -1] || eob - beginOfBlock[openId -1]< ]=]..MIN_FOLD_LINE_NUM..[=[ ){
  143       delete beginOfBlock[openId -1];
  144     } else {
  145       endOfBlock[beginOfBlock[openId -1] ] = eob;
  146     }
  147   }
  148   function hlAddTitle(line, num, isFolding){
  149     elem.title="Click to "+(isFolding? "unfold ": "fold ") + num + " line"+(num>1?"s":"");
  150   }
  151   function hlAddBtn(openId)  {
  152     elem = document.getElementById('x_' + openId);
  153     elem.className = "hl fld hl arrow_unfold";
  154     elem.addEventListener("click", make_handler(elem));
  155     hlAddTitle(elem, (endOfBlock[openId]-openId-1), false);
  156   }
  157   function hlToggleFold(sender){
  158     elem =    document.getElementById(sender.id);
  159     var num = parseInt(sender.id.substr(2));
  160     var isFolding = elem.className.indexOf ('unfold')>0;
  161     foldedLines[num] = isFolding ;
  162     elem.className = "hl fld hl arrow_" + (isFolding ? "fold":"unfold");
  163     hlAddTitle(elem, (endOfBlock[num]-num-1), isFolding);
  164     for (var i=num+1; i<=endOfBlock[num]-1; i++){
  165       if (!foldedLines[i]) foldedLines[i] = 0 ;
  166       foldedLines[i] = foldedLines[i] + (isFolding ? 1:-1);
  167       elem = document.getElementById('x_'+i);
  168       if (     (isFolding || elem.style.display=='block')
  169             || (!isFolding && foldedLines[i]>=1 && elem.className.indexOf ('_fold') < 0)
  170             || (!isFolding && foldedLines[i]>=2 && elem.className.indexOf ('_fold') > 0)) {
  171           elem.style.display = 'none';
  172       } else {
  173           elem.style.display = 'block';
  174       }
  175       if (elem.nextSibling
  176         && elem.nextSibling.nodeType==3
  177         && !elem.nextSibling.data.match(/\S/) ) {
  178           elem.parentNode.removeChild(elem.nextSibling);
  179           if (elem.textContent.length==0) elem.textContent = " ";
  180         }
  181       }
  182     }
  183   /* ]]> */
  184   </script>
  185 ]=]
  186 
  187   ResizeSnippet=''
  188 
  189   if ADD_BLOCK_RESIZE==true then
  190       ResizeSnippet=[[
  191   var hlElements=document.getElementsByClassName('hl');
  192   if (hlElements.length>1){
  193     var pre = hlElements[1];
  194     if (pre instanceof HTMLPreElement) {
  195       pre.style.setProperty('min-height', pre.clientHeight+'px');
  196     }
  197   }
  198   ]]
  199   end
  200 
  201   -- assign some CSS via JS to keep output sane for browsers with JS disabled
  202   FooterInjection=[=[
  203 
  204   <script type="text/javascript">
  205   /* <![CDATA[ */
  206   beginOfBlock.forEach(function (item) {
  207     hlAddBtn(item);
  208   });
  209   ]=]..ResizeSnippet..[=[
  210   var hlFoldElements=document.getElementsByClassName('hl fld');
  211   for (var i=0; i<hlFoldElements.length; i++){
  212     hlFoldElements[i].style.setProperty('padding-left', '1.5em');
  213   }
  214   /* ]]> */
  215 </script>
  216   ]=]
  217 
  218 
  219 
  220   function getOpenParen(token)
  221     pID=pID+1
  222     pCount=pCount+1
  223     openPID[pCount] = pID
  224     return '<script>beginOfBlock.push('..currentLineNumber..');</script>'..token
  225   end
  226 
  227   function getCloseParen(token)
  228     oID=openPID[pCount]
  229     if oID then
  230       pCount=pCount-1
  231       return '<script>hlAddEOB('..oID..', '.. currentLineNumber..');</script>'..token
  232     end
  233   end
  234 
  235   function string.ends(String,End)
  236     return End=='' or string.sub(String,-string.len(End))==End
  237   end
  238 
  239   -- FIX conditional modifiers: add two params
  240   function Decorate(token, state, kwclass, trace)
  241     if (not blockStates[state] or notEmbedded==false) then
  242       return
  243     end
  244 
  245     --io.write("TRC "..trace.."  ")
  246 
  247     -- FIX conditional modifiers: add condition to avoid recognition of delimiters
  248     --     if the last state before is a statement
  249     if langDesc=="Ruby" and string.len(trace)>1
  250         and ((token=="if" or token=="unless" or token=="while" or token=="until")
  251             and (string.ends(trace, ";"..math.floor(HL_KEYWORD)..";")
  252                 or string.ends(trace, ";"..math.floor(HL_IDENTIFIER_BEGIN)..";")
  253                 or string.ends(trace, ";"..math.floor(HL_NUMBER)..";")
  254                 or string.ends(trace, ";"..math.floor(HL_STRING)..";")
  255                 or string.ends(trace, ";"..math.floor(HL_STANDARD)..";")
  256                 or string.ends(trace, ";"..math.floor(HL_OPERATOR)..";") ) )
  257       then
  258         return
  259     end
  260 
  261     if blockBegin[ string.lower(token) ] then
  262       return getOpenParen(token)
  263     end
  264 
  265     if blockEnd[ string.lower(token) ] then
  266       return getCloseParen(token)
  267     end
  268 
  269   end
  270 
  271 end
  272 
  273 function themeUpdate(desc)
  274   if (HL_OUTPUT == HL_FORMAT_HTML or HL_OUTPUT == HL_FORMAT_XHTML) then
  275 
  276     -- edit to use different folding symbols (i.e. arrows)
  277     FOLD_OPEN_SYMBOL='+'   -- possible: + > \\27a4 \\27a7 \\21db \\2261
  278     FOLD_CLOSE_SYMBOL='-'  -- possible: - > \\27a4 \\27a7 \\21db \\2212
  279 
  280     rotation=''
  281     if (FOLD_OPEN_SYMBOL==FOLD_CLOSE_SYMBOL) then rotation='transform:rotate(90deg);' end
  282 
  283     Injections[#Injections+1]=[[
  284 .hl.arrow_fold:before {
  285   content: ']]..FOLD_OPEN_SYMBOL..[[';
  286   color: ]]..Default.Colour..[[;
  287   position: absolute;
  288   left: 1em;
  289   ]]..rotation..[[
  290 }
  291 .hl.arrow_fold:after {
  292   content: '\2026';
  293   color: ]]..Default.Colour..[[;
  294   border-width:1px;border-style:dotted;border-color:]]..Default.Colour..[[;
  295   margin-left: 1em;
  296   padding:0px 2px 0px;
  297 }
  298 .hl.arrow_unfold:before {
  299   content: ']]..FOLD_CLOSE_SYMBOL..[[';
  300   color: ]]..Default.Colour..[[;
  301   position: absolute;
  302   left: 1em;
  303 }
  304 .hl.arrow_fold, .hl.arrow_unfold  {
  305   cursor: pointer;
  306   /*background-color: #eee;*/
  307   width: 100%;
  308   display: inline-block;
  309 }
  310 .hl.arrow_fold {
  311   border-width: 1px;
  312   border-bottom-style: groove;
  313   border-color: ]]..Default.Colour..[[;
  314 } ]]
  315   end
  316 end
  317 
  318 Plugins={
  319   { Type="lang", Chunk=syntaxUpdate },
  320   { Type="theme", Chunk=themeUpdate },
  321 }