Browse Source

rm tex doc

221V 3 years ago
parent
commit
b413524832

+ 0 - 123
doc/actions.tex

@@ -1,123 +0,0 @@
-\section{Actions}
-
-\paragraph{}
-{\bf \#action} is the basic record for all actions. It means that each action
-has {\bf \#action} as its ancestor.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    #action { ancestor,
-              target,
-              module,
-              actions,
-              source=[] }.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-{\bf target} specifies an element where this action will arise.
-
-\subsection{JavaScript DSL {\bf \#jq}}
-JavaScript query selector action mimics JavaScript calls and assignments.
-Specific action may be performed depending on filling{\bf property} or {\bf method} fields.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -record(jq, {?ACTION_BASE(action_jq),
-            property,
-            method,
-            args=[],
-            right }).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Here is an example of method calls:
-\begin{lstlisting}
-    wf:wire(#jq{target=n2ostatus,method=[show,select]}).
-\end{lstlisting}
-unfolded to calls:
-\begin{lstlisting}
-    document.querySelector('#n2ostatus').show();
-    document.querySelector('#n2ostatus').select();
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-And here is example of property chained assignments:
-\begin{lstlisting}
-    wf:wire(#jq{target=history,property=scrollTop,
-        right=#jq{target=history,property=scrollHeight}}).
-\end{lstlisting}
-which transforms to:
-\begin{lstlisting}
-    document.querySelector('#history').scrollTop =
-        document.querySelector('#history').scrollHeight;
-\end{lstlisting}
-\vspace{1\baselineskip}
-Part of N2O API is implemented using \#jq actions (updates and redirect).
-This action is introduced as transitional in order to move
-from Nitrogen DSL to using pure JavaScript transformations.
-
-\subsection*{Event Actions}
-Objects passed over WebSockets channel from server to client are called {\bf actions}.
-Objects passed over the same channel from client to server are called {\bf events}. However
-events themselves are bound to HTML elements with {\bf addEventListener} and in order to perform these bindings,
-actions should be sent first. Such actions are called {\bf event actions}. There are three types of event actions.
-
-\subsection{Page Events {\bf \#event}}
-Page events are regular events routed to the calling module. Postback field is used as the main
-routing argument for {\bf event} module function. By providing {\bf source} elements list you specify
-HTML controls values sent to the server and accessed with {\bf wf:q} accessor from the page context.
-Page events are normally generated by active elements like {\bf \#button}, {\bf \#link},
-{\bf \#textbox}, {\bf \#dropdown}, {\bf \#select}, {\bf \#radio} and others elements
-contain postback field.
-
-\paragraph{}
-Control events are used to solve the need of element writers. When you develop your
-own control elements, you usually want events to be routed not to page but to element module.
-Control events were introduced for this purpose.
-
-\subsection{API Events {\bf \#api}}
-When you need to call Erlang function from JavaScript directly you should use API events.
-API events are routed to page module with {\bf api\_event/3} function. API events were
-used in {\bf AVZ} authorization library. Here is an example of how JSON login could be
-implemented using {\bf api\_event}:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    api_event(appLogin, Args, Term) ->
-        Struct = n2o_json:decode(Args),
-        wf:info(?MODULE, "Granted Access"),
-        wf:redirect("/account").
-\end{lstlisting}
-\vspace{1\baselineskip}
-And from JavaScript you call it like this:
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    document.appLogin(JSON.stringify(response));
-\end{lstlisting}
-\vspace{1\baselineskip}
-All API events are bound to root of the HTML document.
-
-
-\subsection{Message Box {\bf \#alert}}
-Message box {\bf alert} is a very simple dialog that could be used for client debugging.
-You can use {\bf console.log} along with alerts.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    event({debug,Var}) ->
-        wf:wire(#alert{text="Debug: " ++ wf:to_list(Var)}),
-\end{lstlisting}
-
-\subsection{Confirmation Box {\bf \#confirm}}
-You can use confirmation boxes for simple approval with JavaScript {\bf confirm} dialogs.
-You should extend this action in order to build custom dialogs. Confirmation box is just an example of how to
-organize this type of logic.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    event(confirm) ->
-        wf:wire(#confirm{text="Are you happy?",postback=continue}),
-
-    event(continue) -> wf:info(?MODULE, "Yes, you're right!", []);
-\end{lstlisting}
-\vspace{1\baselineskip}

+ 0 - 446
doc/api.tex

@@ -1,446 +0,0 @@
-\section{API}
-
-\subsection{Update DOM \bf{wf:update}}
-You can update part of the page or DOM element with a given
-element or even raw HTML. N2O comes with NITRO template engine
-based on Erlang records syntax and optimized to be as fast as DTL or EEX template engines.
-You may use them with {\bf \#dtl} and {\bf \#eex} template NITRO elements.
-N2O Review application provides a sample how to use DTL templates.
-For using Nitrogen like DSL first you should include {\bf nitro} application to your
-rebar.config
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    {nitro,".*",{git,"git://github.com/synrc/nitro",{tag,"2.9"}}},
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-And also plug it in headers to your erlang page module:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -include("nitro/include/nitro.hrl").
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Here is an example of simple {\bf \#span} NITRO element with an HTML counterpart.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    wf:update(history,[#span{body="Hello"}]).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-It generates DOM update script and sends it to
-WebSocket channel for evaluation:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    document.querySelector('#history')
-            .outerHTML = '<span>Hello</span>';
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Companions are also provided for updating head and tail
-of the elements list: {\bf wf:insert\_top/2} and
-{\bf wf:insert\_bottom/2}. These are translated to appropriate
-JavaScript methods {\bf insertBefore} and {\bf appendChild} during rendering.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    wf:insert_top(history,
-        #panel{id=banner, body= [
-            #span{ id=text,
-                   body = wf:f("User ~s logged in.",[wf:user()]) },
-            #button{id=logout, body="Logout", postback=logout },
-            #br{} ]}),
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Remember to envelop all elements in common root element before inserts.
-
-\paragraph{}
-For relative updates use {\bf wf:insert\_before/2} and {\bf wf:insert\_after/2}.
-To remove an element use {\bf wf:remove/2}.
-
-\paragraph{\bf Element Naming}
-You can specify element's id with Erlang atoms,
-lists or binaries. During rendering the value will be converted
-with {\bf wf:to\_list}. Conversion will be consistent only if you use atoms.
-Otherwise you need to care about illegal symbols for element accessors.
-
-\paragraph{}
-During page updates you can create additional elements with
-runtime generated event handlers, perform HTML rendering for
-template elements or even use distributed map/reduce to calculate view.
-You have to be aware that heavy operations will consume
-more power in the browser, but you can save it by rendering
-HTML on server-side. All DOM updates API works both using
-JavaScript/OTP and server pages.
-
-\paragraph{}
-List of elements you can use is given in {\bf Chapter 9}. You can also create
-your own elements with a custom render function.
-If you want to see how custom element are being implemented you may refer
-to {\bf synrc/extra} packages where some useful controls may be found like
-file uploader, calendar, autocompletion textboxlist and HTML editor.
-
-\newpage
-\subsection{Wire JavaScript \bf{wf:wire}}
-Just like HTML is generated from Elements, Actions are rendered into
-JavaScript to handle events raised in the browser. Actions are always
-transformed into JavaScript and sent through WebSockets pipe.
-
-\subsection*{Direct Wiring}
-There are two types of actions. First class are direct JavaScript
-strings provided directly as Erlang lists or via JavaScript/OTP
-transformations.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    wf:wire("window.location='http://synrc.com'").
-\end{lstlisting}
-
-\subsection*{Actions Render}
-Second class actions are in fact Erlang records
-rendered during page load, server events or client events.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    wf:wire(#alert{text="Hello!"}).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-However basic N2O actions that are part of N2O API, {\bf wf:update} and {\bf wf:redirect},
-are implemented as Erlang records as given in the example. If you need deferred
-rendering of JavaScript, you can use Erlang records instead of direct wiring with
-Erlang lists or JavaScript/OTP.
-
-\paragraph{}
-Any action, wired with {\bf wf:wire}, is enveloped in {\bf \#wire\{actions=[]\}},
-which is also an action capable of polymorphic rendering of custom or built-in actions, specified in the list.
-Following nested action embedding is also valid:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    wf:wire(#wire{actions=[#alert{text="N2O"}]}).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-You may try to see how internally wiring is working:
-
-\begin{lstlisting}
-    > wf:actions().
-      []
-
-    > wf:wire(#alert{text="N2O"}).
-      [#wire{ancestor = action,trigger = undefined,
-             target = undefined,module = action_wire,
-             actions = #alert{ancestor = action,
-                              trigger = undefined,
-                              target = undefined,
-                              module = action_alert,
-                              actions = undefined,
-                              source = [], text = "N2O"},
-              source = []}]
-
-    > iolist_to_binary(wf:render(wf:actions())).
-      <<"alert(\"N2O\");">>
-\end{lstlisting}
-
-Consider wiring {\bf \#event} if you want to add listener to
-existed element on page:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-
-    > wf:wire(#event{target=btn,postback=evt,type=click}),
-      []
-
-    > rp(iolist_to_binary(wf:render(wf:actions()))).
-      <<"{var x=qi('element_id'); x && x.addEventListener('cl
-      ick',function (event){{ if (validateSources([])) ws.sen
-      d(enc(tuple(atom('pickle'),bin('element_id'),bin('g2gCa
-      AVkAAJldmQABWluZGV4ZAADZXZ0awAKZWxlbWVudF9pZGQABWV2ZW50
-      aANiAAAFoWIAB8kuYgAOvJA='),[tuple(tuple(utf8_toByteArra
-      y('element_id'),bin('detail')),event.detail)])));else c
-      onsole.log('Validation Error'); }});};">>
-\end{lstlisting}
-
-
-\newpage
-\subsection{Message Bus {\bf wf:reg} and {\bf wf:send}}
-N2O uses {\bf gproc} process registry for managing async processes pools.
-It is used as a PubSub message bus for N2O communications.
-You can associate a process with the pool with {\bf wf:reg}
-and send a message to the pool with {\bf wf:send}.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    loop() ->
-        receive M ->
-            wf:info(?MODULE, "P: ~p, M: ~p",[self(),M]) end, loop().
-\end{lstlisting}
-
-Now you can test it
-
-\begin{lstlisting}
-    > spawn(fun() -> wf:reg(topic), loop() end).
-    > spawn(fun() -> wf:reg(topic), loop() end).
-    > wf:send(topic,"Hello").
-\end{lstlisting}
-
-It should print in REPL something like:
-
-\begin{lstlisting}
-    > [info] P: <0.2012.0>, M: "Hello"
-    > [info] P: <0.2015.0>, M: "Hello"
-\end{lstlisting}
-
-\paragraph{\bf Custom Registrator}
-
-You may want to replace built-in {\bf gproc} based PubSub registrator
-with something more robust like MQTT and AMQP or something more
-internal like {\bf pg2}. All you need is to implement following API:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -module(mqtt_mq).
-    -compile(export_all).
-
-    send(Topic, Message) -> mqtt:publish(Topic, Message).
-    reg(Topic)           -> mqtt:subscribe(Topic, Message).
-    reg(Topic,Tag)       -> mqtt:subscribe(Topic, Tag, Message).
-    unreg(Topic)         -> mqtt:unsubscribe(Topic).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-And set it in runtime:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > application:set_env(n2o,mq,mqtt_mq).
-\end{lstlisting}
-
-\subsection{Async Processes {\bf wf:async} and {\bf wf:flush}}
-Function {\bf wf:async/2} creates Erlang process, which communicate with the primary page
-process by sending messages. {\bf wf:flush/0} should be called to redirect all updates and
-wire actions back to the page process from its async counterpart. But function {\bf wf:flush/1}
-has completly another meaning, it uses pubsub to deliver a rendered actions in async worker to
-any process, previously registered with {\bf wf:reg/1}, by its topic.
-Usually you send messages to async processes over N2O
-message bus {\bf wf:send/2} which is similar to how {\bf wf:flush/1} works.
-But you can use also {\bf n2o\_async:send/2} selectively to async worker what reminds
-{\bf wf:flush/0}. In following
-example different variants are gives, both incrementing counter by 2. Also notice
-the async process initialization through {\bf init} message. It is not nessesary
-to include init clause to async looper.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    body()      -> [ #span   { id=display, body="0"},
-                     #button { id=send, body="Inc",
-                               postback=inc} ].
-
-    event(init) -> wf:async("counter",fun loop/1);
-    event(inc)  -> wf:send(counter,up),
-                   n2o_async:send("counter",up).
-
-    loop(init)  -> wf:reg(counter), put(counter,0);
-    loop(up)    -> C = get(counter) + 1,
-                   put(counter,C),
-                   wf:update(display,
-                      #span{id=display,body=wf:to_binary(C)}),
-                   wf:flush().
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\paragraph{\bf Process Naming}
-The name of async process is globally unique. There are two
-versions, {\bf wf:async/1} and {\bf wf:async/2}. In the given example
-the name of async process is specified as ``counter'', otherwise,
-if the first parameter was not specified, the default name ``looper''
-will be used. Internally each async process includes custom key which
-is settled by default to session id.
-
-\newpage
-So let's mimic {\bf session\_id} and {\bf \#cx} in the shell:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > put(session_id,<<"d43adcc79dd64393a1eb559227a2d3fd">>).
-      undefined
-
-    > wf:context(wf:init_context(undefined)).
-      {cx,[{query,n2o_query},
-           {session,n2o_session},
-           {route,routes}],
-           [],[],index,undefined,[],
-           undefined,[],undefined,[]}
-
-    > wf:async("ho!",
-         fun(X) -> io:format("Received: ~p~n",[X]) end).
-      index:Received: init
-      {<0.507.0>,{async,
-        {"ho!",<<"d43adcc79dd64393a1eb559227a2d3fd">>}}}
-
-    > supervisor:which_children(n2o_sup).
-      [{{async,
-          {"counter",<<"d43adcc79dd64393a1eb559227a2d3fd">>}},
-        <0.11564.0>,worker,
-        [n2o_async]}]
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Async workers suppors both sync and async messages, you may use {\bf gen\_server}
-for calling by pid, {\bf n2o\_async} for named or even built-in erlang way of
-sending messages. All types of handlilng like info, cast and call are supported.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > pid(0,507,0) ! "hey".
-      Received: "hey"
-      ok
-
-    > n2o_async:send("ho!","hola").
-      Received: "hola"
-      ok
-
-    > gen_server:call(pid(0,507,0),"sync").
-      Received: "sync"
-      ok
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Parse URL and Context parameters {\bf wf:q} and {\bf wf:qp}}
-These are used to extract URL parameters or read from the process context.
-{\bf wf:q} extracts variables from the context stored by controls postbacks.
-{\bf wf:qp} extracts variables from URL params provieded by cowboy bridge.
-{\bf wf:qc} extracts variables from {\bf \#cx.params} context parsed with
-custom query handler during endpoint initialization usually performed
-inside N2O with something like.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    Ctx = wf:init_context(Req),
-    NewCtx = wf:fold(init,Ctx#cx.handlers,Ctx),
-    wf:context(NewCtx),
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{Render {\bf wf:render} or {\bf nitro:render}}
-Render elements or actions with common render. Rendering is usually
-done automatically inside N2O, when you use DOM or Wiring API, but sometime you may
-need manual render, e.g. in static site generators and other NITRO applications
-which couldn't be even dependent from N2O. For that purposes you may use NITRO API
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > nitro:render(#button{id=id,postback=signal}).
-      <<"<button id=\"id\" type=\"button\"></button>">>
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\paragraph{}
-This is simple sample you may use in static site generators, but in N2O context
-you also may need to manual render JavaScript actions produced during HTML rendering.
-First of all you should know that process in which you want to render should be
-initialized with N2O {\bf \#cx} context. Here is example of JavaScript
-produced during previous {\bf \#button} rendering:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > wf:context(wf:init_context([])).
-      undefined
-
-    > rp(iolist_to_binary(nitro:render(wf:actions()))).
-      <<"{var x=qi('id'); x && x.addEventListener('click',
-      function (event){{ if (validateSources([])) ws.send(
-      enc(tuple(atom('pickle'),bin('id'),bin('g2gCaAVkAAJl
-      dmQABWluZGV4ZAAGc2lnbmFsawACaWRkAAVldmVudGgDYgAABaFi
-      AAbo0GIACnB4'),[tuple(tuple(utf8_toByteArray('id'),b
-      in('detail')),event.detail)])));else console.log('Va
-      lidation Error'); }});};">>
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\paragraph{}
-Here is another more complex example of menu rendering using NITRO DSL:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-   menu(Files,Author) ->
-      #panel{id=navcontainer,body=[#ul{id=nav,body=[
-
-      #li{body=[#link{href="#",body="Navigation"},#ul{body=[
-                #li{body=#link{href="/1.htm",body="Root"}},
-                #li{body=#link{href="../1.htm",body="Parent"}},
-                #li{body=#link{href="1.htm",body="This"}}]}]},
-
-      #li{body=[#link{href="#",body="Download"},#ul{body=[
-                #li{body=#link{href=F,body=F}}|| F <- Files ] }]},
-
-      #li{body=[#link{href="#",body="Translations"},#ul{body=[
-                #li{body=#link{href="#",body=Author}}]}]}]}]}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > rp(iolist_to_binary(wf:render(menu(["1","2"],"5HT")))).
-      <<"<div id=\"navcontainer\"><ul id=\"nav\"><li>
-      <a href=\"#\">Navigation</a><ul><li><a href=\"/
-      1.htm\">Root</a></li><li><a href=\"../1.htm\">P
-      arent</a></li><li><a href=\"1.htm\">This</a></l
-      i></ul></li><li><a href=\"#\">Download</a><ul><
-      li><a href=\"1\">1</a></li><li><a href=\"2\">2<
-      /a></li></ul></li><li><a href=\"#\">Translation
-      s</a><ul><li><a href=\"#\">5HT</a></li></ul></l
-      i></ul></div>">>
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\paragraph{}
-Also notice some helpful functions to preprocess HTML and JavaScript
-escaping to avois XSS attacks:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > wf:html_encode(wf:js_escape("alert('N2O');")).
-    "alert(\\&#39;N2O\\&#39;);"
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Redirects {\bf wf:redirect}}
-Redirects are implemented not with HTTP headers, but with JavaScript action modifying {\bf window.location}.
-This saves login context information which is sent in the first packet upon establishing a WebSocket connection.
-
-\subsection{Session Information {\bf wf:session}}
-Store any session information in ETS tables. Use {\bf wf:user}, {\bf wf:role} for
-login and authorization. Consult {\bf AVZ} library documentation.
-
-\newpage
-\subsection{Bridge information {\bf wf:header} and {\bf wf:cookie}}
-You can read and issue cookie and headers information using internal Web-Server routines.
-You can also read peer IP with {\bf wf:peer}. Usually you do Bridge operations
-inside handlers or endpoints.
-
-\begin{lstlisting}
-    wf:cookies_req(?REQ),
-    wf:cookie_req(Name,Value,Path,TTL,Req)
-\end{lstlisting}
-
-You can set cookies for the page using public cookies API during initial page rendering.
-
-\begin{lstlisting}
-    body() -> wf:cookie("user","Joe"), [].
-\end{lstlisting}
-
-You should use wiring inside WebSocket events:
-
-\begin{lstlisting}
-    event(_) ->
-        wf:wire(wf:f("document.cookie='~s=~s'",["user","Joe"])).
-\end{lstlisting}

+ 0 - 31
doc/book.tex

@@ -1,31 +0,0 @@
-% copyright (c) 2013-2014 Synrc Research Center
-
-\documentclass[8pt,twoside]{article}
-\input{synrc.tex}
-\begin{document}
-\titleWF
-\include{copy}
-
-\tableofcontents
-   \thispagestyle{empty}
-\begin{dedication}
-To Mary and all sentient beings.
-\end{dedication}
-\blankpage
-
-\include{index}
-\include{setup}
-\include{processes}
-\include{endpoints}
-\include{handlers}
-\include{protocols}
-\include{api}
-\include{elements}
-\include{actions}
-\include{macros}
-\include{utf8}
-\include{packages}
-\include{persistence}
-\include{last}
-\end{document}
-

+ 0 - 53
doc/copy.tex

@@ -1,53 +0,0 @@
-%% copyrightpage
-\begingroup
-%\footnotesize
-\topskip 20pt
-\parindent 0pt
-\parskip
-\baselineskip
-
-\begin{tabular}{ll}
-{\bf N2O}: & No Bullshit \\
-    & Sane Framework \\
-    & For Wild Web \\
-\end{tabular}
-\\
-
-SECOND EDITION \\
-
-Book Design and Illustrations by Maxim Sokhatsky \\
-Author Maxim Sokhatsky \\
-
-\begin{tabular}{ll}
-Editors: & Anton Logvinenko \\
-         & Vladimir Kirillov \\
-         & Viktor Sovietov \\
-         & Dmitriy Sukhomlynov \\
-\end{tabular}
-
-Publisher imprint: \\
-Toliman LLC \\
-251 Harvard st. suite 11, Brookline, MA 02446 \\
-1.617.274.0635 \\
-\\
-\\
-\\
-
-
-
-
-Printed in Ukraine \\
-
-Order a copy with worldwide delivery: \\
-https://balovstvo.me/n2o \\
-
-{\bf  ISBN — 978-1-62540-038-3\hspace{2em}}
-
-\begin{tabular}{ll}
-\textcopyright{} 2014 & Toliman \\
-\textcopyright{} 2013-2014 & Synrc Research Center
-\end{tabular}
-
-\endgroup
-
-   \thispagestyle{empty}

+ 0 - 262
doc/elements.tex

@@ -1,262 +0,0 @@
-\section{Elements}
-
-\paragraph{}
-With N2O you don't need to use HTML at all. Instead you define your page
-in the form of Erlang records so that the page is type checked at the compile time.
-This is a classic CGI approach for compiled pages and it gives us all the benefits of
-compile time error checking and provides DSL for client and server-side rendering.
-
-\paragraph{}
-Nitrogen elements, by their nature, are UI control primitives
-that can be used to construct Nitrogen pages with Erlang internal DSL.
-They are compiled into HTML and JavaScript.
-Behavior of all elements is controlled on server-side and all the communication
-between browser and server-side is performed over WebSocket channels.
-Hence there is no need to use POST requests or HTML forms.
-
-\subsection{Static Elements: HTML}
-The core set of HTML elements includes br, headings, links, tables, lists and image tags.
-Static elements are transformed into HTML during rendering.
-
-\paragraph{}
-Static elements could also be used as placeholders for other HTML elements.
-Usually ``static'' means elements that don't use postback parameter:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    #textbox { id=userName, body= <<"Anonymous">> },
-    #panel { id=chatHistory, class=chat_history }
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-This will produce the following HTML code:
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    <input value="Anonymous" id="userName" type="text"/>
-    <div id="chatHistory" class="chat_history"></div>
-\end{lstlisting}
-
-\newpage
-\subsection{Active Elements: HTML and JavaScript}
-There are form elements that provide information for the server
-and gather user input: button, radio and check buttons, text box area and password box.
-Form elements usually allow to assign an Erlang postback handler to specify action behavior.
-These elements are compiled into HTML and JavaScript. For example, during rendering, some
-Actions are converted to JavaScript and sent to be executed in the browser.
-Element definition specifies the list of {\bf source} elements that provide data for event's callback.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    {ok,Pid} = wf:async(fun() -> chat_loop() end),
-    #button { id=sendButton, body= <<"Send">>,
-              postback={chat,Pid}, source=[userName,message] }.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-This will produce the following HTML:
-\begin{lstlisting}
-    <input value="Chat" id="sendButton" type="button"/>
-\end{lstlisting}
-and JavaScript code:
-\begin{lstlisting}
-    $('#sendButton').bind('click',function anonymous(event) {
-        ws.send(Bert.encodebuf({
-            source: Bert.binary('sendButton'),
-            pickle: Bert.binary('g1AAAINQAAAAdX...'),
-            linked: [
-                Bert.tuple(Bert.atom('userName'),
-                utf8.toByteArray($('#userName').val())),
-                Bert.tuple(Bert.atom('message'),
-                utf8.toByteArray($('#message').val()))] })); });
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-If postback action is specified then the page module must include a callback to handle postback info:
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    event({chat,Pid}) ->
-        wf:info(?MODULE, "User ~p Msg ~p",
-                [wf:q(userName),wf:q(message)]).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{Base Element}
-Each HTML element in N2O DSL has record compatibility with the base element.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    #element { ancestor=element,
-               module,
-               id,
-               actions,
-               class=[],
-               style=[],
-               source=[],
-               data_fields=[],
-               aria_states=[],
-               body,
-               role,
-               tabindex,
-               show_if=true,
-               html_tag=Tag,
-               title }.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Here {\bf module} is an Erlang module that contains a render function.
-Data and Aria HTML custom fields are common attributes for all elements.
-In case element name doesn't correspond to HTML tag, {\bf html\_tag} field provided.
-{\bf body} field is used as element contents for all elements.
-
-\paragraph{}
-Most HTML elements are defined as basic elements. You can even choose element's
-name different from its original HTML tag name:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -record(h6,    ?DEFAULT_BASE).
-    -record(tbody, ?DEFAULT_BASE).
-    -record(panel, ?DEFAULT_BASE_TAG(<<"div">>)).
-    -record('div', ?DEFAULT_BASE_TAG(<<"div">>)).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{DTL Template {\bf \#dtl}}
-DTL stands for Django Template Language. A DTL element lets to construct HTML
-snippet from template with given placeholders for further substitution.
-Fields contain substitution bindings proplist, filename and templates folder.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -record(dtl, {?ELEMENT_BASE(element_dtl),
-            file="index",
-            bindings=[],
-            app=web,
-            folder="priv/templates",
-            ext="html",
-            bind_script=true }).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Consider we have {\bf prod.dtl} file in {\bf priv/templates} folder with two
-placeholders \{\{title\}\}, \{\{body\}\} and default placeholder for JavaScript \{\{script\}\}.
-All placeholders except \{\{script\}\} should be specified in \#dtl element.
-Here is an example of how to use it:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    body() -> "HTML Body".
-    main() ->
-      [ #dtl { file="prod", ext="dtl",
-               bindings=[{title,<<"Title">>},{body,body()}]} ].
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-You can use templates not only for pages, but for controls as well. Let's say we want
-to use DTL iterators for constructing list elements:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=table.html]
-    {% for i in items %} <a href="{{i.url}}">{{i.name}}</a><br>
-             {% empty %} <span>No items available :-(</span>
-            {% endfor %}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Here is an example of how to pass variables to the DTL template we've just defined:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    #dtl{file="table", bind_script=false, bindings=[{items,
-      [ {[{name, "Apple"},     {url, "http://apple.com"}]},
-        {[{name, "Google"},    {url, "http://google.com"}]},
-        {[{name, "Microsoft"}, {url, "http://microsoft.com"}]} ]}]}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-bind\_script should be set to true for page templates. When control elements are rendered from DTL,
-bind\_script should be set to false.
-
-\subsection{Button {\bf \#button}}
-
-\paragraph{}
-\begin{lstlisting}
-    -record(button, {?ELEMENT_BASE(element_button),
-            type= <<"button">>,
-            name,
-            value,
-            postback,
-            delegate,
-            disabled}).
-\end{lstlisting}
-
-\paragraph{}
-Sample:
-
-\begin{lstlisting}
-#button { id=sendButton, body= <<"Send">>,
-          postback={chat,Pid}, source=[userName,message] }.
-\end{lstlisting}
-
-\subsection{Link {\bf \#dropdown}}
-
-\begin{lstlisting}
-    -record(dropdown, {?ELEMENT_BASE(element_dropdown),
-            options,
-            postback,
-            delegate,
-            value,
-            multiple=false,
-            disabled=false,
-            name}).
-
-    -record(option, {?ELEMENT_BASE(element_select),
-            label,
-            value,
-            selected=false,
-            disabled}).
-\end{lstlisting}
-
-\paragraph{}
-Sample:
-
-\begin{lstlisting}
-    #dropdown { id=drop,
-                value="2",
-                postback=combo,
-                source=[drop], options=[
-        #option { label= <<"Microsoft">>, value= <<"Windows">> },
-        #option { label= <<"Google">>,    value= <<"Android">> },
-        #option { label= <<"Apple">>,     value= <<"Mac">> }
-    ]},
-\end{lstlisting}
-
-\newpage
-\subsection{Link {\bf \#link}}
-
-\paragraph{}
-\begin{lstlisting}
-    -record(link, {?ELEMENT_BASE(element_link),
-            target,
-            url="javascript:void(0);",
-            postback,
-            delegate,
-            name}).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Text Editor {\bf \#textarea}}
-
-\paragraph{}
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -record(textarea, {?ELEMENT_BASE(element_textarea),
-            placeholder,
-            name,
-            cols,
-            rows,
-            value}).
-\end{lstlisting}
-\vspace{1\baselineskip}

+ 0 - 129
doc/endpoints.tex

@@ -1,129 +0,0 @@
-\section{Endpoints}
-N2O Erlang Processes are instantiated and run by Web Server.
-Depending on Web Server endpoint bindings you can specify
-module for HTTP requests handling.
-
-\paragraph{}
-N2O comes with three endpoint handlers for each Web Server supported.
-However you are not required to use any of these.
-You can implement your own endpoint handlers, e.g. for using with
-Meteor.js or Angular.js and providing Erlang back-end event streaming
-from server-side. Here is an example of using HTTP, WebSocket and
-REST endpoint handlers with Cowboy Web Server.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    {"/rest/:resource",     rest_cowboy, []},
-    {"/rest/:resource/:id", rest_cowboy, []},
-    {"/ws/[...]",           n2o_stream,  []},
-    {'_',                   n2o_cowboy,  []}
-\end{lstlisting}
-
-\subsection{HTML Pages over HTTP}
-This handler is used for serving initial dynamic HTML page.
-In case you are serving static HTML content this handler is
-not included into the running stack. {\bf {n2o}\_{cowboy}} is
-a default HTML page handler.
-
-\paragraph{}
-On initial page load {\bf {n2o}\_{document}:run} of page document endpoint is started.
-During its execution {\bf {wf}\_{render}:render} proceeds
-by calling {\bf Module:main} selected by the routing handler.
-
-\newpage
-\subsection{JavaScript Events over WebSocket}
-JavaScript handler shares the same router information as the
-HTML handler because during its initial phase the same chain
-of N2O handlers is called.
-
-\paragraph{}
-This handler knows how to deal with XHR and WebSocket requests.
-{\bf {n2o}\_{stream}} is a default JavaScript event handler
-based on Bullet library created by Loïc Hoguin, optimized and refined.
-
-\paragraph{}
-You can send several types of events directly from JavaScript
-using various protocols. E.g. you may need to use client protocol:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-  JavaScript> ws.send(enc(tuple(atom('client'),
-                   tuple(atom('phone_auth'),bin("+380..")))));
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-And catch this event at Erlang side:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-  event({client,{phone_auth,Phone}}) ->
-      io:format("Phone: ~p~n",[Phone]).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-You can also send direct messages to event/1, but use it carefully
-because it may violate security rules.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > ws.send(enc(tuple(atom('direct'),atom('init'))));
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-With catching at Erlang side:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    event(init) -> io:format("Init called~n").
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{HTTP API over REST}
-REST handler's request context initialization differs for the one
-used by HTML and JavaScript handlers. N2O handler chains are not
-applied to REST requests. {\bf rest\_cowboy} is a default REST
-handler.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    {"/rest/:resource", rest_cowboy, []},
-    {"/rest/:resource/:id", rest_cowboy, []},
-\end{lstlisting}
-
-\lstset{captionpos=b}
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=users.erl]
-    -module(users).
-    -behaviour(rest).
-    -compile({parse_transform, rest}).
-    -include("users.hrl").
-    -export(?REST_API).
-    -rest_record(user).
-
-    init() -> ets:new(users,
-                    [public, named_table, {keypos, #user.id}]).
-
-    populate(Users) -> ets:insert(users, Users).
-    exists(Id) -> ets:member(users, wf:to_list(Id)).
-    get() -> ets:tab2list(users).
-    get(Id) -> [User] = ets:lookup(users, wf:to_list(Id)), User.
-    delete(Id) -> ets:delete(users, wf:to_list(Id)).
-    post(#user{} = User) -> ets:insert(users, User);
-    post(Data) -> post(from_json(Data, #user{})).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-To add users to in-memory storage perform POST requests:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    curl -i -X POST -d "id=vlad" localhost:8000/rest/users
-    curl -i -X POST -d "id=doxtop" localhost:8000/rest/users
-    curl -i -X GET localhost:8000/rest/users
-    curl -i -X PUT -d "id=5HT" localhost:8000/rest/users/vlad
-    curl -i -X GET localhost:8000/rest/users/5HT
-    curl -i -X DELETE localhost:8000/rest/users/5HT
-\end{lstlisting}
-\vspace{1\baselineskip}
-

+ 0 - 69
doc/handlers.tex

@@ -1,69 +0,0 @@
-
-\section{Handlers}
-HTML and JavaScript Web Server HTTP handlers share the same system
-of context initialization.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    init_context(Req) -> #cx{
-        actions=[], module=index, path=[],
-        req=Req, params=[], session=undefined,
-        handlers= [ {'query', wf:config('query', n2o_query)},
-                    {session, wf:config(session, n2o_session)},
-                    {route,   wf:config(route,   n2o_route)} ]}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Chain of three N2O handlers that are always called
-on each HTTP request. You can redefine any of them or plug your own
-additional handler in the chain to transform web server requests.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=wf:fold/3]
-    fold(Fun,Handlers,Ctx) ->
-        lists:foldl(fun({_,Module},Ctx1) ->
-            {ok,_,NewCtx} = Module:Fun([],Ctx1),
-            NewCtx end,Ctx,Handlers).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Query}
-Query Handler parses URL query and HTTP form information from HTTP request.
-
-\subsection{Session}
-Session Handler manages key-value in-memory database ETS table.
-
-\newpage
-\subsection{Router}
-You can specify routing table with application config:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    {n2o, [{route,n2o_route}]}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Remember that routing handler should be kept very simple because it
-influences overall initial page load latency and HTTP capacity.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -module(n2o_route).
-    -include_lib("n2o/include/wf.hrl").
-    -export(?ROUTING_API).
-
-    finish(S, Cx) -> {ok, S, Cx}.
-    init(S, Cx)   -> P = wf:path(Cx#context.req),
-                     M = prefix(Path),
-                     {ok, S, Cx#cx{path=P,module=M}}.
-
-    prefix(<<"/ws/",P/binary>>) -> route(P);
-    prefix(<<"/",P/binary>>)    -> route(P);
-    prefix(P)                   -> route(P).
-
-    route(<<>>)                 -> index;
-    route(<<"index">>)          -> index;
-    route(<<"login">>)          -> login;
-    route(<<"favicon.ico">>)    -> index;
-    route(_)                    -> index.
-\end{lstlisting}

+ 0 - 90
doc/hevea.sty

@@ -1,90 +0,0 @@
-% hevea  : hevea.sty
-% This is a very basic style file for latex document to be processed
-% with hevea. It contains definitions of LaTeX environment which are
-% processed in a special way by the translator. 
-%  Mostly :
-%     - latexonly, not processed by hevea, processed by latex.
-%     - htmlonly , the reverse.
-%     - rawhtml,  to include raw HTML in hevea output.
-%     - toimage, to send text to the image file.
-% The package also provides hevea logos, html related commands (ahref
-% etc.), void cutting and image commands.
-\NeedsTeXFormat{LaTeX2e}
-\ProvidesPackage{hevea}[2002/01/11]
-\RequirePackage{comment}
-\newif\ifhevea\heveafalse
-\@ifundefined{ifimagen}{\newif\ifimagen\imagenfalse}
-\makeatletter%
-\newcommand{\heveasmup}[2]{%
-\raise #1\hbox{$\m@th$%
-  \csname S@\f@size\endcsname
-  \fontsize\sf@size 0%
-  \math@fontsfalse\selectfont
-#2%
-}}%
-\DeclareRobustCommand{\hevea}{H\kern-.15em\heveasmup{.2ex}{E}\kern-.15emV\kern-.15em\heveasmup{.2ex}{E}\kern-.15emA}%
-\DeclareRobustCommand{\hacha}{H\kern-.15em\heveasmup{.2ex}{A}\kern-.15emC\kern-.1em\heveasmup{.2ex}{H}\kern-.15emA}%
-\DeclareRobustCommand{\html}{\protect\heveasmup{0.ex}{HTML}}
-%%%%%%%%% Hyperlinks hevea style
-\newcommand{\ahref}[2]{{#2}}
-\newcommand{\ahrefloc}[2]{{#2}}
-\newcommand{\aname}[2]{{#2}}
-\newcommand{\ahrefurl}[1]{\texttt{#1}}
-\newcommand{\footahref}[2]{#2\footnote{\texttt{#1}}}
-\newcommand{\mailto}[1]{\texttt{#1}}
-\newcommand{\imgsrc}[2][]{}
-\newcommand{\home}[1]{\protect\raisebox{-.75ex}{\char126}#1}
-\AtBeginDocument
-{\@ifundefined{url}
-{%url package is not loaded
-\let\url\ahref\let\oneurl\ahrefurl\let\footurl\footahref}
-{}}
-%% Void cutting instructions
-\newcounter{cuttingdepth}
-\newcommand{\tocnumber}{}
-\newcommand{\notocnumber}{}
-\newcommand{\cuttingunit}{}
-\newcommand{\cutdef}[2][]{}
-\newcommand{\cuthere}[2]{}
-\newcommand{\cutend}{}
-\newcommand{\htmlhead}[1]{}
-\newcommand{\htmlfoot}[1]{}
-\newcommand{\htmlprefix}[1]{}
-\newenvironment{cutflow}[1]{}{}
-\newcommand{\cutname}[1]{}
-\newcommand{\toplinks}[3]{}
-\newcommand{\setlinkstext}[3]{}
-\newcommand{\flushdef}[1]{}
-\newcommand{\footnoteflush}[1]{}
-%%%% Html only
-\excludecomment{rawhtml}
-\newcommand{\rawhtmlinput}[1]{}
-\excludecomment{htmlonly}
-%%%% Latex only
-\newenvironment{latexonly}{}{}
-\newenvironment{verblatex}{}{}
-%%%% Image file stuff
-\def\toimage{\endgroup}
-\def\endtoimage{\begingroup\def\@currenvir{toimage}}
-\def\verbimage{\endgroup}
-\def\endverbimage{\begingroup\def\@currenvir{verbimage}}
-\newcommand{\imageflush}[1][]{}
-%%% Bgcolor definition
-\newsavebox{\@bgcolorbin}
-\newenvironment{bgcolor}[2][]
-  {\newcommand{\@mycolor}{#2}\begin{lrbox}{\@bgcolorbin}\vbox\bgroup}
-  {\egroup\end{lrbox}%
-   \begin{flushleft}%
-   \colorbox{\@mycolor}{\usebox{\@bgcolorbin}}%
-   \end{flushleft}}
-%%% Style sheets macros, defined as no-ops
-\newcommand{\newstyle}[2]{}
-\newcommand{\addstyle}[1]{}
-\newcommand{\setenvclass}[2]{}
-\newcommand{\getenvclass}[1]{}
-\newcommand{\loadcssfile}[1]{}
-\newenvironment{divstyle}[1]{}{}
-\newenvironment{cellstyle}[2]{}{}
-\newif\ifexternalcss
-%%% Postlude
-\makeatother

BIN
doc/images/connections.png


BIN
doc/images/n2o-book.png


BIN
doc/images/n2o-proto.png


BIN
doc/images/n2o_benchmark.png


BIN
doc/images/n2o_protocols.png


BIN
doc/images/page-lifetime.png


+ 0 - 11
doc/images/page-lifetime.uml

@@ -1,11 +0,0 @@
-title N2O Page Lifetime
-
-Browser->+HTTP: HTTP GET
-HTTP->+Transition Proc: Store Actions
-HTTP->-Browser: Rendered Elements (HTML)
-Browser->+WebSocket: WS INIT
-WebSocket->Transition Proc: Transition ACK, Get Actions
-Transition Proc->-WebSocket: Actions
-WebSocket->-Browser: Rendered Actions (JavaScript), WS INIT DONE
-Browser->+WebSocket: Click Event
-WebSocket->-Browser: Rendered Elements (HTML) + Actions (JavaScript)

BIN
doc/images/static-serving.png


BIN
doc/images/wheel.png


+ 0 - 201
doc/index.tex

@@ -1,201 +0,0 @@
-\section{N2O: Application Server}
-
-N2O was started as the first Erlang Web Framework
-that uses WebSocket protocol only. We saved great compatibility with Nitrogen
-and added many improvements, such as binary page construction,
-binary data transfer, minimized process spawns, transmission of all events over the WebSocket
-and work within Cowboy processes. N2O renders pages several times faster than Nitrogen.
-
-\subsection{Wide Coverage}
-N2O is unusual in that it solves problems in different web development domains
-and stays small and concise at the same time. Started as a Nitrogen concept
-of server-side framework it can also build offline client-side applications
-using the same source code. This became possible with powerful Erlang JavaScript Parse
-Transform which enables running Erlang on JavaScript platform and brings in Erlang and JavaScript
-interoperability. You can use Elixir, LFE and Joxa languages for backend development as well.
-
-\paragraph{}
-N2O supports DSL and HTML templates. It lets you build JavaScript
-control elements in Erlang and perform inline rendering with DSL using
-the same code base for both client and server-side.
-How to use N2O is up to you. You can build mobile applications using server-side rendering
-for both HTML and JavaScript thus reducing CPU cycles and saving the battery of a mobile device.
-Or you can create rich offline desktop applications using Erlang JavaScript compiler.
-
-\newpage
-\subsection*{Why Erlang in Web?}
-We have benchmarked all the existing modern web frameworks that were built using functional
-languages and Cowboy was still the winner. The chart below shows raw HTTP
-performance of functional and C-based languages with concurrent
-primitives (Go, D and Rust) on a VAIO Z notebook with i7640M processor.
-
-\includeimage{n2o_benchmark.png}{Web-Servers raw performance grand congregation}
-
-\paragraph{}
-Erlang was built for low latency streaming of binary data in telecom systems.
-It's fundamental design goal included high manageability, scalability
-and extreme concurrency. Thinking of WebSocket channels as binary
-telecom streams and web pages as user binary sessions
-helps to get an understanding reasons behind choosing Erlang
-over other alternatives for web development.
-
-\paragraph{}
-Using Erlang for web allows you to unleash the full power of telecom systems for
-building web-scale, event-driven, message-passing, NoSQL, asynchronous, non-blocking,
-reliable, highly-available, performant, secure, real-time, distributed applications.
-See Erlang: The Movie II.
-
-\paragraph{}
-N2O outperforms full Nitrogen stack with only 2X raw HTTP Cowboy
-performance downgrade thus upgrading rendering performance several
-times compared to any other functional web framework. And
-sure it's faster than raw HTTP performance of Node.js.
-
-\subsection{Rich and Lightweight Applications}
-There are two approaches for designing client/server communication.
-The first one is called 'data-on-wire'. With this approach only JSON, XML or binary
-data are transferred over RPC and REST channels. All HTML rendering
-is performed on the client-side. This is the most suitable approach for building desktop
-applications. Examples include React, Meteor and ClojureScript.
-This approach can also be used for building mobile clients.
-
-\paragraph{}
-Another approach is sending pre-rendered parts of pages and JS
-and then replacing HTML and executing JavaScript on the client-side. This approach
-is better suited for mobile web development since the
-client doesn't have much resources.
-
-\paragraph{}
-With N2O you can create both types of applications. You can use N2O REST framework
-for desktop applications based on Cowboy REST API along with DTL
-templates for initial HTML rendering for mobile applications.
-You can also use Nitrogen DSL-based approach for modeling parts of pages
-as widgets and control elements, thanks to Nitrogen
-rich collection of elements provided by Nitrogen community.
-
-\paragraph{}
-In cases when your system is built around Erlang infrastructure, N2O
-is the best choice for fast web prototyping, bringing simplicity
-of use and clean codebase. Despite HTML being transfered over the wire,
-you still have access to all your Erlang services directly.
-
-\paragraph{}
-You can also create offline applications using Erlang JavaScript compiler
-just the way you would use ClojureScript, Scala.js, Elm, WebSharper
-or any other similar tool. N2O includes: REST micro frameworks,
-server-side and client-side rendering engines,
-WebSocket events streaming, JavaScript generation
-and JavaScript macro system along with {\bf AVZ} authorization
-library (Facebook, Google, Twitter, Github, Microsoft), key-value storages
-access library {\bf KVS} and {\bf MQS} Message Bus client library (gproc, emqttd).
-
-\subsection{JSON and BERT}
-N2O uses JSON and BERT. All messages passed over
-WebSockets are encoded in native Erlang External Term Format.
-It is easy to parse it in JavaScript with {\bf dec(msg)}
-and it helps to avoid complexity on the server-side. Please refer
-to \footahref{http://bert-rpc.org}{http://bert-rpc.org} for detailed information.
-
-\subsection{DSL and Templates}
-We like Nitrogen for the simple and elegant way it constructs typed
-HTML with internal DSL. This is analogous to Scala Lift,
-OCaml Ocsigen and Haskell Blaze approach. It lets you develop reusable control
-elements and components in the host language.
-
-\paragraph{}
-Template-based approach (Yesod, ASP, PHP, JSP, Rails, Yaws and ChicagoBoss)
-requires developers to deal with raw HTML. It allows
-defining pages in terms of top-level controls, placeholders
-and panels. N2O also support this approach by proving bindings
-to DTL and ET template engines.
-
-\paragraph{}
-The main N2O advantage is its suitability for large-scale projects
-without sacrificing simplicity and comfort of prototyping solutions
-in fast and dynamic manner. Below is an example of complete Web Chat
-implementation using WebSockets that shows how  Templates, DSL and
-asynchronous inter-process communication work in N2O.
-
-\newpage
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=chat.erl]
-    -module(chat).
-    -include_lib("nitro/include/nitro.hrl").
-    -compile(export_all).
-
-    main() ->
-       #dtl { file     = "login",
-              app      = review,
-              bindings = [ { body, body() } ] }.
-
-    body() ->
-      [ #span    { id=title,       body="Your nickname: " },
-        #textbox { id=user,        body="Anonymous" },
-        #panel   { id=history },
-        #textbox { id=message },
-        #button  { id=send,        source=[user,message],
-                                   body="Send",
-                                   postback=chat } ].
-
-    event(init) -> wf:reg(room), wf:async("looper",fun loop/1);
-    event(chat) -> User    = wf:q(user),
-                   Message = wf:q(message),
-                   n2o_async:send("looper",{chat,User,Message}).
-
-    loop({chat,User,Message}) ->
-        Terms = #panel { body = [
-                #span  { body = User }, ": ",
-                #span  { body = Message } ]},
-        wf:insert_bottom(history, Terms),
-        wf:flush(room).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Just try to build the similar functionality with your favorite
-language/framework and feel the difference! Here are one message bus,
-one async {\bf gen\_server} worker under supervision, NITRO DSL, DTL template,
-WebSockets, HTML and JavaScript generation in a simple file that you can
-put in your N2O application directory tree without restart and
-manual compilation. Also you can create single-file bundle
-which is able to run in Windows, Linux and Mac. Moreover this
-application is ready to run under multiplatform LING Erlang virtual machine.
-
-\newpage
-\subsection*{Changes from Nitrogen}
-We took a liberty to break some compatibility with the original
-Nitrogen framework, mostly because we wanted to have a clean codebase
-and achieve better performance. However, it's still possible to port
-Nitrogen web sites to N2O quite easily. E.g., N2O returns id and
-class semantics of HTML and not {\bf html\_id}.
-We simplified HTML rendering without using
-{\bf html\_encode} which should be handled by application layer.
-
-\paragraph{}
-Nitrogen.js, originally created by Rusty Klophaus, was removed
-because of the pure WebSocket nature of N2O which doesn't
-require jQuery on the client-side anymore. In terms of lines of code
-we have impressive showing. New {\bf xhr.js} 25 LOC and {\bf bullet.js} 18 LOC
-was added as the replacement, also {\bf nitrogen.js} takes only 45 LOC.
-UTF-8 {\bf utf8.js} 38 LOC could be plugged separately only when you're
-using {\bf bert.js} 200 LOC formatter. {\bf n2o.js} protocol handler is about 20 LOC.
-
-\paragraph{}
-We also removed {\bf simple\_bridge} and optimized N2O on each level to
-unlock maximum performance and simplicity. We hope you will enjoy
-using N2O. We are fully convinced it is the most efficient way to
-build Web applications in Erlang.
-
-\paragraph{}
-Original Nitrogen was already tested in production under high load and we
-decided to remove {\bf nprocreg} process registry along
-with {\bf action\_comet} heavy process creation. N2O creates a single
-process for an async WebSocket handler, all operations
- are handled within Cowboy processes.
-
-\paragraph{}
-Also, we introduced new levels of abstraction. You can extend
-the set of available protocols (Nitrogen, Heartbeat, Binary),
-change protocol formatters to BERT, JSON or MessagePack, inject
-your code on almost any level. The code structure
-is clean and Nitrogen compatibility layer NITRO is fully detachable
-from N2O and lives in a separate {\bf synrc/nitro} application.

+ 0 - 168
doc/last.tex

@@ -1,168 +0,0 @@
-\begingroup
-
-\section{History}
-
-\paragraph{}
-The N2O was born in 2013 in spring. It's started as a process of
-reimplementation of Nitrogen Web Framework behavior for better
-performance and code reducing. The initial version had its own
-render core along with pure websocket nature of the IO protocol.
-
-\paragraph{}
-First official release of N2O was made in October 2013 when
-N2O was presented as one having AES/CBC pickling,
-REST transformations, own TeX handbook and
-JavaScript compiler. It is also known as version 0.10.
-
-\paragraph{}
-In this minor release BERT transformations mainly were improved using parse\_transform.
-Was introduced ETS caching. Tiny 50 LOC Makefile called {\bf otp.mk} was
-suggested for easy production deployment. It's still best option to deploy
- applications. It was release 0.11.
-
-\paragraph{}
-In January 2014 release xen hosting in LING VM
-was initially introduced. Dependencies
-start to freezing; asset and deploy options were improved.
-
-\paragraph{}
-April 2014 release was a giving hand to pure
-JavaScript SPA applications. Now pages could be served
-in nginx behind Erlang cowboy web server. Initial version of
-N2O protocol was introduced in this release. New twitter-format
-stack trace messages was added for error reporting. {\bf bert.js}
-was rewritten and jQuery was removed in this release. In 1.4 release
-was also introduced unified logging schema for KVS and N2O. And main
-WebSocket endpoint was totally rewritten to support N2O protocol.
-
-\paragraph{}
-The release of May 2014 is still supported. In this release
-new build tool {\bf mad} was initially introduced. Version 1.5.
-
-\newpage
-\paragraph{}
-August 2014 version 1.8 received new cookie session manager
-synchronized with ETS table where all entries zipped with session keys.
-Client binary requests was made to exists in {\bf bin} sub-protocol.
-KVS was first added to sample application in this release.
-Full HTML elements and attributes were added, which caused the growth of
-the nitrogen DSL size to the size of N2O.
-
-\paragraph{}
-September 2014 release was numbered 1.9.
-New client side protocol pipeline along with new {\bf n2o.js}.
-For mad was issued new dynamic loader
-which is able to host working directory inside ETS table and readable
-from erlang executable script on Windows, Linux and Mac. UTF-8 support
-was optimized in {\bf utf8.js}. New experimental {\bf rails} protocol and {\bf crashdump.io}
-logging backend module were added in version 1.9.
-
-\paragraph{}
-October 2014 version 1.10 was minor again. The only message in changelog
-were added: "nothing special". The first malfunction bug which was fixed is the
-racing which happened during async DOM bulding. Yes, N2O is faster than browser.
-
-\paragraph{}
-January 2015 version 2.1. Major Release. N2O book from now
-on can be purchased in a hardcover print. For business
-applications validations were introduced. {\bf n2o.js}, {\bf binary.js}, {\bf nitrogen.js},
-{\bf template.js} were slightly optimized. KJELL color support from now on enabled in
-new {\bf review} sample application.
-Log level support and several field and racing fixes in HTML elements.
-
-\paragraph{}
-March 2015 version 2.3. Initial Haskell implentation of N2O server is introduced.
-New N2O WebSocket protocol specification for all stack of {\bf synrc} and {\bf spawnproc} applications.
-New auto-expiring cookie-based session and cache managers. Revised and more sane XHR fallback.
-Automatic language detection from routes in context.
-Several element fixes and latest Cowboy 1.0.1.
-
-\newpage
-\begin{lstlisting}[caption=Bootstraping in a minute]
-
-  $ ./mad app sample
-  Create File: "sample/sys.config"
-  Create File: "sample/apps/sample/priv/static/synrc.css"
-  Create File: "sample/apps/sample/src/web_app.erl"
-  Create File: "sample/apps/rebar.config"
-  Create File: "sample/apps/sample/rebar.config"
-  Create File: "sample/apps/sample/src/sample.app.src"
-  Create File: "sample/apps/sample/src/index.erl"
-  Create File: "sample/apps/sample/src/web_sup.erl"
-  Create File: "sample/apps/sample/priv/static/spa/index.htm"
-  Create File: "sample/rebar.config"
-  Create File: "sample/apps/sample/priv/templates/index.html"
-  Create File: "sample/apps/sample/src/routes.erl"
-  $ cd sample
-  $ time ./mad dep com pla
-  ...
-  Ordered: [kernel,stdlib,fs,cowlib,crypto,
-            compiler,syntax_tools,ranch,gproc,
-            cowboy,erlydtl,n2o,sample,active,mad,sh]
-
-  real    0m41.901s
-  user    0m17.785s
-  sys 0m5.108s
-  $ ./mad rep
-  Configuration: [{n2o,[{port,8000},
-                        {route,routes},
-                        {log_modules,web_app}]},
-                  {kvs,[{dba,store_mnesia},
-                        {schema,[kvs_user,
-                                 kvs_acl,kvs_feed,
-                                 kvs_subscription]}]}]
-  Applications: [kernel,stdlib,fs,cowlib,crypto,
-                 compiler,syntax_tools,ranch,
-                 gproc,cowboy,erlydtl,n2o,
-                 sample,active,mad,sh]
-
-  Erlang/OTP 17 [erts-6.2] [source] [64-bit] [smp:4:4]
-         [async-threads:10] [hipe] [kernel-poll:false]
-
-  Eshell V6.2  (abort with ^G)
-  1>
-\end{lstlisting}
-
-\paragraph{}
-N2O is fast energy efficient binary protocol for IoT and WebSocket applications.
-I hope you will find this retrospective useful in your discovering of N2O.
-
-\newpage
-\section{Afterword}
-
-Hope you find \footahref{http://synrc.com/apps/n2o}{N2O},
-\footahref{http://synrc.com/apps/kvs}{KVS}, and
-\footahref{http://synrc.com/apps/mad}{MAD} stack small and concise,
-because it was the main goal during development.
-We stay with minimal viable functionality criteria.
-
-\paragraph{}
-N2O is free from unnecessary layers and code calls as much as possible.
-At the same time it covers all your needs to build
-flexible web messaging relays using rich stack of protocols.
-
-\paragraph{}
-Minimalistic criteria allows you to see the system's
-most general representation, which drives you to describe efficiently.
-You could be more productive by focusing on core.
-Erlang N2O and companion libraries altogether make
-your life managing web applications easy without
-efforts due to its naturally compact and simple design, and absence of code bloat.
-
-\paragraph{}
-You can see that parse\_transform is very useful, especially in JavaScript
-protocol generation (SHEN) and REST record-to-proplist generators. So having
-quote/unquote in language would be very useful. Fast and small
-Erlang Lisp (LOL) is expecting compiler is this field as universal
-Lisp-based macro system.
-
-\paragraph{}
-All apps in stack operate on its own DSL records-based language:
-N2O --- \#action/\#element; KVS --- \#iterator/\#container.
-This language is accessible directly from Erlang-based languages: Joxa, Elixir, Erlang, Lol.
-
-\paragraph{}
-We hope that this book will guide you in the wild world of Erlang web development
-and you will be enlightened by its minimalistic power.
-
-\endgroup

+ 0 - 125
doc/macros.tex

@@ -1,125 +0,0 @@
-\section{JavaScript Compiler}
-
-\subsection{Compilation and Macros}
-Erlang JavaScript/OTP Parse Transform has two modes defined
-by {\bf \-jsmacro} and {\bf \-js} Erlang module attributes.
-The first mode precompiles Erlang module functions
-into JavaScript strings. The second one exports Erlang functions
-into a separate JavaScript file ready to run in the browser or Node.js.
-
-\paragraph{}
-Sample usage of {\bf \-jsmacro} and {\bf \-js}:
-
-\begin{lstlisting}
-    -module(sample).
-    -compile({parse_transform, shen}).
-    -jsmacro([tabshow/0,doc_ready/1,event/3]).
-    -js(doc_ready/1).
-\end{lstlisting}
-
-\subsection{Erlang Macro Functions}
-Macro functions are useful for using N2O as a server-side framework.
-Functions get rewritten during Erlang compilation into a JavaScript format
-string ready for embedding. Here is an example from N2O pages:
-
-\begin{lstlisting}
-    tabshow() ->
-        X = jq("a[data-toggle=tab]"),
-        X:on("show",
-            fun(E) -> T = jq(E:at("target")),
-            tabshow(T:attr("href")) end).
-
-    doc_ready(E) ->
-        D = jq(document),
-        D:ready(fun() ->
-            T = jq("a[href=\"#" ++ E ++ "\"]"),
-            T:tab("show") end).
-
-    event(A,B,C) ->
-        ws:send('Bert':encodebuf(
-            [{source,'Bert':binary(A)}, {x,C},
-             {pickle,'Bert':binary(B)}, {linked,C}])).
-
-    main() ->
-        Script1 = tabshow(),
-        Script2 = event(1, 2, 3),
-        Script3 = doc_ready(wf:js_list("tab")),
-        io:format("tabshow/0:~n~s~nevent/3:~n~s~ndoc_ready/1:~n~s~n",
-            [Script1,Script2,Script3]).
-\end{lstlisting}
-
-Perform compilation and run tests:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-        $ erlc sample.erl
-        $ erl
-        > sample:main().
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-You'll get the following output:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    tabshow/0:
-        var x = $('a[data-toggle=tab]');
-        x.on('show',function(e) {
-            var t = $(e['target']);
-            return tabshow(t.attr('href'));
-        });
-
-    event/3:
-        ws.send(Bert.encodebuf({source:Bert.binary(1),
-                                x:3,
-                                pickle:Bert.binary(2),
-                                linked:3}));
-
-    doc_ready/1:
-    var d = $(document);
-    d.ready(function() {
-        var t = $('a[href="#' + 'tab' + '"]');
-        return t.tab('show');
-    });
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-As you see, no source-map needed.
-
-\subsection{JavaScript File Compilation}
-Export Erlang function to JavaScript file with {\bf -js([sample/0,fun\_{args}/2])}.
-You could include functions for both {\bf macro} and {\bf js} definitions.
-
-\newpage
-\subsection{Mapping Erlang/OTP to JavaScript/OTP}
-Following OTP libraries are partially supported in Erlang JavaScript Parse Transform:
-{\bf lists}, {\bf proplists}, {\bf queue}, {\bf string}.
-
-\paragraph{\bf Example 1}\
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    S = lists:map(fun(X) -> X * X end,[1,2,3,4]),
-\end{lstlisting}
-
-transforms to:
-
-\begin{lstlisting}
-    s = [1,2,3,4].map(function(x) {
-        return x * x;
-    });
-\end{lstlisting}
-
-\paragraph{\bf Example 2}\
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    M = lists:foldl(fun(X, Acc) -> Acc + X end,0,[1,2,3,4]),
-\end{lstlisting}
-
-transforms to:
-
-\begin{lstlisting}
-    m = [1,2,3,4].reduce(function(x,acc) {
-        return acc + x;
-    },0);
-\end{lstlisting}

+ 0 - 167
doc/packages.tex

@@ -1,167 +0,0 @@
-\section{MAD: Build and Packaging Tool}
-
-\subsection{History}
-
-We came to conclusion that no matter how perfect your libraries are,
-the comfort and ease come mostly from development tools.
-Everything got started when \footahref{https://github.com/proger}{Vladimir~Kirillov} decided to
-replace Rusty's sync beam reloader. As you know sync uses
-filesystem polling which is neither energy-efficient nor elegant. Also
-sync is only able to recompile separate modules, while
-common use-case in N2O is to recompile DTL templates
-and LESS/SCSS stylesheets. That is why we need to recompile
-the whole project. That's the story how \footahref{https://github.com/synrc/active}{active} emerged.
-Under the hood active is a client subscriber
-of \footahref{https://github.com/synrc/fs}{fs} library, native filesystem listener for Linux, Windows and Mac.
-
-\paragraph{}
-De-facto standard in Erlang world is rebar.
-We love rebar interface despite its implementation.
-First we plugged rebar into active and then decided to drop its support,
-it was slow, especially in cold recompilation.
-Rebar was designed to be a stand-alone tool, so it has some
-glitches while using as embedded library.
-Later we switched to Makefile-based build tool \footahref{https://github.com/synrc/otp.mk}{otp.mk}.
-
-\paragraph{}
-The idea to build rebar replacement was up in the air for a long time.
-The best minimal approach was picked up by \footahref{https://github.com/s1n4}{Sina~Samavati},
-who implemented the first prototype called 'mad'. Initially mad
-was able to compile DTL templates, YECC files, escript (like
-bundled in gproc), and it also had support for caching with side-effects.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=Example of building N2O sample]
-                                   Cold       Hot
-    rebar get-deps compile         53.156s    4.714s
-    mad deps compile               54.097s    0.899s
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=Example of building Cowboy]
-                                   Hot
-    make (erlang.mk)               2.588s
-    mad compile                    2.521s
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Introduction}
-
-We were trying to make something minimalistic that fits out \footahref{https://github.com/synrc}{Web Stack}.
-Besides we wanted to use our knowledge of other build tools like lein, sbt etc.
-Also for sure we tried sinan, ebt, Makefile-based scripts.
-
-Synrc mad has a simple interface as follows:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-  BNF:
-      invoke := mad params
-      params := [] | run params
-         run := command [ options ]
-     command := app | lib | deps | compile | bundle
-                start | stop | repl
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-It seems to us more natural, you can specify random
-command sets with different specifiers (options).
-
-\subsection{Single-File Bundling}
-
-The key feature of mad is ability to create single-file bundled web sites.
-Thus making dream to boot simpler than Node.js come true.
-This target escript is ready for run on Windows, Linux and Mac.
-
-\paragraph{}
-To make this possible we implemented a zip filesytem inside escript.
-mad packages priv directories along with ebin and configs.
-You can redefine each file in zip fs inside target
-escript by creating the copy with the same path locally near escript.
-After launch all files are copied to ETS.
-N2O also comes with custom cowboy static handler that is able to
-read static files from this cached ETS filesystem.
-Also bundles are compatible with active online realoading and recompilation.
-
-\subsection{Templates}
-
-mad also comes with N2O templates. So you can bootstrap an N2O-based site
-just having a single copy of mad binary.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    # mad app sample
-    # cd sample
-    # mad deps compile plan bundle sample
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-After that you can just run escript web\_app under Windows, Linux and
-Mac and open \footahref{http://localhost:8000}{http://localhost:8000}.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-C:\> escript sample
-Applications: [kernel,stdlib,crypto,cowlib,ranch,cowboy,compiler,
-               syntax_tools,erlydtl,gproc,xmerl,n2o,sample,
-               fs,active,mad,sh]
-Configuration: [{n2o,[{port,8000},{route,routes}]},
-                {kvs,[{dba,store_mnesia},
-                      {schema,[kvs_user,kvs_acl,kvs_feed,
-                               kvs_subscription]}]}]
-Erlang/OTP 17 [erts-6.0] [64-bit] [smp:4:4] [async-threads:10]
-
-Eshell V6.0  (abort with ^G)
-1>
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Deploy}
-
-mad is also supposed to be a deploy tool with ability to
-deploy not only to our resources like Erlang on Xen, Voxoz (LXC/Xen) but
-also to Heroku and others.
-
-\subsection{OTP Compliant}
-
-mad supports rebar umbrella project structure.
-Specifically two kinds of directory layouts:
-
-\begin{lstlisting}[caption=Solution]
-    apps
-    deps
-    rebar.config
-    sys.config
-\end{lstlisting}
-
-\begin{lstlisting}[caption=OTP Application]
-    deps
-    ebin
-    include
-    priv
-    src
-    rebar.config
-\end{lstlisting}
-
-\subsection{Apps Ordering}
-
-As you may know, you can create OTP releases with
-reltool (rebar generate) or systools (relx). mad currently
-creates releases with relx but is going to do it independently soon.
-Now it can only order applications.
-
-\begin{lstlisting}
-    # mad plan
-    Ordered: [kernel,stdlib,mnesia,kvs,crypto,cowlib,ranch,
-              cowboy,compiler,syntax_tools,erlydtl,gproc,
-              xmerl,n2o,n2o_sample,fs,active,mad,rest,sh]
-\end{lstlisting}
-
-And the good part about mad is it's size:
-
-\begin{lstlisting}
-                      Sources        Binary
-    mad               567 LOC        39 KB
-    rebar             7717 LOC       181 KB
-\end{lstlisting}

+ 0 - 240
doc/persistence.tex

@@ -1,240 +0,0 @@
-\section{KVS: Abstract Erlang Database}
-
-KVS is an Erlang abstraction over various native Erlang key-value databases,
-like Mnesia. Its meta-schema includes only concept
-of iterators (persisted linked lists) that are locked or guarded by
-containers (list head pointers). All write operations to the list are
-serialized using a single Erlang process to provide sequential consistency. The application
-which starts Erlang processes per container called \footahref{https://github.com/synrc/feeds}{feeds}.
-
-\paragraph{}
-The best use-case for KVS and key-value storages is to store operational data.
-This data should be later fed to SQL data warehouses for analysis. Operational data
-stores should be scalable, secure, fault-tolerant and available. That is why
-we store work-in-progress data in key-value storages.
-
-\paragraph{}
-KVS also supports queries that require secondary indexes, which
-are not supported by all backends.
-Currently KVS includes following storage backends: Mnesia, Riak and \footahref{https://github.com/synrc/kai}{KAI}.
-
-\subsection{Polymorphic Records}
-
-Any data in KVS is represented by regular Erlang records.
-The first element of the tuple as usual indicates the name of bucket.
-The second element usually corresponds to the index key field.
-
-\begin{lstlisting}
-            Rec = {user,"maxim@synrc.com",[]}.
-
-     RecordName = element(1, Rec).
-             Id = element(2, Rec).
-\end{lstlisting}
-
-\newpage
-\subsection{Iterators}
-
-Iterator is a sequence of fields used as interface for all tables
-represented as doubly-linked lists. It defines id, next, prev,
-feed\_id fields. This fields should be at the beginning of user's record,
-because KVS core is accessing relative position of the
-field (like \#iterator.next) with setelement/element BIF, e.g.
-
-\begin{lstlisting}
-    setelement(#iterator.next, Record, NewValue).
-\end{lstlisting}
-
-All records could be chained into the double-linked lists in the database.
-So you can inherit from the ITERATOR record just like that:
-
-\begin{lstlisting}
-    -record(access, {?ITERATOR(acl),
-        entry_id,
-        acl_id,
-        accessor,
-        action}).
-\end{lstlisting}
-
-\begin{lstlisting}
-    #iterator { record_name,
-                id,
-                version,
-                container,
-                feed_id,
-                prev,
-                next,
-                feeds,
-                guard }
-\end{lstlisting}
-
-This means your table will support add/remove linked list operations to lists.
-
-\begin{lstlisting}
-    1> kvs:add(#user{id="mes@ua.fm"}).
-    2> kvs:add(#user{id="dox@ua.fm"}).
-\end{lstlisting}
-
-Read the chain (undefined means all)
-
-\begin{lstlisting}
-    3> kvs:entries(kvs:get(feed, user), user, undefined).
-    [#user{id="mes@ua.fm"},#user{id="dox@ua.fm"}]
-\end{lstlisting}
-
-or just
-
-\begin{lstlisting}
-    4> kvs:entries(user).
-    [#user{id="mes@ua.fm"},#user{id="dox@ua.fm"}]
-\end{lstlisting}
-
-Read flat values by all keys from table:
-
-\begin{lstlisting}
-    4> kvs:all(user).
-    [#user{id="mes@ua.fm"},#user{id="dox@ua.fm"}]
-\end{lstlisting}
-
-\subsection{Containers}
-
-If you are using iterators records this automatically
-means you are using containers. Containers are just boxes
-for storing top/heads of the linked lists. Here is layout
-of containers:
-
-\begin{lstlisting}
-    #container { record_name,
-                 id,
-                 top,
-                 entries_count }
-\end{lstlisting}
-
-\subsection{Extending Schema}
-
-Usually you only need to specify custom Mnesia indexes and tables tuning.
-Riak and KAI backends don't need it. Group your table into table packages
-represented as modules with handle\_notice API.
-
-\begin{lstlisting}
-    -module(kvs_feed).
-    -inclue_lib("kvs/include/kvs.hrl").
-
-    metainfo() ->
-        #schema{name=kvs,tables=[
-
-            #table{ name = feed, container = true,
-                    fields = record_info(fields,feed)},
-
-            #table{ name = entry, container = feed,
-                    fields = record_info(fields,entry),
-                    keys = [feed_id,entry_id,from] },
-
-            #table{ name = comment, container = feed,
-                    fields = record_info(fields,comment),
-                    keys = [entry_id,author_id] } ]}.
-\end{lstlisting}
-
-And plug it into schema sys.config:
-
-\begin{lstlisting}
-    {kvs, {schema,[kvs_user,kvs_acl,kvs_feed,kvs_subscription]}},
-\end{lstlisting}
-
-After run you can create schema on local node with:
-
-\begin{lstlisting}
-    1> kvs:join().
-\end{lstlisting}
-
-It will create your custom schema.
-
-\subsection{KVS API}
-
-\subsection{Service}
-System functions for start and stop service:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -spec start() -> ok | {error,any()}.
-    -spec stop() -> stopped.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Schema Change}
-This API allows you to create, initialize and destroy the database schema.
-Depending on database the format and/or feature set may differ. {\bf join/1} function
-is used to initialize database, replicated from remote node along with its schema.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -spec destroy() -> ok.
-    -spec join() -> ok | {error,any()}.
-    -spec join(string()) -> [{atom(),any()}].
-    -spec init(atom(), atom()) -> list(#table{}).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Meta Info}
-This API allows you to build forms from table metainfo.
-You can also use this API for metainfo introspection.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -spec modules() -> list(atom()).
-    -spec containers() -> list(tuple(atom(),list(atom()))).
-    -spec tables() -> list(#table{}).
-    -spec table(atom()) -> #table{}.
-    -spec version() -> {version,string()}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Chain Ops}
-This API allows you to modify the data, chained lists.
-You can use {\bf create/1} to create the container.
-You can add and remove nodes from lists.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -spec create(atom()) -> integer().
-    -spec remove(tuple()) -> ok | {error,any()}.
-    -spec remove(atom(), any()) -> ok | {error,any()}.
-    -spec add(tuple()) -> {ok,tuple()} |
-                          {error,exist} |
-                          {error,no_container}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Raw Ops}
-These functions will patch the Erlang record inside database.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -spec put(tuple()) -> ok | {error,any()}.
-    -spec delete(atom(), any()) -> ok | {error,any()}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Read Ops}
-Allows you to read the Value by Key and list records with given secondary indexes.
-{\bf get/3} API is used to specify default value.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -spec index(atom(), any(), any()) -> list(tuple()).
-    -spec get(atom(),any(), any()) -> {ok,any()}.
-    -spec get(atom(), any()) -> {ok,any()} |
-                                {error,duplicated} |
-                                {error,not_found}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{Import/Export}
-You can use this API to store all database
-in a single file when it is possible. It's ok for development but not very good for production API.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -spec load_db(string()) -> list(ok | {error,any()}).
-    -spec save_db(string()) -> ok | {error,any()}.
-\end{lstlisting}
-\vspace{1\baselineskip}

+ 0 - 134
doc/processes.tex

@@ -1,134 +0,0 @@
-\section{Erlang Processes}
-
-\subsection{Reduced Latency}
-The secret to reducing latency is simple. We try to deliver rendered HTML
-as soon as possible and render JavaScript only when WebSocket initialization is complete.
-It takes three steps and three Erlang processes for doing that.
-
-\includeimage{images/page-lifetime.png}{Page Lifetime}
-
-\paragraph{}
-N2O request lifetime begins with the start of HTTP process serving the first HTML page.
-After that it dies and spawns Transition process.
-Then the browser initiates WebSocket connections to the similar URL endpoint.
-N2O creates persistent WebSocket process and the Transition process dies.
-
-\paragraph{}
-Your page could also spawn processes with {\bf wf:async}.
-These are persistent processes that act like regular Erlang processes.
-This is a usual approach to organize non-blocking UI for file uploads
-and other time consuming operations.
-
-\newpage
-\subsection{Page Serving Process}
-This processes are applicable only to the case when you serving not static HTML,
-but dynamically rendered pages with NITRO, DTL or ET template engines.
-The very first HTTP handler only renders HTML. During page initialization
-function Module:{\bf main/0} is called. This function should return raw HTML or
-NITRO elements that could be rendered into raw HTML. All created on the way
-JavaScript actions are stored in the transition process.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    main() -> #dtl { file     = "login",
-                     app      = review,
-                     bindings = [ { body,
-                          #button { id       = send,
-                                    postback = chat } } ] }.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\paragraph{}
-HTTP handler will die immediately after returning HTML. Transition process
-stores actions and waits for a request from a WebSocket handler.
-
-\subsection{Transition Process}
-Right after receiving HTML the browser initiates WebSocket connection
-thus starting WebSocket handler on the server. After responding with
-JavaScript actions the Transition process dies and the only process left
-running is WebSocket handler. At this point initialization phase is complete.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    transition(Actions) ->
-        receive {'N2O',Pid} -> Pid ! Actions end.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Transition process is only applicable to dynamically rendered pages
-served by {\bf n2o\_document} endpoint. You never deal with it manually.
-
-\subsection{Events Process}
-After that all client/server communication is performed over
-WebSocket channel. All events coming from the browser are
-handled by N2O, which renders elements to HTML and actions to
-JavaScript. Each user at any time has only one WebSocket process
-per connection.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    event(init) -> wf:reg(room);
-    event(chat) -> #insert_top(history,#span{body="message"}),
-                   wf:flush(room).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-This code will register all WebSocket processes under the same
-topic in pubsub and broadcast history changing to all registered
-process in the system under the same topic using {\bf \#flush}
-NITRO protocol message.
-
-\paragraph{}
-During page initialization before Module:{\bf event(init)},
-Module:{\bf main/0} is called to render initial postbacks for
-elements. So you can share the same code to use SPA or DSL/DTL approach.
-
-\subsection{Async Processes}
-These are user processes that were created with {\bf wf:async} invocation.
-This processes was very useful to organize persistent stateful connection
-for legacy async technology like COMET for XHR channel. If you have problem with
-proxying WebSocket stream you can easily use XHR fallback that is
-provided by {\bf xhr.js} N2O companion library.
-Async processes are optional and only needed when you have a UI event taking too much
-time to be processed, like gigabyte file uploads. You can create
-multiple async processes per user. Starting from N2O 2.9 all async
-processes are being created as {\bf gen\_server} under
-{\bf n2o\_sup} supervision tree.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    event(init) -> wf:reg(room),
-                   wf:async("looper", fun async/1);
-
-    async(init) -> ok;
-    aynsc(Chat) -> io:format("Chat: ~p~n",[Chat]).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{SPA Mode}
-In SPA mode N2O can serve no HTML at all. N2O elements are
-bound during initialization handshake and thus can be used
-regularly as in DSL mode.
-
-\paragraph{}
-In the example provided in n2o/samples you can find two different
-front end to the same {\bf review} application which consist of
-two page modules {\bf index} and {\bf login}. You can access this application
-involving no HTML rendering by using static file serving that could be
-switched to direct nginx serving in production.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    open http://localhost:8000/static/app/login.htm
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Or you can see DTL rendered HTML pages which resides at following address:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    open http://localhost:8000/login.htm
-\end{lstlisting}
-\vspace{1\baselineskip}
-

+ 0 - 451
doc/protocols.tex

@@ -1,451 +0,0 @@
-\section{Protocols}
-N2O is more that just web framework or even application server.
-It also has protocol specification that covers broad range of application domains.
-In this chapter we go deep inside network capabilities of N2O communications.
-N2O protocol also has an ASN.1 formal description, however here we will speak on it freely.
-Here is the landscape of N2O protocols stack.
-
-\includeimage{n2o-proto.png}{Protocols Stack}
-
-\paragraph{}
-You may find it similar to XML-based XMPP, binary COM/CORBA,
-JSON-based WAMP, Apache Camel or Microsoft WCF communication foundations.
-We took best from all and put into one protocols stack for web,
-social and enterprise domains providing stable and mature implementation for Erlang
-in a form of N2O application server.
-
-\newpage
-\subsection*{Cross Language Compatibility}
-N2O application server implemented to support N2O protocol definition
-in Erlang which is widely used in enterprise applications.
-Experimental implementation in Haskell {\bf n2o.hs} exists
-which supports only core {\bf heart} protocol along with {\bf bert} formatter.
-We will show you how N2O clients are compatible across
-different server implementations in different languages.
-
-\subsection*{Web Protocols: {\bf nitro}, {\bf spa}, {\bf bin}}
-N2O protocols stack provides definition for several unoverlapped protocol layers.
-N2O application server implementation of N2O protocol specification supports
-four protocol layers from this stack for WebSocket and IoT applications:
-{\bf heart}, {\bf nitro}, {\bf spa} and {\bf bin} protocols.
-HEART protocol is designed for reliable managed connections and stream channel initialization.
-The domain of NITRO protocol is HTML5 client/server interoperability, HTML events and JavaScript delivery.
-SPA protocol dedicated for games and static page applications that involves no HTML,
-such as SVG based games or non-gui IoT applications.
-And finally binary file transfer protocol for images and gigabyte file uploads and downloads.
-All these protocols transfers coexist in the same multi-channel stream.
-
-\subsection*{Social Protocols: {\bf roster}, {\bf muc}, {\bf search}}
-For social connectivity one may need to use {\bf synrc/roster} instant messaging server
-that supports {\bf roster} protocol  with variation
-for enabling public rooms {\bf muc} or full-text {\bf search} facilities.
-
-\subsection*{Enterprise Protocols: {\bf bpe}, {\bf mq}, {\bf rest}}
-There is no single system shipped to support all of N2O protocols but it
-could exist theoretically. For other protocols implementation you may refer
-to other products like {\bf spawnproc/bpe}, {\bf synrc/rest} or {\bf synrc/mq}.
-
-\newpage
-\subsection*{Channel Termination Formatters}
-N2O protocol is formatter agnostic and it doesn't strict you
-to use a particular encoder/decoder.
-Application developers could choose their own formatter per protocol.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    1. BERT : {io,"fire();",1}
-    2. WAMP : [io,"fire();",1]
-    3. JSON : {name:io,eval:"fire();",data:1}
-    4. TEXT : IO \xFF fire(); \xFF 1\n
-    5. XML  : <io><eval>fire();</eval><data>1</data></io>
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-E.g. N2O uses TEXT formatting for ``PING'' and ``N2O,'' protocol messages,
-across versions N2O used to have IO message formatted with JSON and BERT both.
-All other protocol messages were BERT from origin.
-Make sure formatters set for client and server is compatible.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    #cx{formatter=bert}.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Note that you may include to support more that one protocol on the client.
-At server side you can change formatter on the fly without breaking
-the channel stream. Each message during data stream could be formatted
-using only one protocol at a time. If you want to pass each message
-through more that one formatter you should write an echo protocol.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    <script src='/n2o/protocols/bert.js'></script>
-    <script src='/n2o/protocols/client.js'></script>
-    <script>protos = [ $bert, $client ]; N2O_start();</script>
-\end{lstlisting}
-
-
-\newpage
-\subsection*{Protocol Loop}
-After message arrives to endpoint and handlers chain is being initializes,
-message then comes to protocol stack. N2O selects appropriative protocol
-module and handle the message. After than message is being formatted and
-replied back to stream channel. Note that protocol loop is applicable
-only to WebSocket stream channel endpoint.
-
-\includeimage{n2o_protocols.png}{Messaging Pipeline}
-
-\paragraph{}
-Here is pseudocode how message travels for each protocol until some
-of them handle the message. Note tnat this logic is subject to change.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=Top-level protocol loop in {n2o}\_{proto}]
-    reply(M,R,S)              -> {reply,M,R,S}.
-    nop(R,S)                  -> {reply,<<>>,R,S}.
-    push(_,R,S,[],_Acc)       -> nop(R,S);
-    push(M,R,S,[H|T],Acc)     ->
-        case H:info(M,R,S) of
-              {unknown,_,_,_} -> push(M,R,S,T,Acc);
-             {reply,M1,R1,S1} -> reply(M1,R1,S1);
-                            A -> push(M,R,S,T,[A|Acc]) end.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection*{Enabling Protocols}
-You may set up protocol from sys.config file,
-enabling or disabling some of them on the fly.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    protocols() ->
-       wf:config(n2o,protocols,[ n2o_heart,
-                                 n2o_nitrogen,
-                                 n2o_client,
-                                 n2o_file  ]).
-
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-For example in Skyline (DSL) application you use only {\bf nitro} protocol:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > wf:config(n2o,protocols).
-    [n2o_heart,n2o_nitrogen]
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-And in Games (SPA) application you need only {\bf spa} protocol:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > wf:config(n2o,protocols).
-    [n2o_heart,n2o_client]
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{HEART}
-
-HEART protocol is essential WebSocket application level protocol for PING and N2O initialization.
-It pings every 4-5 seconds from client-side to server thus allowing to
-determine client online presence. On reconnection or initial connect
-client sends N2O init marker telling to server to reinitialize the context.
-
-\paragraph{}
-The {\bf heart} protocol defined client originated messages N2O, PING
-and server originated messages PONG, IO and NOP. IO message contains EVAL
-that contains UTF-8 JavaScript string and DATA reply contains any
-binary string, including BERT encoded data. "PING" and "N2O," are
-defined as text 4-bytes messages and second could be followed by
-any text string. NOP is 0-byte acknowledging packet.
-This is heart essence protocol which is enough for any rpc and code
-transferring interface. Normally heart protocol is not for active
-client usage but for supporting active connection with notifications
-and possibly DOM updates.
-
-\subsection*{Session Initialization}
-
-After page load you should start N2O session in JavaScript with configured
-formatters and starting function that will start message loop on the client:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    var transition = {pid: '', host: 'localhost', port:'8000'};
-    protos = [ $bert, $client ];
-    N2O_start();
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-If {\bf pid} field is not set in {\bf transition} variable then you
-will request new session otherwise you may put here information from
-previously settled cookies for attaching to existing session. This {\bf pid}
-disregarding set or empty will be bypassed as a parameter to N2O init marker.
-
-You can manually invoke session initialization inside existing session:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    ws.send('N2O,');
-\end{lstlisting}
-
-\newpage
-In response on successful WebSocket connection and enabled {\bf heart}
-protocol on the server you will receive the IO message event.
-IO events are containers for function and data which can be used as parameters.
-There is no predefined semantic to IO message. Second element of a tuple
-will be directly evaluated in WebBrowser. Third element can contain data or error
-as for SPA and BIN protocols, and can contain only error for NITRO protocol.
-IO events are not constructed on client. N2O request returns IO messages with
-evaluation string and empty data or empty evaluation string
-with error in data field.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    issue TEXT N2O expect IO
-   N2O is TEXT "N2O," ++ PID
-   PID is TEXT "" or any
-    IO is BERT {io,<<>>,Error}
-            or {io,Eval,<<>>}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection*{Online Presence}
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    ws.send('PING');
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-You can try manually send this messag in web console to see whats happening,
-also you can enable logging the heartbeat protocol by including its
-module in {\bf log\_modules}:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    log_modules() -> [n2o_heart].
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Heartbeat protocol PING request returns PONG or empty NOP binary response.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    issue TEXT PING expect PONG
-  PONG is TEXT "PONG" or ""
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-
-\newpage
-\subsection{NITRO}
-
-NITRO protocol consist of three protocol messages: {\bf pickle}, {\bf flush} and {\bf direct}.
-Pickled messages are used if you send messages over unencrypted
-channel and want to hide the content of the message,
-that was generated on server. You can use BASE64 pickling mechanisms
-with optional AES/RIPEMD160 encrypting. NITRO messages on success alway
-return empty data field in IO message and
-error otherwise. Here is definition to NITRO protocol in expect language:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-        issue BERT PICKLE expect IO
-        issue BERT DIRECT expect IO
-        issue BERT FLUSH  expect IO
-    PICKLE is BERT {pickle,_,_,_,_}
-    DIRECT is BERT {direct,_}
-     FLUSH is BERT {flush,_}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Usually {\bf pickle} events are being sent generated from server during
-rendering of {\bf nitro} elements. To see how it looks like you can see
-inside IO messages returned from N2O initialization. There you can find
-something like this:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    ws.send(enc(tuple(atom('pickle'),
-        bin('loginButton'),
-        bin('g2gCaAVkAAJldmQABGF1dGhkAAVsb2dpbmsAC2xvZ2lu'
-             'QnV0dG9uZAAFZXZlbnRoA2IAAAWiYgAA72ViAA8kIQ=='),
-        [ tuple(tuple(utf8_toByteArray('loginButton'),
-                      bin('detail')),[]),
-          tuple(atom('user'),querySource('user')),
-          tuple(atom('pass'),querySource('pass'))])));
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Invocation of {\bf pickle} messages is binded to DOM elements
-using {\bf source} and {\bf postback} information from nitro elements.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-   #button { id=loginButton,
-             body="Login",
-             postback=login,
-             source=[user,pass] } ].
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Only fields listed in {\bf source} will be included in {\bf pickle}
-message on invocation. Information about module and event arguments (postback)
-is sent encrypted or pickled. So it would be hard to know the internal
-structure of server codebase for potential hacker. On the server you will
-recieve following structure:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    {pickle,<<"loginButton">>,
-            <<"g2gCaAVkAAJldmQABGF1dGhkAAVsb2dpbmsAC2xvZ2lu"
-              "QnV0dG9uZAAFZXZlbnRoA2IAAAWiYgAA72ViAA8kIQ==">>,
-           [{{"loginButton",<<"detail">>},[]},
-            {user,[]},
-            {pass,"z"}]}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-You can depickle {\bf \#ev} event with {\bf wf:depickle} API:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > wf:depickle(<<"g1AAAAA6eJzLYMpgTWFgSi1LYWDNyU/PzIPR2Qh+"
-                    "allqXkkGcxIDA+siIHEvKomB5cBKAN+JEQ4=">>).
-
-    #ev { module  = Module  = auth,
-          msg     = Message = login,
-          name    = event,
-          trigger = "loginButton" }
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Information for {\bf \#ev} event is directly passed to page module
-as {\bf Module:event(Message) }. Information from sources {\bf user}
-and {\bf pass} could be retrieved with {\bf wf:q} API:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -module(auth).
-    -compile(export_all).
-
-    event(login) ->
-        io:format(lists:concat([":user:",wf:q(user),
-                                ":pass:",wf:q(pass)])).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-This is Nitrogen-based messaging model. Nitrogen WebSocket processes receive also
-flush and delivery protocol messages, but originated from server, which is internal
-NITRO protocol messages. All client requests originate IO message as a response.
-
-\newpage
-\subsection{SPA}
-
-If you are creating SVG based game you don't need HTML5 nitro elements at all.
-Instead you need simple and clean JavaScript based protocol for updating DOM SVG elements
-but based on {\bf shen} generated or manual JavaScript code sent from server.
-Thus you need still IO messages as a reply but originating message shouldn't
-rely in {\bf nitro} at all. For that purposes in general and for {\bf synrc/games} sample
-in particular we created SPA protocol layer. SPA protocol consist of CLIENT originated message
-and SERVER message that could be originated both from client and server. All messages expects
-IO as a response. In IO response data field is always set with return value of the event
-while eval field is set with rendered actions as in NITRO protocol.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-        issue BERT CLIENT expect IO
-        issue BERT SERVER expect IO
-    SERVER is BERT {server,_}
-    CLIENT is BERT {client,_}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Client messages usually originated at client and represent the Client API Requests:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    ws.send(enc(tuple(
-        atom('client'),
-        tuple(atom('join_game'),1000001))));
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Server messages are usually being sent to client originated on the
-server by sending {\bf info} notifications directly to Web Socket process:
-
-\begin{lstlisting}
-    > WebSocketPid ! {server, Message}
-\end{lstlisting}
-
-You can obtain this Pid during page init:
-
-\begin{lstlisting}
-    event(init) -> io:format("Pid: ~p",[self()]);
-\end{lstlisting}
-
-You can also send server messages from client relays and vice versa.
-It is up to your application and client/server handlers how to handle such messages.
-
-\newpage
-\subsection{BIN}
-
-When you need raw binary Blob on client-side,
-for images or other raw data, you can ask server like this:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > ws.send(enc(tuple(atom('bin'),bin('request'))));
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Ensure you have defined {\bf \#bin} handler and page you are
-asking is visible by router:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    event(#bin{data=Data}) ->
-        wf:info(?MODULE,"Binary Delivered ~p~n",[Data]),
-        #bin{data = "SERVER v1"};
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Having enabled all loggin in module {\bf n2o\_file}, {\bf index} and {\bf wf\_convert}
-you will see:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    n2o_file:BIN Message: {bin,<<"request">>}
-    index:Binary Delivered <<"request">>
-    wf_convert:BERT {bin,_}: "SERVER v1"
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-In JavaScript when you enable `debug=true` you can see:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > {"t":104,"v":[{"t":100,"v":"bin"},
-                    {"t":107,"v":"SERVER v1"}]}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Or by adding handling for BIN protocol:
-
-\begin{lstlisting}
-    > $file.do = function (x)
-        { console.log('BIN received: ' + x.v[1].v); }
-    > ws.send(enc(tuple(atom('bin'),bin('request'))));
-    > BIN received: SERVER v1
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-The formal description of BIN is simple relay:
-
-\begin{lstlisting}
-    issue BERT {bin,_} expect {bin,_}
-\end{lstlisting}

+ 0 - 207
doc/setup.tex

@@ -1,207 +0,0 @@
-\section{Setup}
-
-\subsection{Prerequisites}
-To run N2O websites you need to install Erlang version 18 or higher.
-N2O works on Windows, Mac and Linux.
-
-\subsection{Kickstart Bootstrap}
-To try N2O you only need to fetch it from Github and build. We don't use
-fancy scripts, so building process is OTP compatible: bootstrap site
-is bundled as an Erlang release.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    $ git clone git://github.com/synrc/n2o
-    $ cd n2o/samples
-    $ ./mad deps compile plan repl
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-Now you can try: \footahref{http://localhost:8000}{http://localhost:8000}.
-
-On Linux you should do at first:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    $ sudo apt-get install inotify-tools
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{Application Template}
-If you want to start using N2O inside your application, you can use Cowboy dispatch parameter
-for passing HTTP, REST, WebSocket and Static N2O endpoints:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=sample.erl]
-
-  -module(sample).
-  -behaviour(supervisor).
-  -behaviour(application).
-  -export([init/1, start/2, stop/1, main/1]).
-
-  main(A)    -> mad:main(A).
-  start(_,_) -> supervisor:start_link({local,review},review,[]).
-  stop(_)    -> ok.
-  init([])   -> { ok, { { one_for_one, 5, 100 }, [spec()] } }.
-
-  spec()   -> ranch:child_spec(http, 100, ranch_tcp, port(), cowboy_protocol, env()).
-  port()   -> [ { port, wf:config(n2o,port,8000)  } ].
-  env()    -> [ { env, [ { dispatch, points() } ] } ].
-  static() ->   { dir, "apps/sample/priv/static", mime() }.
-  n2o()    ->   { dir, "deps/n2o/priv",           mime() }.
-  mime()   -> [ { mimetypes, cow_mimetypes, all   } ].
-  points() -> cowboy_router:compile([{'_', [
-
-              { "/static/[...]",       n2o_static,  static()},
-              { "/n2o/[...]",          n2o_static,  n2o()},
-              { "/ws/[...]",           n2o_stream,  []},
-              { '_',                   n2o_cowboy,  []} ]}]).
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-While Listing 1 is a little bit criptic we want to say that N2O
-intentionally not introduced here any syntax sugar.
-For any Erlang application you need to create application
-and supervisor behavior modules which we combined in the
-same Erlang file for simplicity.
-
-\paragraph{}
-Cowboy routing rules also leaved as is.
-We'd better to leave our efforts for making N2O protocol
-and N2O internals simplier. Here we can't fix a much. Just use this
-as template for bootstrapping N2O based applications.
-
-\subsection{Companion Dependencies}
-For raw N2O use with BERT message formatter you need only
-one N2O dependecy, but if you want to use DTL templates,
-JSON message formatter, SHEN JavaScript Compiler or NITRO
-Nitrogen DSL you can plug all of them separately.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    https://github.com/synrc/n2o        2.9
-    https://github.com/synrc/nitro      2.9
-    https://github.com/synrc/kvs        2.9
-    https://github.com/synrc/active     2.9
-    https://github.com/synrc/shen       1.5
-    https://github.com/synrc/rest       1.5
-    https://github.com/spawnproc/bpe    1.5
-    https://github.com/spawnproc/forms  1.5
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection{Configuration}
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=sys.config]
-    [{n2o, [{port,8000},
-            {app,review},
-            {route,routes},
-            {mq,n2o_mq},
-            {json,jsone},
-            {log_modules,config},
-            {log_level,config},
-            {log_backend,n2o_log},
-            {session,n2o_session},
-            {origin,<<"*">>},
-            {bridge,n2o_cowboy},
-            {pickler,n2o_pickle},
-            {erroring,n2o_error}]},
-     {kvs, [{dba,store_mnesia},
-            {schema, [kvs_user,
-                      kvs_acl,
-                      kvs_feed,
-                      kvs_subscription ]} ]} ].
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-
-\subsection*{Ports}
-N2O uses two ports for WebSocket and HTTP connections.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    wf:config(n2o,port,443)
-    wf:config(n2o,websocket_port,443)
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-If you use server pages mode N2O will render HTML with nessesary ports values.
-For single page application mode you should redefine these ports inside the template:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    <script> var transition = { pid: '',
-                                host: 'localhost',
-                                port: '443' }; </script>
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-
-\subsection*{Application}
-In {\bf app} setting you should place the name of your OTP application
-that will be treated by N2O and NITRO as a source for templates and
-other static data with {\bf code:priv\_dir}.
-
-\subsection*{Routes}
-Setting {\bf route} is a place for the name of Erlang module where
-resides mappings from URL to page modules.
-
-\subsection*{Logging}
-N2O supports logging API and you can plug different logging module.
-It ships with {\bf n2o\_io} and {\bf n2o\_log} modules which you can set in the
-{\bf log\_backend} option. This is how logging looks like in N2O:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    wf:info(index,"Message: ~p",[Message]),
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-First argument is a module from which function is being called. By using this
-N2O can filter all log messages with special filter settled with {\bf log\_modules} option.
-It says in which Erlang module function {\bf log\_modules/0} exists that
-returns allowed Erlang modules to log. Option {\bf log\_level} which specified
-in a similar way, it specifies the module with function {\bf log\_level/0} that could
-return one of {\bf none}, {\bf error}, {\bf warning} or {\bf info} atom values which
-means different error log levels.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    -module(config).
-    -compile(export_all).
-
-    log_level() -> info.
-    log_modules() -> [ login, index ].
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\newpage
-\subsection*{Message Queue}
-In {\bf mq} settings you should place the name of Erlang module which supports
-message queue API. By default N2O provides {\bf n2o\_mq} module.
-
-\subsection*{Formatter}
-With {\bf formatter} option you may set the WebSocket channel
-termination formatter such as {\bf bert} or {\bf json}. If you will select json as formatter
-you may want also to chose a json encoder in {\bf json} option. By default in n2o enabled
-{\bf json} formatter and {\bf jsone} encoder. The main reason is that {\bf jsone} is
-written in pure erlang idiomatic code and is ready to run on LING without C NIF linkage.
-But you may want to switch to {\bf jsonx} on BEAM or whatever.
-
-\subsection*{Minimal Page}
-And then add a minimal {\bf index.erl} page:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}[caption=index.erl]
-    -module(index).
-    -compile(export_all).
-    -include_lib("nitro/include/nitro.hrl").
-
-    main() -> #span{body="Hello"}.
-\end{lstlisting}
-\vspace{1\baselineskip}

+ 0 - 137
doc/synrc.tex

@@ -1,137 +0,0 @@
-% Copyright (c) 2010 Synrc Research Center
-
-\usepackage{afterpage}
-
-\usepackage{hevea}
-\usepackage[english]{babel}
-\usepackage{palatino}
-\usepackage{graphicx}
-\usepackage{tocloft}
-\usepackage{cite}
-\usepackage[utf8]{inputenc}
-\usepackage{moreverb}
-\usepackage{listings}
-\usepackage[none]{hyphenat}
-\usepackage{caption}
-\usepackage[usenames,dvipsnames]{color}
-\usepackage[top=18mm, bottom=25.4mm,
-            inner=16mm,outer=18mm,
-            paperwidth=142mm, paperheight=200mm]{geometry}
-
-%left=18mm, right=18mm,
-
-% \usepackage[hmarginratio=3:2]{geometry}
-
-\hyphenation{framework nitrogen javascript facebook streaming JavaScript micro-frameworks}
-
-\setlength{\cftsubsecnumwidth}{2.5em}
-
-% include image for HeVeA and LaTeX
-
-\makeatletter
-\def\@seccntformat#1{\llap{\csname the#1\endcsname\hskip0.7em\relax}}
-\makeatother
-
-\newcommand{\includeimage}[2]
-{\ifhevea
-    {\imgsrc{#1}}
-\else{
-    \begin{figure}[h!]
-    \centering
-    \includegraphics[width=\textwidth]{#1}
-    \caption{#2}
-    \end{figure}}
-\fi}
-
-% HeVeA header
-
-{\ifhevea
-  \let\oldmeta=\@meta
-  \renewcommand{\@meta}{%
-  \oldmeta
-  \begin{rawhtml}
-  <meta name="Author" content="Maxim Sokhatsky">
-  <meta http-equiv="expires" content="Tue, 01 Jan 2020 1:00:00 GMT" />
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-  <meta http-equiv="X-UA-Compatible" content="IE=IE10,chrome=1" />
-  \end{rawhtml}}
-
-  \htmlhead{\rawhtmlinput{templates/head-hevea.htx}}
-  \htmlfoot{\rawhtmlinput{templates/foot.htx}}
-  \footerfalse
-\fi}
-
-% title page for N2O
-
-\newcommand*{\titleWF}
-{
-    \begingroup
-   \thispagestyle{empty}
-    \hbox{
-        \hspace*{0.2\textwidth}
-        \rule{1pt}{\textheight}
-        \hspace*{0.05\textwidth}
-        \parbox[b]{0.75\textwidth}
-        {
-            {\noindent\Huge \bfseries N2O}\\[2\baselineskip]
-            {\LARGE \textsc{
-                No Bullshit\\[0.5\baselineskip]
-                Sane Framework\\[0.5\baselineskip]
-                for Wild Web}}\\[4\baselineskip]
-            \vspace{0.5\textheight}
-%            {\Large \textit{Maxim Sokhatsky}}\\[2\baselineskip]
-%            {\large {\bf {\color{Blue}syn}{\color{OrangeRed}rc} research center}
-%            {\copyright} 2013-2014}\\[1\baselineskip]
-        }
-    }
-    \endgroup
-}
-
-% define images store
-
-\graphicspath{{./images/}}
-
-% start each section from new page
-
-\let\stdsection\section
-\renewcommand\section{\newpage\stdsection}
-
-% define style for code listings
-
-\lstset{
-    backgroundcolor=\color{white},
-    keywordstyle=\color{blue},
-    basicstyle=\bf\ttfamily\footnotesize,
-    columns=fixed}
-
-%\headsep = 0cm
-%\voffset = -1.5cm
-%\hoffset = -0.7cm
-%\topmargin = 0cm
-%\textwidth = 12cm
-%\textheight = 17.5cm
-%\footskip = 1cm
-\parindent = 0cm
-
-\hyphenpenalty=5000
-  \tolerance=1000
-
-\newenvironment{dedication}
-{
-   \thispagestyle{empty}
-   \cleardoublepage
-   \thispagestyle{empty}
-   \vspace*{\stretch{1}}
-   \hfill\begin{minipage}[t]{0.66\textwidth}
-   \raggedright
-}%
-{
-   \end{minipage}
-   \vspace*{\stretch{3}}
-   \clearpage
-}
-
-\newcommand\blankpage{
-    \null
-    \thispagestyle{empty}
-    \newpage}

+ 0 - 52
doc/utf8.tex

@@ -1,52 +0,0 @@
-\section{UTF-8}
-
-\subsection{Erlang}
-
-The main thing you should know about Erlang unicode is that
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    unicode:characters_to_binary("Uni") == <<"Uni"/utf8>>.
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-I.e. in N2O DSL you should use:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    #button{body= <<"Unicode Name"/utf8>>}
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-\subsection{JavaScript}
-
-Whenever you want to send to server the value from DOM element
-you should use utf8\_toByteArray.
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > utf8_toByteArray(document.getElementById('phone').value);
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-However we created shortcut for that purposes which knows
-about radio, fieldset and other types of DOM nodes. So you should use just:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > querySource('phone');
-\end{lstlisting}
-\vspace{1\baselineskip}
-
-querySource JavaScript function ships in nitrogen.js which is part
-of N2O JavaScript library.
-
-\paragraph{}
-Whenever you get unicode data from server you should prepare it before place
-in DOM with utf8\_dec:
-
-\vspace{1\baselineskip}
-\begin{lstlisting}
-    > console.log(utf8_dec(receivedMessage));
-\end{lstlisting}
-\vspace{1\baselineskip}

+ 0 - 17
doc/web/actions.tex

@@ -1,17 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\begin{document}
-\title{N2O Actions}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\input{../actions}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}
-

+ 0 - 16
doc/web/api.tex

@@ -1,16 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\begin{document}
-\title{N2O API}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../api}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}

+ 0 - 17
doc/web/elements.tex

@@ -1,17 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\begin{document}
-\title{N2O Elements}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\input{../elements}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}
-

+ 0 - 18
doc/web/endpoints.tex

@@ -1,18 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\renewcommand{\images}{http://synrc.com/apps/n2o/doc}
-\begin{document}
-\title{N2O Endpoints}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../endpoints}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}
-

+ 0 - 18
doc/web/handlers.tex

@@ -1,18 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\renewcommand{\images}{http://synrc.com/apps/n2o/doc}
-\begin{document}
-\title{N2O Handlers}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../handlers}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}
-

+ 0 - 18
doc/web/index.tex

@@ -1,18 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\renewcommand{\images}{http://synrc.com/apps/n2o/doc/images}
-\begin{document}
-\title{N2O}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../index}
-%HEVEA \rawhtmlinput{templates/slides.htx}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}

+ 0 - 19
doc/web/last.tex

@@ -1,19 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../synrc.css}
-\begin{document}
-\title{N2O History}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../last}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\begin{rawhtml}
-<script type="text/javascript" src="http://synrc.com/hi.js"></script>
-\end{rawhtml}
-\end{document}

+ 0 - 16
doc/web/macros.tex

@@ -1,16 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\begin{document}
-\title{N2O JavaScript}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../macros}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}

+ 0 - 16
doc/web/packages.tex

@@ -1,16 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\begin{document}
-\title{N2O Packaging}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../packages}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}

+ 0 - 16
doc/web/persistence.tex

@@ -1,16 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\begin{document}
-\title{N2O Persistence}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../persistence}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}

+ 0 - 17
doc/web/processes.tex

@@ -1,17 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\renewcommand{\images}{http://synrc.com/apps/n2o/doc}
-\begin{document}
-\title{N2O Processes}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../processes}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}

+ 0 - 17
doc/web/protocols.tex

@@ -1,17 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../../../synrc.css}
-\renewcommand{\images}{http://synrc.com/apps/n2o/doc/images}
-\begin{document}
-\title{N2O Protocols}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../protocols}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\end{document}

+ 0 - 19
doc/web/setup.tex

@@ -1,19 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../synrc.css}
-\begin{document}
-\title{N2O Setup}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../setup}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\begin{rawhtml}
-<script type="text/javascript" src="http://synrc.com/hi.js"></script>
-\end{rawhtml}
-\end{document}

+ 0 - 19
doc/web/toc.tex

@@ -1,19 +0,0 @@
-%HEVEA \begin{divstyle}{toc}
-\section*{TOC}
-\paragraph{}
-\footahref{http://synrc.com/apps/n2o/doc/web}{1. Framework} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/setup.htm}{2. Setup} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/processes.htm}{3. Processes} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/endpoints.htm}{4. Endpoints} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/handlers.htm}{5. Handlers} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/protocols.htm}{6. Protocols} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/api.htm}{7. API} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/elements.htm}{8. Elements} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/actions.htm}{9. Actions} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/macros.htm}{10. JavaScript} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/utf8.htm}{11. UTF-8} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/packages.htm}{12. Packages} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/persistence.htm}{13. Persistence} \@br
-\footahref{http://synrc.com/apps/n2o/doc/web/last.htm}{14. History} \@br
-\footahref{http://synrc.com/apps/n2o/doc/book.pdf}{Download PDF} \@br
-%HEVEA \end{divstyle}

+ 0 - 19
doc/web/utf8.tex

@@ -1,19 +0,0 @@
-\input{../../../../synrc.hva}
-%HEVEA \loadcssfile{../../synrc.css}
-\begin{document}
-\title{N2O UTF8}
-\author{Maxim Sokhatsky}
-%HEVEA \begin{divstyle}{nonselectedwrapper}
-%HEVEA \begin{divstyle}{article}
-\input{toc}
-%HEVEA \begin{divstyle}{articlecol}
-\include{../utf8}
-%HEVEA \rawhtmlinput{templates/disqus.htx}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \end{divstyle}
-%HEVEA \begin{divstyle}{clear}{~}\end{divstyle}
-\begin{rawhtml}
-<script type="text/javascript" src="http://synrc.com/hi.js"></script>
-\end{rawhtml}
-\end{document}