package Autodoc::GenerateRTF;

###############################################################################
###############################################################################
##
##    Written by Adam Swift (c) 1995 by Friday Software and Consulting
##                           All rights reserved.
##
##	  This notice may not be removed from this source code.
##
##    This program is included in the MiscKit by permission from the author
##    and its use is governed by the MiscKit license, found in the file
##    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
##    for a list of all applicable permissions and restrictions.
##
##    Because AutoDoc is licensed free of charge, there is no warranty 
##    for the program.  Copyright holder, Friday Software and Consulting, 
##    is providing this program "as is" and this program is distributed in 
##    the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
##    even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
##    PARTICULAR PURPOSE.
##
###############################################################################
###############################################################################

require 5.000;

##########################
# load required packages #
##########################
use Exporter;
# use Autodoc::DumpDocs;

@ISA      = qw(Exporter);
@EXPORT   = qw(rtf_fileheader
			   rtf_filefooter
			   rtf_fonttable
			   rtf_stylesheet
			   rtf_spacer
			   rtf_head
			   rtf_title
			   rtf_subtitle
			   rtf_paragraph
			   rtf_synopsis
			   rtf_majorheading
			   rtf_minorheading
			   rtf_synopsis
			   rtf_keyvalue
			   rtf_methodline
			   rtf_format_words
			   rtf_format_method
			   rtf_boldify
			   rtf_italicize
			   rtf_copyright
			   rtf_emdash
			   rtf_setfont_times
			   rtf_setfont_helvetica
			   rtf_newline
			   rtf_newline_small
			   rtf_newline_micro
			  );

$module_version = '$Revision: 1.3 $';
$module_version =~ s!(\$\w+: | \$)!!g;
$module_id	    = '$Id: GenerateRTF.pm,v 1.3 1995/10/20 22:16:26 aswift Exp $';
$module_id      =~ s!(\$\w+: | \$)!!g;
$module_name	= $module_id;
$module_name	=~ s!^([^\,]+).*$!$1!;

############################################################################
# 
# Purpose: Module that encapsulates generation of RTF specific syntax to 
#          produce different paragraph and text styles for documentation
#
# HISTORY: START
# $Log: GenerateRTF.pm,v $
# Revision 1.3  1995/10/20  22:16:26  aswift
# Added DevMan style changes Log support
#
#
# HISTORY: END
############################################################################


#############################################################################
#
# NAME:       module_version
#
# ACTION:     returns the version number of this module
#
# RETURN:     the module version
#
#############################################################################
sub module_version
{
    return $module_version;
}

sub module_versionstamp
{
    return "$module_name (rev-$module_version)";
}


#############################################################################
#
# NAME:      rtf_paragraph
#
# ACTION:    Takes a string argument and formats it for rtf formatted output
#            as the basic format style.
#
#            This includes calling rtf_format_words to boldify & italicize
#            words.
#
#            Reformat the text passed to this subroutine to turn the newline 
#            markers into real newlines, and generally make paragraphs 
#            look better.
#
# RETURN:    Returns the formatted string
#
#############################################################################
sub rtf_paragraph
  {    
    my ($paragraph)		= $_[0];
	my ($rtf_paragraph)	= "";
	my ($listRTF)	= "";

    $rtf_paragraph = '\fs36 \pard \s0 \li2116 \fi0 \ri1007 \ql \tx2494 ';
    $rtf_paragraph .= '\tx2872 \tx3250 ';
	$rtf_paragraph .= rtf_setfont_times();

    $listRTF = '\pard \s11 \li7648 \fi-5131 \ri1007 \ql \tx7648 ';
    $listRTF .= "\\tx10180 \\fs16 \\\n \\fs28 ";

    # Make all space-runs into single spaces
    $paragraph =~ s/ +/ /g;

    # make all spaces following a period (+ end paren) double spaces
    $paragraph =~ s/\.(\)?) /\.$1  /g;

    # Make newline markers into rtf compatible newlines
    $paragraph =~ s/\\n\s*/\\\n\\fs16 \\\n\\fs28 /g;

    # Boldify and Italicize the words, THIS REFORMATS '}' CURLY BRACES as '\}'
    $paragraph = rtf_format_words ($paragraph); 

    # Find List encodings and format the lines THE CURLY IS REPLACED WITH ' '
    $paragraph =~ 
	  s/\_\{\s*([^\}\s]+)\s*([^\}]*)\}\s*/\{$listRTF $1\t$2 \}\n /g;

	$rtf_paragraph .= $paragraph;
	$rtf_paragraph .= " " . rtf_newline();

    return "$rtf_paragraph";
  }


#############################################################################
#
# NAME:       rtf_majorheading
#
# ACTION:     takes a string and wraps it into an rtf formatted string in the
#             major heading style
#
# RETURN:     returns the rtf formatted string
#
#############################################################################
sub rtf_majorheading
  {
	my ($majhead)     = $_[0];
	my ($rtf_majhead) = "";

	$rtf_majhead = rtf_spacer();
	$rtf_majhead .= rtf_setfont_helvetica(18);
	$rtf_majhead .= rtf_boldify($majhead);
	$rtf_majhead .= rtf_newline() . rtf_newline_small();

	return $rtf_majhead;
  }


#############################################################################
#
# NAME:       rtf_minorheading
#
# ACTION:     takes a string and wraps it into an rtf formatted string in the
#             minor heading style
#
# RETURN:     returns the rtf formatted string
#
#############################################################################
sub rtf_minorheading
  {
	my ($minhead)     = $_[0];
	my ($rtf_minhead) = "";

	$rtf_minhead = '\pard \tx2116 \tx6148 \tx6794 \tx7440 \tx8086 \tx9378';
	$rtf_minhead .= '\li6148 \fi-4421 \fc0 \cf0 ';
	$rtf_minhead .= rtf_setfont_helvetica(10);
	$rtf_minhead .= rtf_boldify($minhead) . rtf_newline();

	return $rtf_minhead;
  }


#############################################################################
#
# NAME:       rtf_synopsis
#
# ACTION:     returns the text passed in (if any) prepended with the
#             rtf formatting to set text into the sysnopsis style.
#
#############################################################################
sub rtf_synopsis
  {
    my ($synopsis) = "";
	my ($rtf_synopsis) = "";
	
	$synopsis = $_[0]
	  if (scalar @_);
	$rtf_synopsis = '\pard \s11 \li6148 \fi-4031 \ri1007 \ql ';
	$rtf_synopsis .= '\tx7440 \tx8086 \tx8732 \tx9378 \tx10024 \tx10670';
	$rtf_synopsis .= rtf_setfont_times();
	$rtf_synopsis .= "\n" . $synopsis . rtf_newline()
	  if ($synopsis);
	
	return $rtf_synopsis;
  }

#############################################################################
#
# NAME:       rtf_keyvalue
#
# ACTION:     returns the text passed in (if any) prepended with the
#             rtf formatting to set text into the keyvalue style.
#
#############################################################################
sub rtf_keyvalue
  {
    my ($keyvalue) = "";
	my ($rtf_keyvalue) = "";
	
	$keyvalue = $_[0]
	  if (scalar @_);
	$rtf_keyvalue = '\pard \s11 \li6148 \fi-4031 \ri1007 \ql \tx6148 ';
	$rtf_keyvalue .= rtf_setfont_times();
	$rtf_keyvalue .= "\n" . $keyvalue . rtf_newline()
	  if ($keyvalue);
	
	return $rtf_keyvalue;
  }

#############################################################################
#
# NAME:       rtf_methodline
#
# ACTION:     returns the text passed in (if any) prepended with the
#             rtf formatting to set text into the methodline style.
#
#############################################################################
sub rtf_methodline
  {
    my ($methodline) = "";
	my ($rtf_methodline) = "";
	
	$methodline = $_[0]
	  if (scalar @_);

	$rtf_methodline = '\pard \tx3240 \li2100 \fi-760 \li3240';
	$rtf_methodline .= rtf_setfont_times();
	$rtf_methodline .= "\n" . $methodline . rtf_newline_small()
	  if ($methodline);
	
	return $rtf_methodline;
  }

#############################################################################
#
# NAME:      rtf_subtitle
#
# ACTION:    takes a string and wraps it into a rtf formatted string in the 
#            subtitle style (bold helvetica).  
#            If more than one string is passed as an argument,
#            a tab is inserted before each of the following strings,
#            and they are set in plain times-roman, with no two on one line.
#
# RETURN:    returns the rtf formatted string
#
#############################################################################
sub rtf_subtitle
  {
	my ($subtitle)	   = shift (@_);
	my (@substrings)   = @_;
	my ($string)       = "";
	my ($rtf_subtitle) = "";
	
	$rtf_subtitle = '\pard \s17 \li4888 \fi-2771 \ri1007 \ql \tx4888 ';
	$rtf_subtitle .= rtf_setfont_helvetica();
	$rtf_subtitle .= rtf_boldify($subtitle);
	$rtf_subtitle .= rtf_setfont_times();

	foreach $string (@substrings) {
	  $rtf_subtitle .= "\t" . $string;
	  $rtf_subtitle .= rtf_newline()
	}
	$rtf_subtitle .= rtf_newline()
	  if (!(scalar (@substrings)));
	
	return $rtf_subtitle;
  }

#############################################################################
#
# NAME:      rtf_title
#
# ACTION:    Takes a string and wraps it into a rtf formatted string in the 
#            title style
#
# RETURN:    returns the rtf formatted string
#
#############################################################################
sub rtf_title
  {
	my ($title)		= $_[0];
	my ($rtf_title)	= "";

	$rtf_title = rtf_newline_small(3);
	$rtf_title .= '\pard \s5 \li2116 \fi0 \ri1007 \ql ';
	$rtf_title .= rtf_setfont_helvetica(28);
	$rtf_title .= rtf_boldify($title) . rtf_newline();
	$rtf_title .= rtf_newline_small(5);

	return $rtf_title;
  }


#############################################################################
#
# NAME:      rtf_head
#
# ACTION:    Takes a string and wraps it into a rtf formatted string in the
#            head style.
#
# RETURN:    returns the rtf formatted string.
#
#############################################################################
sub rtf_head
  {
	my ($head) = $_[0];
	my ($rtf_head);

    $rtf_head = '\li0 \fi0 \ri0 \ql \sb0 ' . rtf_setfont_times(12);
	$rtf_head .= "\n$head" . rtf_newline();
	
	return $rtf_head;
  }


#############################################################################
#
# NAME:      rtf_spacer
#
# ACTION:    returns a standard 5 line rtf spacer  
#
# RETURN:    a string representation of the spacer
#
#############################################################################
sub rtf_spacer
  {
	my ($spacer) = "";

	$spacer = '\pard \s13 \li1360 \fi0 \ri1007 \ql \fs16 ';
	$spacer .= rtf_newline(4);
	return $spacer;
  }

#############################################################################
#
# NAME:       rtf_fileheader
#
# ACTION:     Returns the text group that defines a rtf file header suitible
#             for the documentation format specified by autodoc
#
# RETURN:     The string containing the RTF group defining the file header
#
#############################################################################
sub rtf_fileheader
{
    local ($header);

    $header = '{\rtf0\ansi';
    $header .= '\paperw16228 \paperh18648 \margl-907 \margr0 \margt0 \margb0';

    return $header;
}


#############################################################################
#
# NAME:       rtf_filefooter
#
# ACTION:     Returns the text group that defines a rtf file footer suitible
#             for the documentation format specified by autodoc
#
# RETURN:     The string containing the RTF group defining the file footer
#
#############################################################################
sub rtf_filefooter
{
    local ($footer);

    $footer = '}';

    return $footer;
}


#############################################################################
#
# NAME:       rtf_fonttable
#
# ACTION:     Returns the text group that defines a font table suitible for
#             documentation in Rich Text Format
#
# RETURN:     The string containing the RTF group defining the font table
#
#############################################################################
sub rtf_fonttable
{
    local ($fonttbl);
    
    $fonttbl = '{\fonttbl';
    $fonttbl .= '\f0\fswiss Helvetica;';
    $fonttbl .= '\f1\froman Times;';
    $fonttbl .= '\f2\fmodern Courier;';
    $fonttbl .= '\f3\ftech Symbol;}';
    
    return $fonttbl;
}


#############################################################################
#
# NAME:       rtf_stylesheet
#
# ACTION:     Returns the text group that defines a style sheet suitible for
#             documentation in Rich Text Format
#
# RETURN:     The string containing the RTF group defining the style sheet
#
#############################################################################
sub rtf_stylesheet
{
    local ($ss);

    $ss = '{\stylesheet';
    $ss .= '{\s0 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250   ';
    $ss .= 'Body;}';
    $ss .= '{\s1 \li2493 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642   ';
    $ss .= 'BodyIndented;}';
    $ss .= '{\s2 \li2493 \fi-376 \ri1007 \ql \tx2494 \tx2872 \tx3250   ';
    $ss .= 'BulletLong;}';
    $ss .= '{\s3 \li2494 \fi-378 \ri1007 \ql   ';
    $ss .= 'BulletShort;}';
    $ss .= '{\s4 \li4888 \fi-2771 \ri1007 \ql \tx4888   ';
    $ss .= 'CategoryOf;}';
    $ss .= '{\s5 \li2116 \fi0 \ri1007 \ql   ';
    $ss .= 'ClassName;}';
    $ss .= '{\s6 \li2494 \fi0 \ri1007 \ql   ';
    $ss .= 'CodeExamp;}';
    $ss .= '{\s7 \li2872 \fi0 \ri1007 \ql   ';
    $ss .= 'CodeExamp2;}';
    $ss .= '{\s8 \li2116 \fi0 \ri1007 \ql   ';
    $ss .= 'CodeExampNoInd;}';
    $ss .= '{\s9 \li4888 \fi-2771 \ri1007 \ql \tx4888   ';
    $ss .= 'ConformsTo;}';
    $ss .= '{\s10 \li4888 \fi-2771 \ri1007 \ql   ';
    $ss .= 'DeclaredIn;}';
    $ss .= '{\s11 \li6148 \fi-4031 \ri1007 \ql \tx6148 \tx9676 \tx10180   ';
    $ss .= 'FirstVar/TypeLine1;}';
    $ss .= '{\s12 \li0 \fi0 \ri0 \ql \tx-25 \tx8290 \tx9172   ';
    $ss .= 'Footer;}';
    $ss .= '{\s13 \li1360 \fi0 \ri1007 \ql   ';
    $ss .= 'Heading;}';
    $ss .= '{\s14 \li4888 \fi-2771 \ri1007 \ql \tx4888   ';
    $ss .= 'ImplementedBy;}';
    $ss .= '{\s15 \li2116 \fi0 \ri1007 \ql   ';
    $ss .= 'Important;}';
    $ss .= '{\s16 \li4888 \fi-2771 \ri1007 \ql \tx4888   ';
    $ss .= 'Incorporates;}';
    $ss .= '{\s17 \li4888 \fi-2771 \ri1007 \ql   ';
    $ss .= 'InheritsFrom;}';
    $ss .= '{\s18 \li2116 \fi0 \ri1007 \ql \tx2872   ';
    $ss .= 'InstanceVar;}';
    $ss .= '{\s19 \li2493 \fi-376 \ri1007 \ql   ';
    $ss .= 'Method;}';
    $ss .= '{\s20 \li3249 \fi-756 \ri1007 \ql   ';
    $ss .= 'MethodDesc;}';
    $ss .= '{\s21 \li2493 \fi-376 \ri1007 \ql   ';
    $ss .= 'MethodFirst;}';
    $ss .= '{\s22 \li2116 \fi0 \ri1007 \ql   ';
    $ss .= 'Note;}';
    $ss .= '{\s23 \li2493 \fi-376 \ri1007 \ql \tx2494 \tx2872 \tx3250   ';
    $ss .= 'Num1Long;}';
    $ss .= '{\s24 \li2494 \fi-378 \ri1007 \ql   ';
    $ss .= 'Num1Short;}';
    $ss .= '{\s25 \li2493 \fi-376 \ri1007 \ql   ';
    $ss .= 'NumLong;}';
    $ss .= '{\s26 \li2494 \fi-378 \ri1007 \ql   ';
    $ss .= 'NumShort;}';
    $ss .= '{\s27 \li2116 \fi0 \ri1007 \ql   ';
    $ss .= 'SeeAlso;}';
    $ss .= '{\s28 \li2493 \fi-376 \ri1007 \ql   ';
    $ss .= 'Step;}';
    $ss .= '{\s29 \li2493 \fi-376 \ri1007 \ql   ';
    $ss .= 'Step1;}';
    $ss .= '{\s30 \li2116 \fi0 \ri1007 \ql   ';
    $ss .= 'SubHeading;}';
    $ss .= '{\s31 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180   ';
    $ss .= 'TableBody1;}';
    $ss .= '{\s32 \li6148 \fi-3654 \ri1007 \ql \tx6148 \tx10432   ';
    $ss .= 'TableBody2;}';
    $ss .= '{\s33 \li2493 \fi0 \ri1007 \ql \tx6148 \tx10180   ';
    $ss .= 'TableHead;}';
    $ss .= '{\s34 \li6652 \fi-503 \ri1007 \ql \tx9676 \tx10180   ';
    $ss .= 'Var/Type;}';
    $ss .= '{\s35 \li6148 \fi-4031 \ri1007 \ql \tx6148 \tx9676 \tx10180   ';
    $ss .= 'Var/TypeLine1;}';
    $ss .= '{\s36 \li2116 \fi-2015 \ri1007 \ql \tx806 \tx2116   ';
    $ss .= 'Warning;}';
    $ss .= '}';
    return $ss;
}


#############################################################################
#
# NAME:       rtf_format_method
#
# ACTION:     Process the method string passed in to format it with bold and 
#             italics.  Return the converted method string and a space 
#             separated list of arguments to the method.
#
# RETURN:     An array of two elements, the method as a formatted rtf string 
#             and a string with all of the arguments to the method separated
#             with spaces.
#
#############################################################################
sub rtf_format_method
  {
	my ($method)		 = $_[0];
	my ($rtf_method)	 = "";
	my ($marg)			 = "";
	my ($method_args)	 = "";
	my ($marg_separator) = " ";
	
	if ($method =~ m!^\-!) {
	  $rtf_method = rtf_emdash() . " ";
	} else {
	  $rtf_method = "+ ";
	}

	# check if the method line is so long it should be broken accross lines
	if (length($method) > 60) {
	  $marg_separator = rtf_newline() . "\t";
	}

	# remove the + or -
	$method =~ s!^[\+\-]!!;

	# boldify the method name AFTER the return value type casting (if any)
	if ($method =~ m!^\(!) {
	  $method =~ s!^(\([^\)]+\))\s*!!;
	  $rtf_method .= $1;
	}
	$method =~ s!^[^\:]*!!;
	$rtf_method .= rtf_boldify ($&);

	# format the method arguments, their types, and titles
    while ($method =~ m!^:!) {
	  
	  # extract the colon - oww!
	  $method =~ s!:!!;	
	  $rtf_method .= rtf_boldify (":");
	  
	  # extract the type casting (if any)
	  if ($method =~ m!^\s*\(!) {
	    $method =~ s!\s*(\([^\)]+\))\s*!!;
	    $rtf_method .= "$1";
	  }

	  # extract the argument and add it to the list of method arguments
	  $method =~ s!\s*(\S*)!!;
	  $marg = $1;
	  $method_args .= "$marg ";
	  $rtf_method .= rtf_italicize ($marg);
	  
	  # check for a title for the next argument
	  if ($method =~ m!:!) {
	    $method =~ s!([^:]*)!!;
	    $rtf_method .= $marg_separator . rtf_boldify ($1);
	  }		
    } 
	$rtf_method .= rtf_newline();
	
	return ($rtf_method, $method_args);
  }


#############################################################################
#
# NAME:       rtf_format_words
#
# ACTION:     Process string passed in to format special words as bold or 
#             italics.  Return the converted string.
#
# RETURN:     The formatted rtf string
#
#############################################################################
sub rtf_format_words
  {
    my ($text) = " $_[0] ";		# Add spaces to help with matching 
	my (@bold_words, @italic_words);

	@bold_words	  = Autodoc::DumpDocs::doc_bold_words();
	@italic_words = Autodoc::DumpDocs::doc_italic_words();

    # boldify text of the form #{the text}
    $text =~ s/\#\{([^\}]+)\}/\\b $1\\b0 /g;

    # italicize text of the form %{the text}
    $text =~ s/\%\{([^\}]+)\}/\\i $1\\i0 /g;

    # boldify words which start with a "#" in front of them
    $text =~ s/([^\\])\#([\w\:]+)/$1\\b $2\\b0 /g
	  while ($text =~ m/[^\\]\#[\w\:]+/);

    # italicize words which start with a "%" in front of them
    $text =~ s/([^\\])\%([\w]+)/$1\\i $2\\i0 /g
	  while ($text =~ m/[^\\]\%[\w]+/);
	
    # italicize words in the $format_italicwords array
    foreach $word (@italic_words) {
	  $text =~ s/(\W)$word(\W)/$1\\i $word\\i0 $2/g;
    }
	
    # boldify words in the $format_boldwords array
    foreach $word (@bold_words) {
	  $text =~ s/(\W)$word(\W)/$1\\b $word\\b0 $2/g;
    }

    # Reformat curly braces so they don't prematurely end the rtf doc.
    $text =~ s/\}/\\\}/g;

    # Reformat '\%' and '\#' to just '%' and '#'
    $text =~ s/\\([\#\%])/$1/g;
	
    # Remove the spaces we added before.
    $text =~ s/^\s+//;
    $text =~ s/\s+$//;
    return $text;
  }


#############################################################################
#
# NAME:       rtf_boldify
#
# ACTION:     Takes a string as input, and adds rtf formatting to set the 
#             string in bold. 
#
# RETURN:     Returns the rtf bold formatted string
#
#############################################################################
sub rtf_boldify
  {
	my ($string) = $_[0];
	return ("\\b " . $string . "\\b0 ");
  }


#############################################################################
#
# NAME:       rtf_italicize
#
# ACTION:     Takes a string as input, and adds rtf formatting to set the 
#             string in italics. 
#
# RETURN:     Returns the rtf italic formatted string
#
#############################################################################
sub rtf_italicize
  {
	my ($string) = $_[0];
	return ("\\i " . $string . "\\i0 ");
  }


#############################################################################
#
# NAME:       rtf_setfont_times
#
# ACTION:     Returns a string to change the rtf font to times-roman 14pt
#
#############################################################################
sub rtf_setfont_times
  {
	my ($fontsize) = 28;
	
	if (scalar (@_)) {
	  $fontsize = $_[0] * 2;
	}
	return ("\\f1 \\fs" . $fontsize . " ");
  }


#############################################################################
#
# NAME:       rtf_setfont_helvetica
#
# ACTION:     Returns a string to change the rtf font to helvetica 14pt
#             If an argument is passed, we set the font size to that point
#             size (which appears as double that font size in 'rtf-land')
#
#############################################################################
sub rtf_setfont_helvetica
  {
	my ($fontsize) = 28;
	
	if (scalar (@_)) {
	  $fontsize = $_[0] * 2;
	}
	return ("\\f0 \\fs" . $fontsize . " ");
  }



#############################################################################
#
# NAME:       rtf_copyright
#
# ACTION:     Returns the rtf string which produces a copyright symbol
#
#############################################################################
sub rtf_copyright
  {
	return "\\f3 \\'e3\\f1 ";
  }


#############################################################################
#
# NAME:       rtf_emdash
#
# ACTION:     Returns the rtf string which produces a em-dash symbol
#
#############################################################################
sub rtf_emdash
  {
	return "{\\f3 -}";
  }


#############################################################################
#
# NAME:       rtf_newline_micro
#
# ACTION:     Returns the rtf string which produces a 4pt font size newline
#             if a numerical argument is passed, that number of newlines is
#             output.
#
#############################################################################
sub rtf_newline_micro
  {
	my ($num) = "";
	my ($out) = "\\\n";

	if (scalar (@_) > 0) {
	  for ($num = $_[0]; $num > 1; $num --) {
		$out .= "\\\n";
	  }
	}
	return ("\{\\fs8 " . $out . "\}");
  }

#############################################################################
#
# NAME:       rtf_newline_small
#
# ACTION:     Returns the rtf string which produces a 8pt font size newline
#             if a numerical argument is passed, that number of newlines is
#             output.
#
#############################################################################
sub rtf_newline_small
  {
	my ($num) = "";
	my ($out) = "\\\n";

	if (scalar (@_) > 0) {
	  for ($num = $_[0]; $num > 1; $num --) {
		$out .= "\\\n";
	  }
	}
	return ("\{\\fs16 " . $out . "\}");
  }

#############################################################################
#
# NAME:       rtf_newline
#
# ACTION:     Returns the rtf string which produces a rtf formatted newline
#             if a numerical argument is passed, that number of newlines is
#             output.
#
#############################################################################
sub rtf_newline
  {
	my ($num) = "";
	my ($out) = "\\\n";

	if (scalar (@_) > 0) {
	  for ($num = $_[0]; $num > 1; $num --) {
		$out .= "\\\n";
	  }
	}
	return ($out);
  }

1;
