add new TOC
authorHanoh Haim <[email protected]>
Wed, 20 Apr 2016 13:16:06 +0000 (16:16 +0300)
committerHanoh Haim <[email protected]>
Wed, 20 Apr 2016 13:16:06 +0000 (16:16 +0300)
12 files changed:
images/Thumbs.db
images/icons/selected_tab_bg.png [new file with mode: 0644]
images/icons/toggle.png [new file with mode: 0644]
trex_book.asciidoc
trex_rpc_server_spec-docinfo.html [new file with mode: 0644]
trex_rpc_server_spec.asciidoc
trex_stateless.asciidoc
trex_toc.asciidoc [new file with mode: 0644]
trex_vm_manual-docinfo.html [new file with mode: 0644]
trex_vm_manual.asciidoc
ws_main.py
wscript

index a7cb4a9..893347a 100755 (executable)
Binary files a/images/Thumbs.db and b/images/Thumbs.db differ
diff --git a/images/icons/selected_tab_bg.png b/images/icons/selected_tab_bg.png
new file mode 100644 (file)
index 0000000..16bb5d6
Binary files /dev/null and b/images/icons/selected_tab_bg.png differ
diff --git a/images/icons/toggle.png b/images/icons/toggle.png
new file mode 100644 (file)
index 0000000..84380cd
Binary files /dev/null and b/images/icons/toggle.png differ
index 2326f3e..f13c63a 100755 (executable)
@@ -10,6 +10,7 @@ TRex
 :toclevels: 4
 
 include::trex_ga.asciidoc[]
+include::trex_toc.asciidoc[]
 
 
 == Introduction
diff --git a/trex_rpc_server_spec-docinfo.html b/trex_rpc_server_spec-docinfo.html
new file mode 100644 (file)
index 0000000..6fb66a5
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+
+
+
+
index 7df6355..1663830 100755 (executable)
@@ -10,6 +10,7 @@ The TRex RPC Server
 :toclevels: 4
 
 include::trex_ga.asciidoc[]
+include::trex_toc.asciidoc[]
 
 
 == Change log
index 303de5c..4aad01e 100755 (executable)
@@ -22,6 +22,8 @@ ifdef::backend-xhtml11[]
 endif::backend-xhtml11[]
 
 include::trex_ga.asciidoc[]
+include::trex_toc.asciidoc[]
+
 
 == Audience 
 
diff --git a/trex_toc.asciidoc b/trex_toc.asciidoc
new file mode 100644 (file)
index 0000000..664370b
--- /dev/null
@@ -0,0 +1,221 @@
+
+ifdef::backend-xhtml11[]
+++++
+    <div id="toggle"><img src="images\icons\toggle.png" title="click to toggle table of contents"></div>
+
+    <div id="toc">
+        <div id="toctitle">
+            Table of Contents
+        </div>
+        
+        <div id="nav-tree">
+          
+        </div>
+    </div>
+
+
+    <!-- load the theme CSS file -->
+    <link href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" rel="stylesheet"/>
+    
+    <link href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" rel="stylesheet" />
+
+    <!-- include the jQuery library -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js">
+    </script>
+
+    <!-- include the jQuery UI library -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js">
+    </script>
+
+    <!-- include the minified jstree source -->
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js">
+    </script>
+    
+    <style type="text/css">
+    
+        #toc {
+          margin-bottom: 2.5em;
+        }
+        
+        #toctitle {
+          color: #527bbd;
+          font-size: 1.1em;
+          font-weight: bold;
+          margin-top: 1.0em;
+          margin-bottom: 0.1em;
+        }
+
+        @media screen {
+          body {
+            max-width: 50em; /* approximately 80 characters wide */
+            margin-left: 20em;
+          }
+        
+          #toc {
+            position: fixed;
+            top: 0;
+            left: 0;
+            bottom: 0;
+            width: 18em;
+            padding-bottom: 1.5em;
+            margin: 0;
+            overflow-x: auto;
+            overflow-y: hidden;
+            border-right: solid 2px #cfcfcf;
+            background-color: #FAFAFA;
+            white-space: nowrap;
+          }
+        
+          #toctitle {
+            font-size: 17px !important;
+            color: #4d4d4d !important;
+            margin-top: 0px;
+            height: 36px;
+            line-height: 36px;
+            background-color: #e4e2e2;
+            padding: 8px 0px 7px 45px;
+            white-space: nowrap;
+          }
+          
+          #toc .toclevel1 {
+            margin-top: 0.5em;
+          }
+        
+          #toc .toclevel2 {
+            margin-top: 0.25em;
+            display: list-item;
+            color: #aaaaaa;
+          }
+        
+        }
+
+
+      /* Custom for Nave Tree */
+      #nav-tree{
+        margin-left: 10px !important;
+      }
+      
+      #nav-tree ul > li {
+        color: #000 !important;
+      }
+      
+      .jstree-wholerow.jstree-wholerow-clicked {
+        background-image: url('images\icons\selected_tab_bg.png');
+        background-repeat: repeat-x;
+        color: #fff !important;
+        text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+      }
+
+      .jstree-anchor {
+        font-size: 12px !important;
+        color: #91A501 !important;
+      }
+
+      /* For side bar */
+      .ui-resizable-e{
+        width: 10px !important;
+      }
+
+      .jstree-clicked{
+        color: green !important;
+      }
+      
+      .jstree-default .jstree-themeicon{
+        display: none !important;
+      }
+
+      #toggle {
+        position: fixed;
+        top: 14px;
+        left: 10px;
+        z-index: 10;
+      }
+
+      #toggle img {
+        opacity:0.3;
+      }
+
+      #toggle img:hover {
+        opacity:0.9;
+      }
+
+    </style>
+
+
+
+<script>
+
+      $(document).ready(function(){
+
+        // Initialize NavTree
+        initializeNavTree();
+        // Drag TOC left and right
+        initResizable();
+        // Toggle TOC whe clicking on the menu icon
+        toggleTOC();
+
+        function initializeNavTree() {
+          $('#nav-tree').jstree({
+            'core' : {
+              "animation" :false,
+              "themes" : { "stripes" : false },
+              'data' : {
+                "url" : "./input_replace_me.json",  
+                "dataType" : "json" // needed only if you do not supply JSON headers
+              }
+            }
+            ,
+            "plugins" : [ "wholerow" ]
+          });
+
+          $('#nav-tree').on("changed.jstree", function (e, data) {
+            window.location.href = data.instance.get_selected(true)[0].original.link;
+          });
+        }
+        
+        function initResizable() {
+            var toc = $("#toc");
+            var bodyLeftMargin = $("body");
+            $("#toc").resizable({
+                resize: function(e, ui) {
+                    var tocWidth = $("#toc").outerWidth();
+                    bodyLeftMargin.css({"marginLeft":parseInt(tocWidth)+20+"px"}); 
+                },
+                handles: 'e'
+            });
+        }
+
+
+        function toggleTOC(){
+          var isOpen = true;
+          $( "#toggle" ).click(function() {
+            if ( isOpen ) {
+              // Close it
+              $("#toc").hide("slide", 500);
+              // Show the show/hide button
+              $("#toggle").css("right", "-40px");
+              // $("body").css("margin-left", "20px");
+              $("body").animate({
+                "margin-left": "50px"
+              }, 500);
+            } else {
+              // Open it
+              $("#toc").show("slide", 500);
+              // Show the show/hide button
+              $("#toggle").css("right", "15px");
+              // $("body").css("margin-left", $(toc).outerWidth()+20+"px");
+              $("body").animate({
+                "margin-left": $(toc).outerWidth()+20+"px"
+              }, 500);
+            }
+            isOpen = !isOpen;
+          });
+        }
+
+      }
+      )
+
+</script>
+++++
+endif::backend-xhtml11[]
+
diff --git a/trex_vm_manual-docinfo.html b/trex_vm_manual-docinfo.html
new file mode 100644 (file)
index 0000000..6fb66a5
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+
+
+
+
index 7e22d54..ec4c39c 100755 (executable)
@@ -8,6 +8,8 @@ TRex Virtual Machine setup and basic usage
 
 
 include::trex_ga.asciidoc[]
+include::trex_toc.asciidoc[]
+
 
 
 == Introduction
@@ -276,12 +278,14 @@ Once we have TRex up and running, we can enjoy the benefit of having live monito
 
 
 This can be easily done by following these steps:
-  0. Download the latest version of TrexViewer application and install it using http://trex-tgn.cisco.com/trex/client_gui/setup.exe[this link].
 
-  1. Start the application and fill in the following: + 
+1. Download the latest version of TrexViewer application and install it using http://trex-tgn.cisco.com/trex/client_gui/setup.exe[this link].
+
+
+2. Start the application and fill in the following: + 
     - Trex ip: `127.0.0.1:4500`
 
-  2. Click the play button.
+3. Click the play button.
 
 ifdef::backend-docbook[]
 image::images/trex_motinor_config.png[title="TRex viewer start screen",align="center",width=400,link="images/trex_motinor_config.png"]
@@ -291,9 +295,7 @@ ifdef::backend-xhtml11[]
 image::images/trex_motinor_config.png[title="TRex viewer start screen",align="center",width=900,link="images/trex_motinor_config.png"]
 endif::backend-xhtml11[]
 
-
-
-  3. **That's it!** +
+**That's it!** +
      Now the live data from TRex will be displayed on the screen.
 
 ifdef::backend-docbook[]
@@ -328,3 +330,8 @@ The VM runs TRex with single client and single server port. The traffic generate
 TRex identifies only the packets which were dedicately sent by one of those traffic ports and receives them in the other port. Hence, packets generated by client port will be received by the server port and vice versa.
 
 Ontop, network adapter #4 used to [underline]#listen# to all traffic generated by both of TRex's ports, therefore it is very useful in providing live data of the generated flows over the network.
+
+
+
+
+
index 849e68f..73b35c5 100644 (file)
@@ -12,11 +12,155 @@ APPNAME='wafdocs'
 import os, re, shutil
 import shlex
 import subprocess
+import json
+
 
 
 top = '.'
 out = 'build'
 
+from HTMLParser import HTMLParser
+
+class CTocNode:
+    def __init__ (self):
+        self.name="root"
+        self.level=1; # 1,2,3,4
+        self.parent=None
+        self.childs=[]; # link to CTocNode
+
+    def get_link (self):
+        name=self.name
+        l=name.split('.');
+        l=l[-1].lower()
+        s='';
+        for c in l:
+            if c.isalpha() or c.isspace():
+                s+=c
+
+        return  '#_'+'_'.join(s.lower().split());
+
+
+    def add_new_child (self,name,level):
+        n=CTocNode();
+        n.name=name;
+        n.level=level;
+        n.parent=self;
+        self.childs.append(n);
+        return n
+
+    def to_json_childs (self):
+        l=[]
+        for obj in self.childs:
+            l.append(obj.to_json());
+        return (l);
+
+    def to_open (self):
+        if self.level <3:
+            return True
+        else:
+            return False
+
+
+    def to_json (self):
+        d={"text" : self.name,
+           "link" : self.get_link(),
+           "state"       : {
+                "opened"    : self.to_open()
+                }
+          }
+        if len(self.childs)>0 :
+            d["children"]= self.to_json_childs()
+        return d
+
+
+
+class TocHTMLParser(HTMLParser):
+
+    def __init__ (self):
+        HTMLParser.__init__(self);
+        self.state=0;
+        self.root=CTocNode()
+        self.root.parent=self.root
+        self.level=2;
+        self.d={};
+        self.last_level=1
+        self.set_level(1,self.root)
+
+
+    def set_level (self,level,node):
+        assert(node!=None);
+        assert(isinstance(node,CTocNode)==True); 
+        self.d[str(level)]=node
+
+        # in case we change from high to low level remove the higher level 
+        if level<self.last_level:
+            for l in range(level+1,self.last_level+1):
+                self.d.pop(str(l),None)
+
+
+
+    def _get_level (self,level):
+        k=str(level)
+        if self.d.has_key(k):
+            n=self.d[k]
+            assert(n!=None);
+            return n
+        else:
+            return None
+
+    def get_level (self,level):
+        for l in range(level,0,-1):
+            n=self._get_level(l)
+            if n != None:
+                return n
+        assert(0);
+
+
+    def is_header (self,tag):
+        if len(tag)==2 and tag[0]=='h' and tag[1].isdigit() and (int(tag[1])>1):
+            return (True);
+
+    def handle_starttag(self, tag, attrs):
+        if self.is_header (tag):
+            self.state=True;
+            self.level=int(tag[1]);
+
+    def handle_endtag(self, tag):
+        if self.is_header (tag):
+            self.state=False;
+
+
+    def handle_data(self, data):
+        if self.state:
+           level=self.level
+
+           cnode=self.get_level(level-1)
+
+           n=cnode.add_new_child(data,level);
+           assert(n!=None);
+           self.set_level(level,n) 
+           self.last_level=level
+
+    def dump_as_json (self):
+        return json.dumps(self.root.to_json_childs(), sort_keys=False, indent=4)
+
+
+
+
+def create_toc_json (input_file,output_file):
+    f = open (input_file)
+    l=f.readlines()
+    f.close();
+    html_input = ''.join(l)
+    parser = TocHTMLParser()
+    parser.feed(html_input);
+    f = open (output_file,'w')
+    f.write(parser.dump_as_json());
+    f.close();
+
+
+
+
 re_xi = re.compile('''^(include|image)::([^.]*.(asciidoc|\\{PIC\\}))\[''', re.M)
 def ascii_doc_scan(self):
     p = self.inputs[0].parent
@@ -96,6 +240,47 @@ def convert_to_pdf(task):
     os.system('a2x --no-xmllint -v -f pdf  -d  article %s -D %s ' %(task.inputs[0].abspath(),out_dir ) )
     return (0)
 
+
+
+def toc_fixup_file (input_file,
+                    out_file, 
+                    json_file_name
+                    ):
+
+    file = open(input_file)
+    contents = file.read()
+    replaced_contents = contents.replace('input_replace_me.json', json_file_name)
+    file = open(out_file,'w')
+    file.write(replaced_contents)
+    file.close();
+
+
+
+def convert_to_html_toc_book(task):
+
+    input_file = task.inputs[0].abspath()
+
+    json_out_file = os.path.splitext(task.outputs[0].abspath())[0]+'.json' 
+    tmp = os.path.splitext(task.outputs[0].abspath())[0]+'.tmp' 
+    json_out_file_short = os.path.splitext(task.outputs[0].name)[0]+'.json' 
+    
+    cmd='{0} -a stylesheet={1} -a  icons=true -a docinfo -d book   -a max-width=55em  -o {2} {3}'.format(
+            task.env['ASCIIDOC'],
+            task.inputs[1].abspath(),
+            tmp,
+            task.inputs[0].abspath());
+
+    os.system( cmd )
+
+    create_toc_json(tmp,json_out_file)
+
+    toc_fixup_file(tmp,task.outputs[0].abspath(),json_out_file_short);
+
+    os.system('rm {0}'.format(tmp));
+
+
+
+
 def convert_to_pdf_book(task):
     input_file = task.outputs[0].abspath()
     out_dir = task.outputs[0].parent.get_bld().abspath()
@@ -209,6 +394,14 @@ def build_cp(bld,dir,root,callback):
 
 
 
+
+
+
+
+
+
+
+
 def build(bld):
     bld(rule=my_copy, target='symbols.lang')
 
@@ -252,13 +445,6 @@ def build(bld):
     bld(rule='${ASCIIDOC}  -a stylesheet=${SRC[1].abspath()} -a  icons=true -a max-width=55em  -o ${TGT} ${SRC[0].abspath()}',
         source='release_notes.asciidoc waf.css', target='release_notes.html', scan=ascii_doc_scan)
                 
-
-    bld(rule='${ASCIIDOC} -a docinfo -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2 -a max-width=55em  -d book   -o ${TGT} ${SRC[0].abspath()}',
-        source='trex_book.asciidoc waf.css', target='trex_manual.html', scan=ascii_doc_scan)
-
-    bld(rule='${ASCIIDOC} -a docinfo -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2  -a max-width=55em  -d book   -o ${TGT} ${SRC[0].abspath()}',
-        source='trex_stateless.asciidoc waf.css', target='trex_stateless.html', scan=ascii_doc_scan)
-
     bld(rule='${ASCIIDOC} -a docinfo -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2  -a max-width=55em  -d book   -o ${TGT} ${SRC[0].abspath()}',
         source='draft_trex_stateless.asciidoc waf.css', target='draft_trex_stateless.html', scan=ascii_doc_scan)
 
@@ -277,17 +463,26 @@ def build(bld):
     
     bld(rule=convert_to_pdf_book, source='trex_control_plane_design_phase1.asciidoc waf.css', target='trex_control_plane_design_phase1.pdf', scan=ascii_doc_scan)
 
-    bld(rule='${ASCIIDOC}   -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2 -a max-width=55em  -o ${TGT} ${SRC[0].abspath()}',
-        source='trex_vm_manual.asciidoc waf.css', target='trex_vm_manual.html', scan=ascii_doc_scan)
+    # with nice TOC 
+    bld(rule=convert_to_html_toc_book,
+        source='trex_vm_manual.asciidoc waf.css', target='trex_vm_manual.html',scan=ascii_doc_scan)
+
+    bld(rule=convert_to_html_toc_book,
+        source='trex_stateless.asciidoc waf.css', target='trex_stateless.html',scan=ascii_doc_scan);
+
+    bld(rule=convert_to_html_toc_book,
+        source='trex_book.asciidoc waf.css', target='trex_manual.html',scan=ascii_doc_scan);
+
+    bld(rule=convert_to_html_toc_book,
+        source='trex_rpc_server_spec.asciidoc waf.css', target='trex_rpc_server_spec.html',scan=ascii_doc_scan);
+
+
 
     bld(rule='${ASCIIDOC}   -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2 -a max-width=55em  -o ${TGT} ${SRC[0].abspath()}',
         source='vm_doc.asciidoc waf.css', target='vm_doc.html', scan=ascii_doc_scan)
 
     bld(rule='${ASCIIDOC}   -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2 -a max-width=55em  -o ${TGT} ${SRC[0].abspath()}',
         source='packet_builder_yaml.asciidoc waf.css', target='packet_builder_yaml.html', scan=ascii_doc_scan)
-        
-    bld(rule='${ASCIIDOC}   -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2 -a max-width=55em  -o ${TGT} ${SRC[0].abspath()}',
-        source='trex_rpc_server_spec.asciidoc waf.css', target='trex_rpc_server_spec.html', scan=ascii_doc_scan)
 
     bld(rule='${ASCIIDOC}   -a stylesheet=${SRC[1].abspath()} -a  icons=true -a toc2 -a max-width=55em  -o ${TGT} ${SRC[0].abspath()}',
         source='trex_control_plane_design_phase1.asciidoc waf.css', target='trex_control_plane_design_phase1.html', scan=ascii_doc_scan)
@@ -367,18 +562,18 @@ def release(bld):
 def publish(bld):
     # copy all the files to our web server 
     remote_dir = "%s:%s" % ( Env().get_local_web_server(), Env().get_remote_release_path ()+'../doc/')
-    os.system('rsync -av --rsh=ssh build/ %s' % (remote_dir))
+    os.system('rsync -av --del --rsh=ssh build/ %s' % (remote_dir))
 
 
 def publish_ext(bld):
    from_ = 'build/'
-   os.system('rsync -avz -e "ssh -i %s" --rsync-path=/usr/bin/rsync %s %s@%s:%s/doc/' % (Env().get_trex_ex_web_key(),from_, Env().get_trex_ex_web_user(),Env().get_trex_ex_web_srv(),Env().get_trex_ex_web_path() ) )
+   os.system('rsync -avz --del -e "ssh -i %s" --rsync-path=/usr/bin/rsync %s %s@%s:%s/doc/' % (Env().get_trex_ex_web_key(),from_, Env().get_trex_ex_web_user(),Env().get_trex_ex_web_srv(),Env().get_trex_ex_web_path() ) )
    
 
 def publish_test(bld):
     # copy all the files to our web server 
     remote_dir = "%s:%s" % ( Env().get_local_web_server(), Env().get_remote_release_path ()+'../test/')
-    os.system('rsync -av --rsh=ssh build/ %s' % (remote_dir))
+    os.system('rsync -av --del --rsh=ssh build/ %s' % (remote_dir))
 
 
 
diff --git a/wscript b/wscript
index f935668..187a552 100755 (executable)
--- a/wscript
+++ b/wscript
@@ -24,6 +24,9 @@ def configure(conf):
     ws_main.configure(conf)
 
 
+def create_toc (bld):
+    ws_main.create_toc(bld)
+
 def build(bld):
     ws_main.build(bld)