Author: jross
Date: Fri Jan 29 01:42:18 2016
New Revision: 1727465

URL: http://svn.apache.org/viewvc?rev=1727465&view=rev
Log:
QPID-6970: Update transom; convert remaining wiki-style tables to standard 
formats

Modified:
    qpid/site/Makefile
    qpid/site/input/components/messaging-api/index.md
    qpid/site/input/components/qmf/index.md
    qpid/site/input/components/qpid-jca/index.md
    qpid/site/input/components/qpid-wcf/index.md
    qpid/site/python/transom.py

Modified: qpid/site/Makefile
URL: 
http://svn.apache.org/viewvc/qpid/site/Makefile?rev=1727465&r1=1727464&r2=1727465&view=diff
==============================================================================
--- qpid/site/Makefile (original)
+++ qpid/site/Makefile Fri Jan 29 01:42:18 2016
@@ -137,3 +137,7 @@ gen-cpp-release-%:
 .PHONY: update-plano
 update-plano:
        curl 
"https://raw.githubusercontent.com/ssorj/plano/master/python/plano.py"; -o 
python/plano.py
+
+.PHONY: update-transom
+update-transom:
+       curl 
"https://raw.githubusercontent.com/ssorj/transom/master/python/transom.py"; -o 
python/transom.py

Modified: qpid/site/input/components/messaging-api/index.md
URL: 
http://svn.apache.org/viewvc/qpid/site/input/components/messaging-api/index.md?rev=1727465&r1=1727464&r2=1727465&view=diff
==============================================================================
--- qpid/site/input/components/messaging-api/index.md (original)
+++ qpid/site/input/components/messaging-api/index.md Fri Jan 29 01:42:18 2016
@@ -22,11 +22,11 @@
 A connection-oriented messaging API that supports many languages and
 platforms.
 
-  || *Languages* || C++, Perl, Python, Ruby, .NET ||
-  || *Platforms* || Linux, Windows ||
-  || *AMQP versions* || 1.0, 0-10 ||
-  || *Downloads* || C++, bindings: 
[qpid-cpp-{{current_cpp_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz.sha1)],<br/>Python:
 
[qpid-python-{{current_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz.sha1)]
 
 ||
-  || *Source location* ||  
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/>,<br/> 
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/python/> ||
+  - *Languages* - C++, Perl, Python, Ruby, .NET
+  - *Platforms* - Linux, Windows
+  - *AMQP versions* - 1.0, 0-10
+  - *Downloads* - C++, bindings: 
[qpid-cpp-{{current_cpp_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/cpp/{{current_cpp_release}}/qpid-cpp-{{current_cpp_release}}.tar.gz.sha1)],<br/>Python:
 
[qpid-python-{{current_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/{{current_release}}/qpid-python-{{current_release}}.tar.gz.sha1)]
+  - *Source location* -  
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/>,<br/> 
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/python/>
 
 ## Documentation
 
@@ -56,11 +56,13 @@ find previous versions with our
 
 ### Examples
 
-  || *C++* || 
[hello_world.cpp]({{current_release_url}}/messaging-api/cpp/examples/hello_world.cpp.html)
 || 
[client.cpp]({{current_release_url}}/messaging-api/cpp/examples/client.cpp.html)
 || 
[server.cpp]({{current_release_url}}/messaging-api/cpp/examples/server.cpp.html)
 || 
[spout.cpp]({{current_release_url}}/messaging-api/cpp/examples/spout.cpp.html) 
|| 
[drain.cpp]({{current_release_url}}/messaging-api/cpp/examples/drain.cpp.html) 
||
-  || *Perl* || 
[hello_world.pl]({{current_release_url}}/messaging-api/perl/examples/hello_world.pl.html)
 || 
[client.pl]({{current_release_url}}/messaging-api/perl/examples/client.pl.html) 
|| 
[server.pl]({{current_release_url}}/messaging-api/perl/examples/server.pl.html) 
|| 
[spout.pl]({{current_release_url}}/messaging-api/perl/examples/spout.pl.html) 
|| 
[drain.pl]({{current_release_url}}/messaging-api/perl/examples/drain.pl.html) ||
-  || *Python* || 
[hello]({{current_release_url}}/messaging-api/python/examples/hello.html) ||  
|| [server]({{current_release_url}}/messaging-api/python/examples/server.html) 
|| [spout]({{current_release_url}}/messaging-api/python/examples/spout.html) || 
[drain]({{current_release_url}}/messaging-api/python/examples/drain.html) ||
-  || *Ruby* || 
[hello_world.rb]({{current_release_url}}/messaging-api/ruby/examples/hello_world.rb.html)
 || 
[client.rb]({{current_release_url}}/messaging-api/ruby/examples/client.rb.html) 
|| 
[server.rb]({{current_release_url}}/messaging-api/ruby/examples/server.rb.html) 
|| 
[spout.rb]({{current_release_url}}/messaging-api/ruby/examples/spout.rb.html) 
|| 
[drain.rb]({{current_release_url}}/messaging-api/ruby/examples/drain.rb.html) ||
-  || *.NET* || 
[helloworld.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.helloworld.cs.html)
 || 
[client.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.client.cs.html)
 || 
[server.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.server.cs.html)
 || 
[spout.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.spout.cs.html)
 || 
[drain.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.drain.cs.html)
 ||
+  | Language | Hello World | Client | Server | Spout | Drain |
+  | - | - | - | - | - | - |
+  | *C++* | 
[hello_world.cpp]({{current_release_url}}/messaging-api/cpp/examples/hello_world.cpp.html)
 | 
[client.cpp]({{current_release_url}}/messaging-api/cpp/examples/client.cpp.html)
 | 
[server.cpp]({{current_release_url}}/messaging-api/cpp/examples/server.cpp.html)
 | 
[spout.cpp]({{current_release_url}}/messaging-api/cpp/examples/spout.cpp.html) 
| 
[drain.cpp]({{current_release_url}}/messaging-api/cpp/examples/drain.cpp.html) |
+  | *Perl* | 
[hello_world.pl]({{current_release_url}}/messaging-api/perl/examples/hello_world.pl.html)
 | 
[client.pl]({{current_release_url}}/messaging-api/perl/examples/client.pl.html) 
| 
[server.pl]({{current_release_url}}/messaging-api/perl/examples/server.pl.html) 
| [spout.pl]({{current_release_url}}/messaging-api/perl/examples/spout.pl.html) 
| [drain.pl]({{current_release_url}}/messaging-api/perl/examples/drain.pl.html) 
|
+  | *Python* | 
[hello]({{current_release_url}}/messaging-api/python/examples/hello.html) |  | 
[server]({{current_release_url}}/messaging-api/python/examples/server.html) | 
[spout]({{current_release_url}}/messaging-api/python/examples/spout.html) | 
[drain]({{current_release_url}}/messaging-api/python/examples/drain.html) |
+  | *Ruby* | 
[hello_world.rb]({{current_release_url}}/messaging-api/ruby/examples/hello_world.rb.html)
 | 
[client.rb]({{current_release_url}}/messaging-api/ruby/examples/client.rb.html) 
| 
[server.rb]({{current_release_url}}/messaging-api/ruby/examples/server.rb.html) 
| [spout.rb]({{current_release_url}}/messaging-api/ruby/examples/spout.rb.html) 
| [drain.rb]({{current_release_url}}/messaging-api/ruby/examples/drain.rb.html) 
|
+  | *.NET* | 
[helloworld.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.helloworld.cs.html)
 | 
[client.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.client.cs.html)
 | 
[server.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.server.cs.html)
 | 
[spout.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.spout.cs.html)
 | 
[drain.cs]({{current_release_url}}/messaging-api/dotnet/examples/csharp.example.drain.cs.html)
 |
 
 ## Issues
 

Modified: qpid/site/input/components/qmf/index.md
URL: 
http://svn.apache.org/viewvc/qpid/site/input/components/qmf/index.md?rev=1727465&r1=1727464&r2=1727465&view=diff
==============================================================================
--- qpid/site/input/components/qmf/index.md (original)
+++ qpid/site/input/components/qmf/index.md Fri Jan 29 01:42:18 2016
@@ -24,11 +24,11 @@ built on Qpid messaging. It takes advant
 security, and rich capabilities of Qpid to provide flexible and
 easy-to-use manageability to a large set of applications.
 
-  || *Languages* || C++, Python ||
-  || *Platforms* || Linux ||
-  || *AMQP versions* || 0-10 ||
-  || *Downloads* || 
[qpid-cpp-{{current_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz.sha1)],
 
[qpid-qmf-{{current_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz.sha1)]
 ||
-  || *Source location* ||  
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/>,<br/> 
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/extras/qmf/> ||
+  - *Languages* - C++, Python
+  - *Platforms* - Linux
+  - *AMQP versions* - 0-10
+  - *Downloads* - 
[qpid-cpp-{{current_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/{{current_release}}/qpid-cpp-{{current_release}}.tar.gz.sha1)],
 
[qpid-qmf-{{current_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/{{current_release}}/qpid-qmf-{{current_release}}.tar.gz.sha1)]
+  - *Source location* -  
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/>,<br/> 
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/extras/qmf/>
 
 ## Documentation
 

Modified: qpid/site/input/components/qpid-jca/index.md
URL: 
http://svn.apache.org/viewvc/qpid/site/input/components/qpid-jca/index.md?rev=1727465&r1=1727464&r2=1727465&view=diff
==============================================================================
--- qpid/site/input/components/qpid-jca/index.md (original)
+++ qpid/site/input/components/qpid-jca/index.md Fri Jan 29 01:42:18 2016
@@ -24,11 +24,11 @@ A
 1.5 compliant resource adapter that allows for JEE integration between
 EE applications and AMQP 0-10 message brokers.
 
-  || *Languages* || Java ||
-  || *Platforms* || JVM ||
-  || *AMQP versions* || 0-10 ||
-  || *Download* || 
[qpid-java-{{current_java_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz.sha1)]
 ||
-  || *Source location* ||  
<http://svn.apache.org/repos/asf/qpid/java/trunk/jca/> ||
+  - *Languages* - Java
+  - *Platforms* - JVM
+  - *AMQP versions* - 0-10
+  - *Download* - 
[qpid-java-{{current_java_release}}.tar.gz](http://www.apache.org/dyn/closer.lua/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz)
 
\[[ASC](http://www.apache.org/dist/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz.asc),
 
[MD5](http://www.apache.org/dist/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz.md5),
 
[SHA1](http://www.apache.org/dist/qpid/java/{{current_java_release}}/qpid-java-{{current_java_release}}.tar.gz.sha1)]
+  - *Source location* -  <http://svn.apache.org/repos/asf/qpid/java/trunk/jca/>
 
 ## Features
 

Modified: qpid/site/input/components/qpid-wcf/index.md
URL: 
http://svn.apache.org/viewvc/qpid/site/input/components/qpid-wcf/index.md?rev=1727465&r1=1727464&r2=1727465&view=diff
==============================================================================
--- qpid/site/input/components/qpid-wcf/index.md (original)
+++ qpid/site/input/components/qpid-wcf/index.md Fri Jan 29 01:42:18 2016
@@ -23,11 +23,11 @@ A [Windows Communication
 Foundation](http://msdn.microsoft.com/en-us/library/ms731082.aspx)
 channel implementation that speaks AMQP.
 
-  || *Languages* || .NET ||
-  || *Platforms* || Windows ||
-  || *AMQP versions* || 0-10 ||
-  || *Downloads* || 
[qpid-wcf-0.28.zip](http://archive.apache.org/dist/qpid/0.28/qpid-wcf-0.28.zip) 
\[[ASC](http://archive.apache.org/dist/qpid/0.28/qpid-wcf-0.28.zip.asc), 
[SHA1](http://archive.apache.org/dist/qpid/0.28/SHA1SUM)] ||
-  || *Source location* ||  
<http://svn.apache.org/repos/asf/qpid/trunk/qpid/wcf/> ||
+  - *Languages* - .NET
+  - *Platforms* - Windows
+  - *AMQP versions* - 0-10
+  - *Downloads* - 
[qpid-wcf-0.28.zip](http://archive.apache.org/dist/qpid/0.28/qpid-wcf-0.28.zip) 
\[[ASC](http://archive.apache.org/dist/qpid/0.28/qpid-wcf-0.28.zip.asc), 
[SHA1](http://archive.apache.org/dist/qpid/0.28/SHA1SUM)]
+  - *Source location* -  <http://svn.apache.org/repos/asf/qpid/trunk/qpid/wcf/>
 
 ## Features
 

Modified: qpid/site/python/transom.py
URL: 
http://svn.apache.org/viewvc/qpid/site/python/transom.py?rev=1727465&r1=1727464&r2=1727465&view=diff
==============================================================================
--- qpid/site/python/transom.py (original)
+++ qpid/site/python/transom.py Fri Jan 29 01:42:18 2016
@@ -68,16 +68,17 @@ class Transom:
         
         extras = {
             "code-friendly": True,
-            "tables": True,
-            "wiki-tables": True,
+            "footnotes": True,
             "header-ids": True,
             "markdown-in-html": True,
+            "metadata": True,
+            "tables": True,
             }
 
         self.markdown = _markdown2.Markdown(extras=extras)
 
         self.files = list()
-        self.files_by_input_path = dict()
+        self.files_by_path = dict()
 
         self.resources = list()
         self.pages = list()
@@ -94,8 +95,7 @@ class Transom:
         if not _is_file(self.template_path):
             raise Exception("No template found")
             
-        with _open_file(self.template_path, "r") as file:
-            self.template_content = file.read()
+        self.template_content = _read_file(self.template_path)
 
         init_globals = {"site_url": self.site_url}
 
@@ -104,8 +104,8 @@ class Transom:
         else:
             self.config_env = init_globals
 
-        self.traverse_input_pages(self.input_dir, None)
-        self.traverse_input_resources(self.input_dir)
+        self.traverse_input_pages("", None)
+        self.traverse_input_resources("")
 
         for file in self.files:
             file.init()
@@ -146,9 +146,7 @@ class Transom:
         for subpath in subpaths:
             from_file = _join(from_dir, subpath)
             to_file = _join(to_dir, subpath)
-            parent_dir = _split(to_file)[0]
 
-            _make_dir(parent_dir)
             _copy_file(from_file, to_file)
 
     def check_output_files(self):
@@ -158,7 +156,7 @@ class Transom:
         for file in self.files:
             expected_files.add(file.output_path)
 
-        self.traverse_output_files(self.output_dir, found_files)
+        self.traverse_output_files("", found_files)
 
         missing_files = expected_files.difference(found_files)
         extra_files = found_files.difference(expected_files)
@@ -175,15 +173,23 @@ class Transom:
             for path in sorted(extra_files):
                 print("  {}".format(path))
 
-    def traverse_output_files(self, dir, files):
-        names = set(_os.listdir(dir))
+    def traverse_output_files(self, subdir, files):
+        output_dir = _join(self.output_dir, subdir)
+        names = set(_os.listdir(output_dir))
 
         for name in names:
-            path = _join(dir, name)
+            path = _join(subdir, name)
+            output_path = _join(self.output_dir, path)
 
-            if _is_file(path):
-                files.add(path)
-            elif _is_dir(path) and name != ".svn":
+            if _is_file(output_path):
+                files.add(output_path)
+            elif _is_dir(output_path):
+                if name == ".svn":
+                    continue
+
+                if name == "transom":
+                    continue
+                
                 self.traverse_output_files(path, files)
 
     def check_links(self, internal=True, external=False):
@@ -232,8 +238,7 @@ class Transom:
         config_path = _join(self.input_dir, "_transom_ignore_links")
 
         if _is_file(config_path):
-            with _open_file(config_path, "r") as file:
-                ignore_patterns = list(file)
+            ignore_patterns = _read_file(config_path)
 
             def retain(link):
                 for pattern in ignore_patterns:
@@ -263,8 +268,9 @@ class Transom:
 
         return code, error
 
-    def traverse_input_pages(self, dir, page):
-        names = set(_os.listdir(dir))
+    def traverse_input_pages(self, subdir, parent_page):
+        input_dir = _join(self.input_dir, subdir)
+        names = set(_os.listdir(input_dir))
 
         if "_transom_ignore_pages" in names:
             return
@@ -272,56 +278,78 @@ class Transom:
         for name in ("index.md", "index.html", "index.html.in"):
             if name in names:
                 names.remove(name)
-                page = _Page(self, _join(dir, name), page)
+                parent_page = _Page(self, _join(subdir, name), parent_page)
                 break
 
         for name in sorted(names):
-            path = _join(dir, name)
-
             if name.startswith("_transom_"):
                 continue
 
-            if _is_file(path):
-                for extension in _page_extensions:
-                    if name.endswith(extension):
-                        _Page(self, path, page)
-                        break
-            elif _is_dir(path) and name != ".svn":
-                self.traverse_input_pages(path, page)
+            if name == ".svn":
+                continue
 
-    def traverse_input_resources(self, dir):
-        names = set(_os.listdir(dir))
+            path = _join(subdir, name)
+            input_path = _join(self.input_dir, path)
 
-        for name in sorted(names):
-            path = _join(dir, name)
+            if _is_file(input_path):
+                if input_path.endswith(".html.in"):
+                    ext = ".html.in"
+                else:
+                    stem, ext = _os.path.splitext(name)
+
+                if ext in _page_extensions:
+                    _Page(self, path, parent_page)
+            elif _is_dir(input_path):
+                self.traverse_input_pages(path, parent_page)
+
+    def traverse_input_resources(self, subdir):
+        input_dir = _join(self.input_dir, subdir)
+        names = set(_os.listdir(input_dir))
+
+        if "_transom_ignore_resources" in names:
+            return
 
+        for name in sorted(names):
             if name.startswith("_transom_"):
                 continue
 
-            if _is_file(path):
-                if path not in self.files_by_input_path:
+            if name == ".svn":
+                continue
+
+            path = _join(subdir, name)
+            input_path = _join(self.input_dir, path)
+
+            if _is_file(input_path):
+                if path not in self.files_by_path:
                     _Resource(self, path)
-            elif _is_dir(path) and name != ".svn":
+            elif _is_dir(input_path):
                 self.traverse_input_resources(path)
 
-    def get_output_path(self, input_path):
-        path = input_path[len(self.input_dir) + 1:]
-        return _join(self.output_dir, path)
-
     def get_url(self, output_path):
         path = output_path[len(self.output_dir) + 1:]
         path = path.replace(_os.path.sep, "/")
+
         return "{}/{}".format(self.site_url, path)
 
+    def info(self, message, *args):
+        if self.verbose:
+            print(message.format(*args))
+
+    def warn(self, message, *args):
+        message = message.format(*args)
+        print("Warning! {}".format(message))
+
 class _File(object):
-    def __init__(self, site, input_path):
+    def __init__(self, site, path):
         self.site = site
-        self.input_path = input_path
-        self.output_path = self.site.get_output_path(self.input_path)
+        self.path = path
+
+        self.input_path = _join(self.site.input_dir, self.path)
+        self.output_path = _join(self.site.output_dir, self.path)
         self.url = self.site.get_url(self.output_path)
 
         self.site.files.append(self)
-        self.site.files_by_input_path[self.input_path] = self
+        self.site.files_by_path[self.path] = self
 
     def init(self):
         self.site.link_targets.add(self.url)
@@ -353,6 +381,7 @@ class _File(object):
             except Exception as e:
                 msg = "Expression '{}'; file '{}'; {}"
                 args = expr, self.input_path, e
+
                 print(msg.format(*args))
 
                 out.append(token)
@@ -364,27 +393,28 @@ class _File(object):
         return "".join(out)
 
     def __repr__(self):
-        return _format_repr(self, self.input_path)
+        return _format_repr(self, self.path)
 
 class _Resource(_File):
-    def __init__(self, site, input_path):
-        super(_Resource, self).__init__(site, input_path)
+    def __init__(self, site, path):
+        super(_Resource, self).__init__(site, path)
 
         self.site.resources.append(self)
 
     def save_output(self):
-        _make_dir(_split(self.output_path)[0])
         _copy_file(self.input_path, self.output_path)
 
 class _Page(_File):
-    def __init__(self, site, input_path, parent):
-        super(_Page, self).__init__(site, input_path)
+    def __init__(self, site, path, parent):
+        super(_Page, self).__init__(site, path)
 
         self.parent = parent
 
         self.content = None
-        self.title = None
         self.template_content = None
+
+        self.title = None
+        self.attributes = dict()
         
         self.site.pages.append(self)
 
@@ -400,73 +430,58 @@ class _Page(_File):
 
         self.template_content = self.site.template_content
         
-        page_dir = _split(self.input_path)[0]
-        template_path = _join(page_dir, "_transom_template.html")
+        input_dir, name = _split(self.input_path)
+        template_path = _join(input_dir, "_transom_template.html")
 
         if _is_file(template_path):
-            with _open_file(template_path, "r") as file:
-                self.template_content = file.read()
+            self.template_content = _read_file(template_path)
         
     def load_input(self):
-        if self.site.verbose:
-            print("Loading {}".format(self))
-
-        with _open_file(self.input_path, "r") as file:
-            self.content = file.read()
+        self.site.info("Loading {}", self)
+        self.content = _read_file(self.input_path)
 
     def save_output(self, path=None):
-        if self.site.verbose:
-            print("Saving {} to {}".format(self, self.output_path))
+        self.site.info("Saving {} to {}", self, self.output_path)
 
         if path is None:
             path = self.output_path
 
-        _make_dir(_split(path)[0])
-
-        with _open_file(self.output_path, "w") as file:
-            file.write(self.content)
+        _write_file(self.output_path, self.content)
 
     def load_output(self):
-        with _open_file(self.output_path, "r") as file:
-            self.content = file.read()
+        self.content = _read_file(self.output_path)
 
     def convert(self):
-        if self.input_path.endswith(".md"):
+        if self.path.endswith(".md"):
             self.convert_from_markdown()
-        elif self.input_path.endswith(".html.in"):
+        elif self.path.endswith(".html.in"):
             self.convert_from_html_in()
 
     def convert_from_markdown(self):
-        if self.site.verbose:
-            print("Converting {} from markdown".format(self))
+        self.site.info("Converting {} from markdown", self)
 
         # Strip out comments
         content_lines = self.content.splitlines()
-        content_lines = (x for x in content_lines if not x.startswith(";;"))
+        content_lines = [x for x in content_lines if not x.startswith(";;")]
 
         content = _os.linesep.join(content_lines)
         content = self.site.markdown.convert(content)
 
         self.content = self.apply_template(content)
+        self.attributes.update(content.metadata)
 
     def convert_from_html_in(self):
-        if self.site.verbose:
-            print("Converting {} from html.in".format(self))
-
+        self.site.info("Converting {} from html.in", self)
         self.content = self.apply_template(self.content)
 
     def apply_template(self, content):
         return self.template_content.replace("{{content}}", content)
 
     def process(self):
-        if self.site.verbose:
-            print("Processing {}".format(self))
-
-        if self.parent is None:
-            self.title = "Home"
-            return
+        self.site.info("Processing {}", self)
 
-        self.title = _split(self.output_path)[1]
+        dir, name = _split(self.output_path)
+        self.title = name
 
         if isinstance(self.title, bytes):
             self.title = self.title.decode("utf8")
@@ -480,12 +495,12 @@ class _Page(_File):
         self.title = self.title.strip()
 
     def render(self):
-        if self.site.verbose:
-            print("Rendering {}".format(self))
+        self.site.info("Rendering {}", self)
 
         page_vars = {
-            "path_navigation": self.render_path_navigation(),
             "title": self.title,
+            "path_navigation": self.render_path_navigation(),
+            "extra_headers" : self.attributes.get("extra_headers", ""),
         }
 
         self.content = self.replace_placeholders(self.content, page_vars)
@@ -514,7 +529,7 @@ class _Page(_File):
         try:
             root = self.parse_xml(self.content)
         except Exception as e:
-            print("Warning: {}".format(str(e)))
+            self.site.warn(str(e))
             return
 
         links = self.gather_links(root)
@@ -576,12 +591,18 @@ class _Page(_File):
 
             target = "{}#{}".format(self.url, id)
 
-            assert target not in link_targets, target
+            if target in link_targets:
+                self.site.warn("Duplicate link target in '{}'", target)
 
             link_targets.add(target)
 
         return link_targets
 
+_join = _os.path.join
+_split = _os.path.split
+_is_file = _os.path.isfile
+_is_dir = _os.path.isdir
+
 def _make_dir(dir):
     if not _os.path.exists(dir):
         _os.makedirs(dir)
@@ -589,6 +610,16 @@ def _make_dir(dir):
 def _open_file(path, mode):
     return _codecs.open(path, mode, "utf8", "replace", _buffer_size)
 
+def _read_file(path):
+    with _open_file(path, "r") as file:
+        return file.read()
+
+def _write_file(path, content):
+    _make_dir(_split(path)[0])
+
+    with _open_file(path, "w") as file:
+        return file.write(content)
+    
 # Adapted from 
http://stackoverflow.com/questions/22078621/python-how-to-copy-files-fast
 
 _read_flags = _os.O_RDONLY
@@ -596,6 +627,8 @@ _write_flags = _os.O_WRONLY | _os.O_CREA
 _eof = b""
 
 def _copy_file(src, dst):
+    _make_dir(_split(dst)[0])
+    
     try:
         fin = _os.open(src, _read_flags)
         fout = _os.open(dst, _write_flags)
@@ -610,8 +643,3 @@ def _format_repr(obj, *args):
     cls = obj.__class__.__name__
     strings = [str(x) for x in args]
     return "{}({})".format(cls, ",".join(strings))
-
-_join = _os.path.join
-_split = _os.path.split
-_is_file = _os.path.isfile
-_is_dir = _os.path.isdir



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to