#! /usr/bin/env python

# This software carries the following license:
#
# Modified BSD license
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# 
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Steinar Knutsen

"""Outline 1.4

Converts plain text outlines to Lout. ` at the end of a line signifies
forced line break.
"""

import string, sys

indentsize = 3 # Number of spaces equal to a level of indentation,
   # a tab is always considered a level of indentation

louthead = """\
@SysInclude { doc }
@Document
   @InitialSpace { tex }
//
@Text @Begin
@LD {
"""
loutfoot = """\
}
@End @Text
"""
linefeed = "//1vx\n"
indent = "@RID {\n"
outdent = "}\n"

chartable = {
   '#': '"#"',
   '&': '"&"',
   '/': '"/"',
   '@': '"@"',
   '\\': r'"\\"',
   '^': '"^"',
   '{': '"{"',
   '|': '"|"',
   '}': '"}"',
   '~': '"~"'
}

class converter:
   def __init__(self, input):
      self.input = input
      self.output = [louthead]
   def indentone(self):
      if self.output[-1] == linefeed:
         self.output.append(indent)
      else:
         self.output.extend([linefeed, indent])
   def outdentone(self):
      if self.output[-2:] == [linefeed, linefeed]:
         # The list may be separated with an empty line
         self.output[-2:] = [outdent, linefeed, linefeed]
      elif self.output[-1] == linefeed:
         # The list may be nested
         self.output[-1:] = [outdent, linefeed]
      else:
         # Default case
         self.output.extend([outdent, linefeed])
   def insert_line(self):
      if self.output[-1] == linefeed:
         self.output.append(linefeed)
      else:
         self.output.extend([linefeed, linefeed])
   def insert_break(self):
      self.output.append(linefeed)
   def translate(self, line, replace=string.replace):
      line = string.split(line, '"')
      for old, new in chartable.items():
         for i in range(len(line)):
            line[i] = replace(line[i], old, new)
      return string.join(line, r'"\""')
   def count_tabs(self, line):
      indent = 0
      spaceindex = 0
      i = 0
      while i < len(line) and line[i] == '\t' or line[i] == ' ':
         if line[i] == '\t':
            indent += 1
         else:
            spaceindex += 1
            if spaceindex == indentsize:
               indent += 1
               spaceindex = 0
         i += 1
      return indent
   def close(self, strip = string.strip):
      currindentlvl, previndentlvl = 0, 0
      for line in self.input:
         if len(strip(line)) == 0:
            self.insert_line()
            continue
         previndentlvl = currindentlvl
         currindentlvl = self.count_tabs(line)
         line = self.translate(line)
         if currindentlvl > previndentlvl:
            count = currindentlvl - previndentlvl
            while count > 0:
               count = count - 1
               self.indentone()
         elif currindentlvl < previndentlvl:
            count = previndentlvl - currindentlvl
            while count > 0:
               count = count - 1
               self.outdentone()
         if line[-2] == '`':
            line = line[:-2]+"\n"
            self.output.append(line)
            self.insert_break()
         else:
            self.output.append(line)
      if currindentlvl != 0:
         while currindentlvl > 0:
            currindentlvl = currindentlvl - 1
            self.outdentone()
      self.output.append(loutfoot)
      return string.join(self.output, '')

if __name__ == "__main__":
   filter = converter(sys.stdin.readlines())
   sys.stdout.write(filter.close())
