]> lifelog.hopto.org Git - LifeLog.git/commitdiff
Further MarkdownPlugin development, it is becoming serious.
authorWill Budic <redacted>
Sun, 4 Jun 2023 01:56:31 +0000 (11:56 +1000)
committerWill Budic <redacted>
Sun, 4 Jun 2023 01:56:31 +0000 (11:56 +1000)
htdocs/cgi-bin/docs/LogTagsHelp.md
htdocs/cgi-bin/docs/PerlCNF/Specifications_For_CNF_ReadMe.md
htdocs/cgi-bin/index.cgi
htdocs/cgi-bin/index.cnf
htdocs/cgi-bin/system/modules/CNFParser.pm
htdocs/cgi-bin/system/modules/MarkdownPlugin.pm

index 4e53c0fe166ac7a585be4e1932c8fc8a392cf3c5..2f315471213a8d347cd92958cb4c046cd48b424c 100644 (file)
@@ -1,23 +1,23 @@
 # LifeLog Post Tags
 
-```
+```CNF
 <<B<{Text To Bold}>>
 <<I<{Text To Italic}>>
 <<TITLE<{Title Text}>>
-<<LIST<{List of items delimited by new line to terminate item or with '~' otherwise.}>
+<<LIST<{List of items delimited by new line to terminate item or with '~' otherwise.}>>
 <<IMG<{url to image}>>
 <<FRM<{file name}_frm.png}>>
 ```
 
-* frm.png images file pairs are located in the ./images folder of the cgi-bin directory. These are manually resized by the user. Next to the original. Otherwise considered as stand alone icons.
+* frm.png images file pairs are located in the ./images folder of the cgi-bin directory. These are manually resized by the user. Next to the original. Otherwise, considered as standalone icons.
 * _frm.png Image is resized to -> width="210" height="120"
 
 Examples:
-```
 
+```sh
   ../cgi-bin/images/
                        my_cat_simon_frm.png
-   my_cat_simon.jpg
+      my_cat_simon.jpg
 
   For log entry, place:
   &nbsp;<<FRM<my_cat_simon_frm.png> <<TITLE<Simon The Cat>>
@@ -29,7 +29,7 @@ Examples:
 
 ```
 
-* YuoTube embed script is automatically parsed.
+* YouTube embed script is automatically parsed.
 
 Example:
 
index b5f5a8d1581e1fc2f59134a7c3f4fbcd858713bc..3af1595c59cac1b3d69bc590da97901d47137a56 100644 (file)
@@ -41,7 +41,7 @@ Quick Jump: [CNF Tag Formats](#cnf-tag-formats)  |  [CNF Collections Formatting]
 11. Constants are usually scripted at the beginning of the file, or parsed first in a separate file.
 12. The instruction processor can use them if signifier $ surrounds the constant name. Therefore, replacing it with the constants value if further found in the file.
 
-    ```HTML
+    ```CNF
      <<<CONST $APP_PATH=~/MyApplication>>>
      <<app_path<$APP_PATH$/module/main>>>
     ```
@@ -77,7 +77,7 @@ Quick Jump: [CNF Tag Formats](#cnf-tag-formats)  |  [CNF Collections Formatting]
 26. Anon value is in best practice and in general synchronized, from script to a database configuration store. It is up to the implementation.
 27. Anon value is global to the application and its value can be modified.
 
-    ```HTML
+    ```CNF
             <<USE_SWITCH<true>>>
             <<DIALOG_TITLE_EN<MyApplication Title>>>
     ```
@@ -86,7 +86,7 @@ Quick Jump: [CNF Tag Formats](#cnf-tag-formats)  |  [CNF Collections Formatting]
     2. When querying for an anon value, replacement parameter array can be passed.
     3. Numbering is from **\$\$\$1\$\$\$**..**$$$(n...)\$\$\$** to be part of its value. Strategically placed.
 
-    ```HTML
+    ```CNF
         <<GET_SUB_URL<https://www.$$$1$$$.acme.com/$$$2$$$>>>
     ```
 
@@ -100,14 +100,14 @@ Quick Jump: [CNF Tag Formats](#cnf-tag-formats)  |  [CNF Collections Formatting]
 
 28. Listing is an reappearing same name tag postfixed with an **\$\$**.
 
-    ```HTML Example 1:
+    ```CNF Example 1:
                 <<INS$$>ls -la>
                 <<INS$$>uname -a>
     ```
 
 29. Listing is usually a named list of instructions, items grouped and available as individual entries of the listing value.
 
-    ```HTML Example 2:
+    ```CNF Example 2:
                 <<Animals$$>Cat>
                 <<Animals$$>Dog>
                 <<Animals$$>Eagle>
@@ -119,7 +119,7 @@ Quick Jump: [CNF Tag Formats](#cnf-tag-formats)  |  [CNF Collections Formatting]
     3. It is not recommended to use reserve anons as their value settings, that is; can be modified in scripts for their value.
     4. Reserve anon if present is usually a placeholder, lookup setting, that in contrast if not found there, might rise exceptions from the application using CNF.
 
-    ```HTML Example 2:
+    ```CNF Example 2:
                 Notice to Admin, following please don't modify in any way! 
                 Start --> { 
                 <<^RELEASE>2.3>>
@@ -134,18 +134,18 @@ Quick Jump: [Introduction](#introduction)  |  [CNF Collections Formatting](#cnf-
 
 ### Property Value Tag
 
-   ```HTML
+   ```CNF
         <<{name}<{value}>>>
    ```
 
 ### Instruction Value Tag
 
-   ```HTML
+   ```CNF
         <<<{INSTRUCTION}
         {value\n...valuen\n}>>>
    ```
 
-   ```HTML
+   ```CNF
         <<{name}<{INSTRUCTION}
         {value\n...valuen\n}>>>
    ```
@@ -160,7 +160,7 @@ Quick Jump: [Introduction](#introduction)  |  [CNF Collections Formatting](#cnf-
 
 **Examples:**
 
-```HTML
+```CNF
         <<$HELP<CONST
             Sorry help is currently.
             Not available.
@@ -309,7 +309,7 @@ CNF supports basic SQL Database structure statement generation. This is done via
 
 1. TABLE
 
-    ```HTML
+    ```CNF
         <<MyAliasTable<TABLE
                     ID INT PRIMARY KEY NOT NULL,
                     ALIAS VCHAR(16) UNIQUE CONSTRAINT,
@@ -320,14 +320,14 @@ CNF supports basic SQL Database structure statement generation. This is done via
 
 2. INDEX
 
-    ```HTML
+    ```CNF
         <<MyAliasTable<INDEX<idx_alias on MyAliasTable (ALIAS);>>>
     ```
 
 3. SQL
      1. SQL statements are actual full SQL placed in the tag body value.
 
-    ```HTML
+    ```CNF
         <<VW_ALIASES>SQL
             CREATE VIEW VW_ALIASES AS SELECT ID,ALIAS ORDER BY ALIAS;
         >>>
@@ -340,7 +340,7 @@ CNF supports basic SQL Database structure statement generation. This is done via
    3. Migration is not run on newly created databases. These create the expected latest data structure.
    4. SQL Statements a separated by ';' terminator. To be executed one by one.
 
-    ```HTML
+    ```CNF
         <<1.6<MIGRATE
                 ALTER TABLE LOG ADD STICKY BOOL DEFAULT 0;
         >>
@@ -366,7 +366,7 @@ CNF supports basic SQL Database structure statement generation. This is done via
        1. This behavior can be controlled by disabling something like an auto file storage update. i.e. during application upgrades. To prevent user set settings to reset to factory defaults.
        2. The result would then be that database already stored data remains, and only new ones are added. This exercise is out of scope of this specification.
 
-    ```HTML
+    ```CNF
         <<MyAliasTable<DATA
         01`admin`admin@inc.com`Super User~
         02`chef`chef@inc.com`Bruno Allinoise~
@@ -380,7 +380,7 @@ CNF supports basic SQL Database structure statement generation. This is done via
    3. File is to be sequentially buffer read and processed instead as a whole in one go.
    4. The same principles apply in the file as to the DATA instruction CNF tag format, that is expected to be contained in it.
 
-    ```HTML
+    ```CNF
         <<MyItemsTbl<FILE data_my_app.cnf>
     ```
 
@@ -398,7 +398,7 @@ CNF supports basic SQL Database structure statement generation. This is done via
     3. Requirements are for plugins to work to have the DO_ENABLED=>1 config attribute set.
         1. Plugins currently also will require be last specified in the file, to have access to previous anons that are instructed.
 
-    ```HTML
+    ```CNF
        /**
         * Plugin instructions are the last one setup and processed,
         * by placing the actual result into the plugins tag name.
@@ -444,7 +444,7 @@ CNF supports basic SQL Database structure statement generation. This is done via
             2. This is currently a TREE instruction only inbuilt option in PerlCNF, for the CNFNodes individuals scripts order of processing.
    4. Tree Format Example:
 
-        ```HTML
+        ```CNF
         <<APP<My Nice Application by ACME Wolf PTY>>
 
         <<doc<TREE>
@@ -473,7 +473,7 @@ Quick Jump: [Introduction](#introduction) | [CNF Collections Formatting](#cnf-co
    3. It is recommended to comment out this feature, if never is to be used or found not safe to have such thing enabled.
    4. This if named are assigned as anons, with the last processed value as the return. Making them evaluated and processed ever only once.
 
-```perl
+```CNF
 <<<DO
 print "Hello form CNF, you have ".(scalar %anons) ." anons so far.\n"
 >>>
@@ -517,7 +517,7 @@ print "Welcome to ", $cnf->constant('$APP_NAME'), " version ", $cnf->constant('$
 
 **~//perl_dev/WB_CNF/db/configuration.cnf** file contents:
 
-```HTML
+```CNF
 
 # List command anon with the name of 'list'.
 <<list<ls -lh dev|sort>>>
index 7f953e8816ef759bff522125db1c6b547e54529c..ca30772419ff2128c451ac4598006ee25e0732ee 100755 (executable)
@@ -28,8 +28,7 @@ BEGIN {
   set_message(\&handle_errors);
 }
 
-#debug -> 
-use lib "/home/will/dev/LifeLog/htdocs/cgi-bin/system/modules";
+
 use lib "system/modules";
 require CNFParser;
 require CNFNode;
@@ -39,19 +38,19 @@ our $script_path = $0;
 $script_path =~ s/\w+.cgi$//;
 
 
-exit main();
+exit &HTMLPageBuilderFromCNF;
 
-sub main {    
+sub HTMLPageBuilderFromCNF {    
     my $html = obtainDirListingHTML('docs');
-    my $cnf  = CNFParser -> new(
+    my $cnf  = CNFParser -> new (
                             $script_path."index.cnf",{
                              DO_ENABLED => 1, HAS_EXTENSIONS=>1,
                              ANONS_ARE_PUBLIC => 1,
-                                                   PAGE_HEAD    => "<h2>Index Page of Docs</h2>", 
+                                                   PAGE_HEAD    => "<h2>Index Page of Docs Directory</h2>", 
                                                    PAGE_CONTENT => $html, 
                                                    PAGE_FOOT    => "<!--Not Defined-->"
                             }
-                        );
+                );
     my $ptr = $cnf->data();
     $ptr = $ptr->{'PAGE'};   
     say $$ptr if $ptr;    
@@ -59,20 +58,25 @@ sub main {
 }
 
 sub obtainDirListingHTML {
-    my ($dir, $ret) = (shift,"");    
-    $ret .="<b>$dir &#8594;</b><ul>\n";
-    $ret .= listFiles($dir,$script_path,"");    
-    opendir (my $handle, $script_path.$dir) or die "Couldn't open directory, $!";
-    while (my $node = readdir $handle) {
-        my $file_full_path = "$script_path$dir/$node";
-        if($node !~ /^\./ && -d $file_full_path){
-           $ret .= obtainDirListingHTML($dir.'/'.$node);
+    my ($dir, $ret) = (shift,"");
+    my $html = listFiles($dir,$script_path,"");
+    if($html){
+       $ret .="<ul><b>$dir &#8594;</b>\n"; 
+       $ret .= $html;
+        opendir (my $handle, $script_path.$dir) or die "Couldn't open directory, $!";
+        while (my $node = readdir $handle) {
+            my $file_full_path = "$script_path$dir/$node";
+            if($node !~ /^\./ && -d $file_full_path){
+               $html = obtainDirListingHTML($dir.'/'.$node);
+               $ret .= $html if $html
+            }
         }
+        closedir $handle;
+       $ret .= "</ul>";
     }
-    closedir $handle;    
-    $ret .= "</ul>";
     return $ret;
 }
+
 sub listFiles ($){
     my ($dir, $script_path, $ret) = @_;
     my $path = $script_path.$dir;
@@ -83,7 +87,7 @@ sub listFiles ($){
             my $name = $1;
             if($file =~ /\.md$/){
                 my @title = getDocTitle($file);                
-                $ret .= qq(\t\t\t<li><a href="$dir/$title[0]">$title[1] - $name</a></li>\n);
+                $ret .= qq(\t\t\t<li><a href="$dir/$title[0]">$title[1]</a> &dash; $name</li>\n);
             }else{                
                 $ret .= qq(\t\t\t<li><a href="$dir/$name">$name</a></li>\n);
             }
index 7ddedc9ba28fc58124cb7d8aed5bb990223b3f76..c8f997e6353ee317820b9efda715fc67782fb074 100644 (file)
@@ -23,7 +23,7 @@
 [#[
 
     #container{
-        border: 2px solid black;
+        border: 2px solid #00000017;
         width: 78%;        
         margin: 0 auto;
         padding: 0px;        
         text-align: left;
     }
 
-    div .CNF {
+    div .cnf {
         border:1px solid lightgray;
         background: rgba(255,255,255,0.2);
         padding:10px; 
         font-family:monospace;
         text-align: left;
         padding-bottom: 10px;
+        margin-top:5px;
     }
 
-    .CNF h1{
+    .cnf h1{
         text-align: left;
         padding-left: 15px;
         margin-top: -20px;
         font-size: 15px;
     }
 
-    .CNF h1 span{
+    .cnf h1 span{
         background-color: white;
         border:1px solid lightgray;
         color:lightgray;
         text-decoration-style: wavy;
     }
 
+
+    #menu_page {
+        position: fixed;
+        float: left;
+        margin: 0;
+        margin-top:5px;
+        border: 2px solid #94cde7;
+        padding: 5px;
+        text-align: center;
+        background: #ccffff;
+        margin-left: 89%;
+    }
+
+    
+    .menu_head {
+        border: 2px solid #00000017;
+        font-size:small;        
+    }
+
 ]#]
 >STYLE>
 
@@ -255,12 +275,15 @@ function loadDocResult(content){
  OnLoad : onIndexBodyLoad()
 
 <div< 
-    id:menu
+    id:menu_page
  <#<
-    <a id="to_bottom" href="#bottom" title="Go to bottom of page."><span class="ui-icon ui-icon-arrowthick-1-s" style="float:none;"></span></a>
-            &nbsp;Page&nbsp;
-    <a id="to_top" href="#top" title="Go to top of page.">
-    <span class="ui-icon ui-icon-arrowthick-1-n" style="float:none;"></span></a><hr>
+    <span class="menu_head">
+        <a id="to_bottom" href="#bottom" title="Go to bottom of page."><span class="ui-icon ui-icon-arrowthick-1-s" style="float:none;"></span></a>
+                &nbsp; Page &nbsp;
+        <a id="to_top" href="#top" title="Go to top of page.">
+        <span class="ui-icon ui-icon-arrowthick-1-n" style="float:none;"></span></a>
+    </span>
+    <hr>
     <a class="ui-button ui-corner-all ui-widget" href="index.cgi">Index</a><hr> 
     <a class="ui-button ui-corner-all ui-widget" href="main.cgi">Life Log</a>
 >#>    
@@ -319,12 +342,10 @@ function loadDocResult(content){
 
 <<INFO_MD<ESCAPED>
 
-
 ### INFO
 \> This Page is the Documentation listing coming with the [LifeLog](https://github.com/wbudic/LifeLog) Application.
 \>
-\>\>[Open Source License](https://choosealicense.com/licenses/isc/)
-
+\>[Open Source License](https://choosealicense.com/licenses/isc/)
 
 >>
 
@@ -333,16 +354,23 @@ function loadDocResult(content){
     subroutine  : convert
     property    : INFO_MD
 >>
+<<1>>
 
-
+//Following for debug purposess and tests.
 
 ```CNF
+
+
 \<\<\<CONST
 $APP_NAME       = "Test Application"
 $APP_VERSION    = v.1.0
 \>\>\>
-\<\<$APP_DESCRIPTION<CONST>
+
+\<\<B\<{Text To Bold}\>\>
+\<\<I\<{Text To Italic}\>\>
+
+\<\<$APP_DESCRIPTION\<CONST\>
 This application presents just
 a nice multi-line template.
 \>\>
-```
+```
\ No newline at end of file
index 19821a2ed6b04883d140e7191644d1426c124801..3ded85445041677a60d1ca35fb45d6024bce6555 100644 (file)
@@ -89,9 +89,9 @@ sub new { my ($class, $path, $attrs, $del_keys, $self) = @_;
 sub import {     
     my $caller = caller;    
     {
-         *{"${caller}::configDumpENV"} = \&dumpENV;
-         *{"${caller}::anon"}          = \&anon;
-         *{"${caller}::SQL"}           = \&SQL;
+         *{"${caller}::configDumpENV"}  = \&dumpENV;
+         *{"${caller}::anon"}           = \&anon;
+         *{"${caller}::SQL"}            = \&SQL;         
     }
     return 1;    
 }
@@ -676,7 +676,7 @@ sub parse {  my ($self, $cnf, $content, $del_keys) = @_;
                 $e = $3 
                 }
                 $v= $5;
-                $v =~ s/>$//m if $4 eq '<' or $6; #value has been crammed into an instruction?
+                $v =~ s/>$//m if defined($4) && $4 eq '<' or $6; #value has been crammed into an instruction?
             
             }
             if(!$v && !$RESERVED_WORDS{$t}){
index bcdeb11405a8e00fdc4f19e39a910230332f99af..f1da337146921c054eec57592255783144779740 100644 (file)
@@ -6,8 +6,10 @@ use Syntax::Keyword::Try;
 use Exception::Class ('MarkdownPluginException');
 use feature qw(signatures);
 use Date::Manip;
+##no critic ControlStructures::ProhibitMutatingListFunctions
 
 our $TAB = ' 'x4;
+our $PARSER;
 
 sub new ($class, $fields={Language=>'English',DateFormat=>'US'}){      
 
@@ -28,6 +30,7 @@ sub new ($class, $fields={Language=>'English',DateFormat=>'US'}){
 sub convert ($self, $parser, $property) {    
 try{    
     my ($item, $script) =  $parser->anon($property);
+    $PARSER = $parser;
     die "Property not found [$property]!" if !$item;
 
     my $ref = ref($item); my $escaped = 0;
@@ -57,10 +60,50 @@ try{
         MarkdownPluginException->throw(error=>$e ,show_trace=>1);
 }}
 
+
+package HTMLListItem {    
+    sub new{
+        my $class = shift;
+        my ($type,$item,$spc) = @_;
+        my @array = ();
+        return bless{type=>$type,item=>$item,spc=>$spc,list=>\@array},$class;
+    }
+    sub parent($self) {
+        return  exists($self->{parent}) ? $self->{parent} : undef
+    }
+    sub add($self, $item){
+        push @{$self->{list}}, $item;        
+        $item ->{parent} = $self;
+    }    
+    sub hasItems($self){        
+        return @{$self->{list}}>0
+    }
+    sub toString($self){        
+        my $t = $self->{type};
+        my $isRootItem = $self -> {spc} == 0 ? 1 : 0;
+        my $hasItems   = $self->hasItems()   ? 1 : 0;
+        my $ret = "<li>".$self -> {item}."</li>\n";  
+        if($hasItems){
+           $ret = "<li>".$self -> {item}."<$t>\n";
+        }
+        foreach my $item(@{$self->{list}}){
+            if($item->hasItems()){
+                $ret .= $item->toString()."\n"
+            }else{
+                $ret .= '<li>'.$item->{item}."</li>\n"
+            }
+        }
+        if($hasItems){
+           $ret .= "</$t></li>\n";
+        }
+        return $ret
+    }
+}
+
 sub setCodeTag($tag, $class){
     if($tag){
-        $tag = $1;
-        if($tag eq 'html' or $tag eq 'CNF' or $tag eq 'code' or $tag eq 'perl'){
+        $tag = lc $tag;        
+        if($tag eq 'html' or $tag eq 'cnf' or $tag eq 'code' or $tag eq 'perl'){
             $class = $tag;
             $tag = 'div';
         }else{
@@ -79,8 +122,8 @@ sub setCodeTag($tag, $class){
 sub parse ($self, $script){
 try{
     my ($buffer, $para, $ol, $lnc); 
-    my @list; my $ltype=0;  my $nix=0;my $nplen=0;
-    my @titels;my $code = 0; my $tag;  my $pml_val = 0;  my ($bqte, $bqte_nested,$bqte_tag);
+    my @list; my $ltype=0;  my $nix=0; my $nplen=0; my $list_item;
+    my @titels;my $code = 0; my ($tag, $class);  my $pml_val = 0;  my ($bqte, $bqte_nested,$bqte_tag);
     $script =~ s/^\s*|\s*$//;
     foreach my $ln(split(/\n/,$script)){        
         $ln =~ s/\t/$TAB/gs;  
@@ -88,27 +131,29 @@ try{
         if($ln =~ /^```(\w*)\s(.*)```$/g){
             $tag = $1;
             $ln  = $2;
-            my @code_tag = setCodeTag($tag, "");            
+            my @code_tag = @{ setCodeTag($tag, "") }; 
             $buffer .= qq(<$code_tag[1] class='$code_tag[0]'>$ln</$code_tag[1]>\n);
             next
-        }elsif($ln =~ /^```(\w*)/){
-            my @code_tag = setCodeTag($tag, $1);
-            my $class = $code_tag[0];         
-            $tag = $code_tag[1];
+        }elsif($ln =~ /^\s*```(\w*)/){
+            if(!$tag){
+                my @code_tag = @{ setCodeTag($1, $1) };
+                $class = $code_tag[0];         
+                $tag = $code_tag[1] if !$tag;
+            }
             if($code){
                if($para){ 
                   $buffer .= "$para\n"
                }
-               $buffer .= "</$tag><br>"; $tag = $para = "";
-               $code = 0;
+               $buffer .= "</$tag><br>"; undef $para;
+               $code = 0; undef $tag;
             }else{
                $buffer .= "<$tag class='$class'>"; 
                if($class eq 'perl'){
                   $buffer .= qq(<h1><span>$class</span></h1>);
                   $code = 2;
                 }else{
-                  if($class eq 'CNF' or $class eq 'html'){
-                     $buffer .= qq(<h1><span>$class</span></h1>);
+                  if($class eq 'cnf' or $class eq 'html'){
+                     $buffer .= '<h1><span>'.uc $class.'</span></h1>'
                   }
                   $code = 1
                 }
@@ -120,25 +165,30 @@ try{
             $buffer .= qq(<$h>$title</$h><a name=").scalar(@titels)."\"></a>\n"
         }
         elsif(!$code &&  ($ln =~ /^(\s*)(\d+)\.\s(.*)/ || $ln =~ /^(\s*)([-+*])\s(.*)/)){
-            my @arr;
+            
             my $spc = length($1);
             my $val = $3 ? ${style($3)} : "";
-            $ltype  = $2 =~ /[-+*]/ ? 1:0;            
-            if($spc>$nplen){            
-               $nplen = $spc;               
-               $list[@list] = \@arr;
-               $nix++;
-            }elsif($spc<$nplen){
-               $nix--; 
+            my $new = HTMLListItem->new((/[-+*]/?'ul':'ol'), $val, $spc);
+
+            if(!$list_item){                
+                $list_item = $new;
+                $list[@list] = $list_item;
+                $nplen = $spc;
+                
+            }elsif($spc>$nplen){                
+                $list_item -> add($new);                
+                $list_item = $new;
+                $nplen = $spc;
+                
+            }else{                
+               while($list_item->{spc}>=$spc && $list_item -> parent()){
+                     $list_item = $list_item -> parent();
+               }                
+               if ( !$list_item ){$list_item = $new}else{
+                     $list_item -> add($new);
+                     $list_item = $new;                
+               }
             }
-            if($list[$nix-1]){
-                @arr = @{$list[$nix-1]};                        
-                $arr[@arr] = $ltype .'|'.$val;
-                $list[$nix-1] = \@arr;
-            }else{
-                $arr[@arr] = $ltype .'|'.$val;
-                $list[@list] = \@arr;
-            }            
         }elsif(!$code && $ln =~ /(^|\\G)[ ]{0,3}(>+) ?/){
             my $nested = length($2);
              $ln =~ s/^\s*\>+//;
@@ -150,7 +200,6 @@ try{
             }else{
                 $bqte_tag = "p";
             }
-
             if(!$bqte_nested){
                 $bqte_nested = $nested;
                 $bqte .="<blockquote><$bqte_tag>\n"
@@ -175,7 +224,7 @@ try{
         }
         elsif(!$code && $ln =~ /^\s*\*\*\*/){
             if($para){
-                $para .= qq(<hr>\n)
+                $para   .= qq(<hr>\n)
             }else{
                 $buffer .= qq(<hr>\n)
             }
@@ -187,36 +236,65 @@ try{
                     $v =~ s/</&#60;/g;
                     $v =~ s/>/&#62;/g;
                     $para .= "$v\n"; 
-                }elsif($code == 2){
-                    $v =~ s/([,;=\(\)\{\}\[\]]|->)/<span class=opr>$1<\/span>/g;
-                    $v =~ s/(['"].*['"])/<span class='str'>$1<\/span>/g;
-                    $v =~ s/class=opr/class='opr'/g;
-                    $v =~ s/(my|our|local|use|lib|require|new|while|for|foreach|while|if|else|elsif)/<span class='bra'>$1<\/span>/g;                    
-                    $v =~ s/(\$\w+)/<span class='inst'>$1<\/span>/g;                    
-                    $para .= "$v<br>\n";
-                }else{                   
+                }elsif($code == 2){   
+                    $para .= code2HTML($v)."<br>\n";
+                }else{           
+
+
+                    $v =~ m/  ^(<{2,3}) ([\$@%]*\w*)$ 
+                            | ^(>{2,3})$
+                            | (<<) ([\$@%]*\w*) <(\w+)>
+                     /gx;
+
+                    if($1&&$2){
+                        my $t = $1;  
+                        my $i = $2;  
+                        $t =~ s/</&#60;/g;                      
+                        $para .= qq(<span class='bra'>$t</span><span class='ins'>$i</span><br>);
+                        $pml_val = 1;
+                        next;
+                        
+                    }elsif($3){
+                        my $t = $3; 
+                        $t =~ s/>/&#62;/g;  
+                        $para .= "<span class='bra'>$t</span><br>\n";
+                        $pml_val = 0;
+                        next;
+                    }elsif($4&&$5&&6){
+                        my $t = $4;   
+                        my $v = $5;
+                        my $i = $6;
+                        $t =~ s/</&#60;/g;
+                        $para .= qq(<span class='bra'>$t</span><span class='var'>$v</span>
+                                    <span class='bra'>&#60;</span><span class='ins'>$i</span><span class='bra'>&#62;</span><br>);
+                        $pml_val = 1;
+                        next;
+
+                    }
                     
                     $v =~ m/ ^(<<)  ([@%]<) ([\$@%]?\w+) ([<>])
                             |^(<{2,3})                          
-                                ([\$@%\w]+)
-                                      (<[\w\ ]*>)* 
-                            |(>{2,3})$
+                                ([\$@%\w]+)\s*
+                                      <*([^>]+)
+                              (>{2,3})$
+                            
                            /gx;# and my @captured = @{^CAPTURE};
-
-                    if($5&&$6&&$7){
+                    
+                    if($5&&$6&&$7&&$8){
                         my $t = $5;
                         my $v = $6;
                         my $i = $7;
-                        $i =~ m/^<([\$@%\w]+?)>$/;
-                        $i = $1; $pml_val = 1;                       
-                        $para .= qq(<span class='bra'>&#60;&#60;</span><span class='var'>$v</span><span class='bra'>&#60;</span><span class='inst'>$i</span><span class='bra'>&#62;</span><br>);
+                        my $c = $8;
+                        $t =~ s/</&#60;/g;
+                        $c =~ s/>/&#62;/g;
+                        $pml_val = 1;                       
+                        $para .= qq(<span class='bra'>$t</span><span class='var'>$v</span><span class='bra'>&#60;</span><span class='inst'>$i</span><span class='bra'>$c</span><br>);
                        
                     }elsif($5&&$6){
-                         my $t = $5;
-                         my $i = $6;
-                         $t =~ s/</&#60;/g; $pml_val = 1;
-                        $para .= qq(<span class='bra'>$t</span><span class='inst'>$i</span><br>
-                                );
+                        my $t = $5;
+                        my $i = $6;
+                        $t =~ s/</&#60;/g; $pml_val = 1;
+                        $para .= qq(<span class='bra'>$t</span><span class='inst'>$i</span><br>);
 
                     }elsif($1 && $2 && $3){
                         
@@ -251,21 +329,14 @@ try{
                 $para .= ${style($1)}."\n"         
             }
         }else{            
+            
             if(@list){
-                if($para){
-                   my @arr;
-                   if($list[$nix-1]){
-                        @arr = @{$list[$nix-1]};
-                        $arr[@arr] = '2|'.$para;
-                        $list[$nix-1] = \@arr; 
-                   }else{
-                        $arr[@arr] = '2|'.$para;
-                        $list[@list] = \@arr;
-                   }
-                   $para=""
+                $buffer .= "<".$list[0]->{type}.">\n"; #This is the root list type, it can only be one per item entry.
+                foreach (@list){
+                $buffer .= $_->toString()."\n";    
                 }
-               $buffer .= createList(0,$ltype,\@list);
-               undef @list; $nplen = 0
+                $buffer .= "</".$list[0]->{type}.">\n";
+                undef @list
             }
             elsif($para){
                if($code){
@@ -282,7 +353,14 @@ try{
         while($bqte_nested-->0){$bqte .="\n</$bqte_tag></blockquote>\n"}
         $buffer .= $bqte;        
     }
-    $buffer .= createList(0,$ltype,\@list) if(@list);
+    
+    if(@list){
+        $buffer .= "<".$list[0]->{type}.">\n"; #This is the root list type, it can only be one per item entry.
+        foreach my$item(@list){
+        $buffer .= $item->toString()."\n";    
+        }
+        $buffer .= "</".$list[0]->{type}.">\n";
+    }
     $buffer .= qq(<p>$para</p>\n) if $para;    
 
 return [\$buffer,\@titels]
@@ -290,63 +368,69 @@ return [\$buffer,\@titels]
         MarkdownPluginException->throw(error=>$e ,show_trace=>1);
 }}
 
-my @LIST_ITEM_TYPE = ('ol','ul','blockquote');
-
-sub createList ($nested,$type,@list){
-    $nested++;
-    my ($bf,$tabs) =("", " "x$nested);
-    my $tag = $LIST_ITEM_TYPE[$type];
-
-    foreach my $arr(@list){
-            $bf .= qq($tabs<$tag>\n) if $nested>1;
-            foreach my $li(@$arr){
-                if(ref($li) eq 'ARRAY'){
-                    $bf =~ s/\s<\/($tag)>\s$//gs if $bf;
-                    my $r = $1;
-                    my @lst = \@$li;
-                    my $typ = get_list_type(@lst);
-                    $bf .= createList($nested,$typ,@lst);
-                    $bf .= qq($tabs</$tag>\n) if($r)                    
-                }else{
-                    $li =~ s/^(\d)\|//;
-                    if($1 == 2){
-                        $bf .= "$tabs<blockquote>$li</blockquote>\n"
-                    }else{
-                        $bf .= "$tabs<li>$li</li>\n"
-                    }
-                }
-            }
-            $bf .= qq($tabs</$tag>\n) if $nested>1;
-    }
-    return $bf
+sub code2HTML($v){
+        $v =~ s/([,;=\(\)\{\}\[\]]|->)/<span class='opr'>$1<\/span>/g;
+        $v =~ s/(['"].*['"])/<span class='str'>$1<\/span>/g;        
+        $v =~ s/(my|our|local|use|lib|require|new|while|for|foreach|while|if|else|elsif)/<span class='bra'>$1<\/span>/g;                    
+        $v =~ s/(\$\w+)/<span class='inst'>$1<\/span>/g;
+        return $v
 }
 
-sub get_list_type (@list){
-    foreach my $arr(@list){
-        foreach my $li(@$arr){
-            if($li =~ /^(\d)|/){
-                return $1;
-            }
-            last;
-        }
-    }
-    return 0;
-}
+
 
 sub style ($script){
     MarkdownPluginException->throw(error=>"Invalid argument passed as script!",show_trace=>1) if !$script;
     #Links <https://duckduckgo.com>
     $script =~ s/<(http[:\/\w.]*)>/<a href=\"$1\">$1<\/a>/g;
-        
+    
     my @result = map {
         s/\*\*(.*)\*\*/\<em\>$1<\/em\>/;
         s/\*(.*)\*/\<strong\>$1<\/strong\>/;
         s/__(.*)__/\<del\>$1<\/del\>/;
         s/~~(.*)~~/\<strike\>$1<\/strike\>/;        
         $_
-    } split(/\s/,$script); 
+    } split(/\s/,$script);
+    my $ret = join(' ',@result);
+
+    #Inline code
+    $ret =~ m/```(.*)```/g;
+    if($1){
+        my $v = $1; 
+           $v =~ m/ ^(<<)  ([@%]<) ([\$@%]?\w+) ([<>])
+                            |^(<{2,3})                          
+                                ([^>]+)
+                                    ( (<[\W\w ]*>) | (>{2,3})$ )
+                /gx;
+            if($5&&$6&&$7){
+                my $t = $5;
+                   $v = $6;
+                my $c = $7;
+                $t =~ s/</&#60;/g; 
+                $c =~ s/>/&#62;/g;
+                $v=~m/^(\w+)/;
+                my $w = $1; 
+                
+                if($PARSER->isReservedWord($w)){
+                    $v =~ s/^(\w+)/<span class='inst'>$w<\/span>/;
+
+                }
+                $v = qq(<span class='bra'>$t</span><span class='var'>$v</span></span><span class='bra'>$c</span>);                
+                
+            }elsif($5&&$6){
+                my $t = $5;
+                my $i = $6;
+                my $c = $7; $c = $8 if !$c;
+                $t =~ s/</&#60;/g; 
+                $c =~ s/>/&#62;/g if $c;
+                $v = qq(<span class='bra'>$t</span><span class='inst'>$i</span>$c);
+            }            
+            elsif($1 && $2 && $3){
+                $v = qq(<span class='bra'>&#60;&#60;$2<\/span><span class='var'>$3</span><span class='bra'>&#62;<\/span>);
+                
+            }
+        $ret =~ s/```(.*)```/\<span\>$v<\/span\>/;         
+    }
     
-    my $ret = join(' ',@result);    
     #Images
     $ret =~ s/!\[(.*)\]\((.*)\)/\<div class="div_img"><img class="md_img" src=\"$2\"\ alt=\"$1\"\/><\/div>/;
     #Links [Duck Duck Go](https://duckduckgo.com)