diff options
Diffstat (limited to 'mdoc2man.rb')
-rwxr-xr-x | mdoc2man.rb | 465 |
1 files changed, 0 insertions, 465 deletions
diff --git a/mdoc2man.rb b/mdoc2man.rb deleted file mode 100755 index 910b2e5745..0000000000 --- a/mdoc2man.rb +++ /dev/null @@ -1,465 +0,0 @@ -#!/usr/bin/env ruby -### -### mdoc2man - mdoc to man converter -### -### Quick usage: mdoc2man.rb < mdoc_manpage.8 > man_manpage.8 -### -### Ported from Perl by Akinori MUSHA. -### -### Copyright (c) 2001 University of Illinois Board of Trustees -### Copyright (c) 2001 Mark D. Roth -### Copyright (c) 2002, 2003 Akinori MUSHA -### All rights reserved. -### -### 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. All advertising materials mentioning features or use of this software -### must display the following acknowledgement: -### This product includes software developed by the University of -### Illinois at Urbana, and their contributors. -### 4. The University nor the names of their -### contributors may be used to endorse or promote products derived from -### this software without specific prior written permission. -### -### THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``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 TRUSTEES OR CONTRIBUTORS 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. -### -### $Id$ -### - -class Mdoc2Man - ANGLE = 1 - OPTION = 2 - PAREN = 3 - - RE_PUNCT = /^[!"'),\.\/:;>\?\]`]$/ - - def initialize - @name = @date = @id = nil - @refauthors = @reftitle = @refissue = @refdate = @refopt = nil - - @optlist = 0 ### 1 = bullet, 2 = enum, 3 = tag, 4 = item - @oldoptlist = 0 - @nospace = 0 ### 0, 1, 2 - @enum = 0 - @synopsis = true - @reference = false - @ext = false - @extopt = false - @literal = false - end - - def mdoc2man(i, o) - i.each { |line| - if /^\./ !~ line - o.print line - o.print ".br\n" if @literal - next - end - - line.slice!(0, 1) - - next if /\\"/ =~ line - - line = parse_macro(line) and o.print line - } - - initialize - end - - def parse_macro(line) - words = line.split - retval = '' - - quote = [] - dl = false - - while word = words.shift - case word - when RE_PUNCT - while q = quote.pop - case q - when OPTION - retval << ']' - when PAREN - retval << ')' - when ANGLE - retval << '>' - end - end - retval << word - next - when 'Li', 'Pf' - @nospace = 1 - next - when 'Xo' - @ext = true - retval << ' ' unless retval.empty? || /[\n ]\z/ =~ retval - next - when 'Xc' - @ext = false - retval << "\n" unless @extopt - break - when 'Bd' - @literal = true if words[0] == '-literal' - retval << "\n" - break - when 'Ed' - @literal = false - break - when 'Ns' - @nospace = 1 if @nospace == 0 - retval.chomp!(' ') - next - when 'No' - retval.chomp!(' ') - retval << words.shift - next - when 'Dq' - retval << '``' - begin - retval << words.shift << ' ' - end until words.empty? || RE_PUNCT =~ words[0] - retval.chomp!(' ') - retval << '\'\'' - @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0] - next - when 'Sq', 'Ql' - retval << '`' << words.shift << '\'' - @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0] - next - # when 'Ic' - # retval << '\\fB' << words.shift << '\\fP' - # next - when 'Oo' - #retval << "[\\c\n" - @extopt = true - @nospace = 1 if @nospace == 0 - retval << '[' - next - when 'Oc' - @extopt = false - retval << ']' - next - when 'Ao' - @nospace = 1 if @nospace == 0 - retval << '<' - next - when 'Ac' - retval << '>' - next - end - - retval << ' ' if @nospace == 0 && !(retval.empty? || /[\n ]\z/ =~ retval) - @nospace = 0 if @nospace == 1 - - case word - when 'Dd' - @date = words.join(' ') - return nil - when 'Dt' - if words.size >= 2 && words[1] == '""' && - /^(.*)\(([0-9])\)$/ =~ words[0] - words[0] = $1 - words[1] = $2 - end - @id = words.join(' ') - return nil - when 'Os' - retval << '.TH ' << @id << ' "' << @date << '" "' << - words.join(' ') << '"' - break - when 'Sh' - retval << '.SH' - @synopsis = (words[0] == 'SYNOPSIS') - next - when 'Xr' - retval << '\\fB' << words.shift << - '\\fP(' << words.shift << ')' << words.shift - break - when 'Rs' - @refauthors = [] - @reftitle = '' - @refissue = '' - @refdate = '' - @refopt = '' - @reference = true - break - when 'Re' - retval << "\n" - - # authors - while @refauthors.size > 1 - retval << @refauthors.shift << ', ' - end - retval << 'and ' unless retval.empty? - retval << @refauthors.shift - - # title - retval << ', \\fI' << @reftitle << '\\fP' - - # issue - retval << ', ' << @refissue unless @refissue.empty? - - # date - retval << ', ' << @refdate unless @refdate.empty? - - # optional info - retval << ', ' << @refopt unless @refopt.empty? - - retval << ".\n" - - @reference = false - break - when 'An' - next - when 'Dl' - retval << ".nf\n" << '\\& ' - dl = true - next - when 'Ux' - retval << "UNIX" - next - end - - if @reference - case word - when '%A' - @refauthors.unshift(words.join(' ')) - break - when '%T' - @reftitle = words.join(' ') - @reftitle.sub!(/^"/, '') - @reftitle.sub!(/"$/, '') - break - when '%N' - @refissue = words.join(' ') - break - when '%D' - @refdate = words.join(' ') - break - when '%O' - @refopt = words.join(' ') - break - end - end - - case word - when 'Nm' - name = words.empty? ? @name : words.shift - @name ||= name - retval << ".br\n" if @synopsis - retval << "\\fB" << name << "\\fP" - @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0] - next - when 'Nd' - retval << '\\-' - next - when 'Fl' - retval << '\\fB\\-' << words.shift << '\\fP' - @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0] - next - when 'Ar' - retval << '\\fI' - if words.empty? - retval << 'file ...\\fP' - else - retval << words.shift << '\\fP' - while words[0] == '|' - retval << ' ' << words.shift << ' \\fI' << words.shift << '\\fP' - end - @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0] - next - end - when 'Cm' - retval << '\\fB' << words.shift << '\\fP' - while RE_PUNCT =~ words[0] - retval << words.shift - end - next - when 'Op' - quote << OPTION - @nospace = 1 if @nospace == 0 - retval << '[' - # words.push(words.pop + ']') - next - when 'Aq' - quote << ANGLE - @nospace = 1 if @nospace == 0 - retval << '<' - # words.push(words.pop + '>') - next - when 'Pp' - retval << "\n" - next - when 'Ss' - retval << '.SS' - next - end - - if word == 'Pa' && !quote.include?(OPTION) - retval << '\\fI' - retval << '\\&' if /^\./ =~ words[0] - retval << words.shift << '\\fP' - while RE_PUNCT =~ words[0] - retval << words.shift - end - # @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0] - next - end - - case word - when 'Dv' - retval << '.BR' - next - when 'Em', 'Ev' - retval << '.IR' - next - when 'Pq' - retval << '(' - @nospace = 1 - quote << PAREN - next - when 'Sx', 'Sy' - retval << '.B ' << words.join(' ') - break - when 'Ic' - retval << '\\fB' - until words.empty? || RE_PUNCT =~ words[0] - case words[0] - when 'Op' - words.shift - retval << '[' - words.push(words.pop + ']') - next - when 'Aq' - words.shift - retval << '<' - words.push(words.pop + '>') - next - when 'Ar' - words.shift - retval << '\\fI' << words.shift << '\\fP' - else - retval << words.shift - end - - retval << ' ' if @nospace == 0 - end - - retval.chomp!(' ') - retval << '\\fP' - retval << words.shift unless words.empty? - break - when 'Bl' - @oldoptlist = @optlist - - case words[0] - when '-bullet' - @optlist = 1 - when '-enum' - @optlist = 2 - @enum = 0 - when '-tag' - @optlist = 3 - when '-item' - @optlist = 4 - end - - break - when 'El' - @optlist = @oldoptlist - next - end - - if @optlist != 0 && word == 'It' - case @optlist - when 1 - # bullets - retval << '.IP \\(bu' - when 2 - # enum - @enum += 1 - retval << '.IP ' << @enum << '.' - when 3 - # tags - retval << ".TP\n" - case words[0] - when 'Pa', 'Ev' - words.shift - retval << '.B' - end - when 4 - # item - retval << ".IP\n" - end - - next - end - - case word - when 'Sm' - case words[0] - when 'off' - @nospace = 2 - when 'on' - # retval << "\n" - @nospace = 0 - end - words.shift - next - end - - retval << word - end - - return nil if retval == '.' - - retval.sub!(/\A\.([^a-zA-Z])/, "\\1") - # retval.chomp!(' ') - - while q = quote.pop - case q - when OPTION - retval << ']' - when PAREN - retval << ')' - when ANGLE - retval << '>' - end - end - - # retval << ' ' unless @nospace == 0 || retval.empty? || /\n\z/ =~ retval - - retval << ' ' unless !@ext || @extopt || / $/ =~ retval - - retval << "\n" unless @ext || @extopt || retval.empty? || /\n\z/ =~ retval - - retval << ".fi\n" if dl - - return retval - end - - def self.mdoc2man(i, o) - new.mdoc2man(i, o) - end -end - -if $0 == __FILE__ - Mdoc2Man.mdoc2man(ARGF, STDOUT) -end |