113498266Sopenharmony_ci#!/usr/bin/env perl
213498266Sopenharmony_ci#***************************************************************************
313498266Sopenharmony_ci#                                  _   _ ____  _
413498266Sopenharmony_ci#  Project                     ___| | | |  _ \| |
513498266Sopenharmony_ci#                             / __| | | | |_) | |
613498266Sopenharmony_ci#                            | (__| |_| |  _ <| |___
713498266Sopenharmony_ci#                             \___|\___/|_| \_\_____|
813498266Sopenharmony_ci#
913498266Sopenharmony_ci# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
1013498266Sopenharmony_ci#
1113498266Sopenharmony_ci# This software is licensed as described in the file COPYING, which
1213498266Sopenharmony_ci# you should have received as part of this distribution. The terms
1313498266Sopenharmony_ci# are also available at https://curl.se/docs/copyright.html.
1413498266Sopenharmony_ci#
1513498266Sopenharmony_ci# You may opt to use, copy, modify, merge, publish, distribute and/or sell
1613498266Sopenharmony_ci# copies of the Software, and permit persons to whom the Software is
1713498266Sopenharmony_ci# furnished to do so, under the terms of the COPYING file.
1813498266Sopenharmony_ci#
1913498266Sopenharmony_ci# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
2013498266Sopenharmony_ci# KIND, either express or implied.
2113498266Sopenharmony_ci#
2213498266Sopenharmony_ci# SPDX-License-Identifier: curl
2313498266Sopenharmony_ci#
2413498266Sopenharmony_ci###########################################################################
2513498266Sopenharmony_ci
2613498266Sopenharmony_ci=begin comment
2713498266Sopenharmony_ci
2813498266Sopenharmony_ciThis script converts an nroff file to curldown
2913498266Sopenharmony_ci
3013498266Sopenharmony_ciExample: cd2nroff [options] <file.md> > <file.3>
3113498266Sopenharmony_ci
3213498266Sopenharmony_ciNote: when converting .nf sections, this tool does not know if the
3313498266Sopenharmony_cisection is code or just regular quotes. It then assumes and uses ~~~c
3413498266Sopenharmony_cifor code.
3513498266Sopenharmony_ci
3613498266Sopenharmony_ci=end comment
3713498266Sopenharmony_ci=cut
3813498266Sopenharmony_ci
3913498266Sopenharmony_cimy $nroff2cd = "0.1"; # to keep check
4013498266Sopenharmony_ci
4113498266Sopenharmony_cisub single {
4213498266Sopenharmony_ci    my ($f)=@_;
4313498266Sopenharmony_ci    open(F, "<:crlf", "$f") ||
4413498266Sopenharmony_ci        return 1;
4513498266Sopenharmony_ci    my $line;
4613498266Sopenharmony_ci    my $title;
4713498266Sopenharmony_ci    my $section;
4813498266Sopenharmony_ci    my $source;
4913498266Sopenharmony_ci    my @seealso;
5013498266Sopenharmony_ci    my @desc;
5113498266Sopenharmony_ci    my $header; # non-zero when TH is passed
5213498266Sopenharmony_ci    my $quote = 0; # quote state
5313498266Sopenharmony_ci    while(<F>) {
5413498266Sopenharmony_ci        $line++;
5513498266Sopenharmony_ci        my $d = $_;
5613498266Sopenharmony_ci        if($_ =~ /^.\\\"/) {
5713498266Sopenharmony_ci            # a comment we can ignore
5813498266Sopenharmony_ci            next;
5913498266Sopenharmony_ci        }
6013498266Sopenharmony_ci        if(!$header) {
6113498266Sopenharmony_ci            if($d =~ /.so (.*)/) {
6213498266Sopenharmony_ci                # this is basically an include, so do that
6313498266Sopenharmony_ci                my $f = $1;
6413498266Sopenharmony_ci                # remove leading directory
6513498266Sopenharmony_ci                $f =~ s/(.*?\/)//;
6613498266Sopenharmony_ci                close(F);
6713498266Sopenharmony_ci                open(F, "<:crlf", "$f") || return 1;
6813498266Sopenharmony_ci            }
6913498266Sopenharmony_ci            if($d =~ /^\.TH ([^ ]*) (\d) \"(.*?)\" ([^ \n]*)/) {
7013498266Sopenharmony_ci                # header, this needs to be the first thing after leading comments
7113498266Sopenharmony_ci                $title = $1;
7213498266Sopenharmony_ci                $section = $2;
7313498266Sopenharmony_ci                # date is $3
7413498266Sopenharmony_ci                $source = $4;
7513498266Sopenharmony_ci                # if there are enclosing quotes around source, remove them
7613498266Sopenharmony_ci                $source =~ s/[\"\'](.*)[\"\']\z/$1/;
7713498266Sopenharmony_ci                $header = 1;
7813498266Sopenharmony_ci
7913498266Sopenharmony_ci            print <<HEAD
8013498266Sopenharmony_ci---
8113498266Sopenharmony_cic: Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
8213498266Sopenharmony_ciSPDX-License-Identifier: curl
8313498266Sopenharmony_ciTitle: $title
8413498266Sopenharmony_ciSection: $section
8513498266Sopenharmony_ciSource: $source
8613498266Sopenharmony_ciHEAD
8713498266Sopenharmony_ci                ;
8813498266Sopenharmony_ci            }
8913498266Sopenharmony_ci            next;
9013498266Sopenharmony_ci        }
9113498266Sopenharmony_ci
9213498266Sopenharmony_ci        if($quote) {
9313498266Sopenharmony_ci            if($d =~ /^\.SH/) {
9413498266Sopenharmony_ci                #end of quote without an .fi
9513498266Sopenharmony_ci                $quote = 0;
9613498266Sopenharmony_ci                push @desc, "~~~\n";
9713498266Sopenharmony_ci            }
9813498266Sopenharmony_ci            elsif($d =~ /^\.fi/) {
9913498266Sopenharmony_ci                #end of quote
10013498266Sopenharmony_ci                $quote = 0;
10113498266Sopenharmony_ci                push @desc, "~~~\n";
10213498266Sopenharmony_ci                next;
10313498266Sopenharmony_ci            }
10413498266Sopenharmony_ci            else {
10513498266Sopenharmony_ci                # double-backslashes converted to single ones
10613498266Sopenharmony_ci                $d =~ s/\\\\/\\/g;
10713498266Sopenharmony_ci                push @desc, $d;
10813498266Sopenharmony_ci                next;
10913498266Sopenharmony_ci            }
11013498266Sopenharmony_ci        }
11113498266Sopenharmony_ci        if($d =~ /^\.SH (.*)/) {
11213498266Sopenharmony_ci            my $word = $1;
11313498266Sopenharmony_ci            # if there are enclosing quotes, remove them first
11413498266Sopenharmony_ci            $word =~ s/[\"\'](.*)[\"\']\z/$1/;
11513498266Sopenharmony_ci            if($word eq "SEE ALSO") {
11613498266Sopenharmony_ci                # we just slurp up this section
11713498266Sopenharmony_ci                next;
11813498266Sopenharmony_ci            }
11913498266Sopenharmony_ci            push @desc, "\n# $word\n\n";
12013498266Sopenharmony_ci        }
12113498266Sopenharmony_ci        elsif($d =~ /^\.(RS|RE)/) {
12213498266Sopenharmony_ci            # ignore these
12313498266Sopenharmony_ci        }
12413498266Sopenharmony_ci        elsif($d =~ /^\.IP (.*)/) {
12513498266Sopenharmony_ci            my $word = $1;
12613498266Sopenharmony_ci            # if there are enclosing quotes, remove them first
12713498266Sopenharmony_ci            $word =~ s/[\"\'](.*)[\"\']\z/$1/;
12813498266Sopenharmony_ci            push @desc, "\n## $word\n\n";
12913498266Sopenharmony_ci        }
13013498266Sopenharmony_ci        elsif($d =~ /^\.IP/) {
13113498266Sopenharmony_ci            # .IP with no text we just skip
13213498266Sopenharmony_ci        }
13313498266Sopenharmony_ci        elsif($d =~ /^\.BR (.*)/) {
13413498266Sopenharmony_ci            # only used for SEE ALSO
13513498266Sopenharmony_ci            my $word = $1;
13613498266Sopenharmony_ci            # remove trailing comma
13713498266Sopenharmony_ci            $word =~ s/,\z//;
13813498266Sopenharmony_ci
13913498266Sopenharmony_ci            for my $s (split(/,/, $word)) {
14013498266Sopenharmony_ci                # remove all double quotes
14113498266Sopenharmony_ci                $s =~ s/\"//g;
14213498266Sopenharmony_ci                # tream leading whitespace
14313498266Sopenharmony_ci                $s =~ s/^ +//g;
14413498266Sopenharmony_ci                push @seealso, $s;
14513498266Sopenharmony_ci            }
14613498266Sopenharmony_ci        }
14713498266Sopenharmony_ci        elsif($d =~ /^\.I (.*)/) {
14813498266Sopenharmony_ci            push @desc, "*$1*\n";
14913498266Sopenharmony_ci        }
15013498266Sopenharmony_ci        elsif($d =~ /^\.B (.*)/) {
15113498266Sopenharmony_ci            push @desc, "**$1**\n";
15213498266Sopenharmony_ci        }
15313498266Sopenharmony_ci        elsif($d =~ /^\.nf/) {
15413498266Sopenharmony_ci            push @desc, "~~~c\n";
15513498266Sopenharmony_ci            $quote = 1;
15613498266Sopenharmony_ci        }
15713498266Sopenharmony_ci        else {
15813498266Sopenharmony_ci            # embolden
15913498266Sopenharmony_ci            $d =~ s/\\fB(.*?)\\fP/**$1**/g;
16013498266Sopenharmony_ci            # links to "curl.*()" are left bare since cd2nroff handles them
16113498266Sopenharmony_ci            # specially
16213498266Sopenharmony_ci            $d =~ s/\\fI(curl.*?\(3\))\\fP/$1/ig;
16313498266Sopenharmony_ci            # emphasize
16413498266Sopenharmony_ci            $d =~ s/\\fI(.*?)\\fP/*$1*/g;
16513498266Sopenharmony_ci            # emphasize on a split line
16613498266Sopenharmony_ci            $d =~ s/\\fI/*/g;
16713498266Sopenharmony_ci            # bold on a split line
16813498266Sopenharmony_ci            $d =~ s/\\fB/**/g;
16913498266Sopenharmony_ci            # remove backslash amp
17013498266Sopenharmony_ci            $d =~ s/\\&//g;
17113498266Sopenharmony_ci            # remove backslashes
17213498266Sopenharmony_ci            $d =~ s/\\//g;
17313498266Sopenharmony_ci            # fix single quotes
17413498266Sopenharmony_ci            $d =~ s/\(aq/'/g;
17513498266Sopenharmony_ci            # fix double quotes
17613498266Sopenharmony_ci            $d =~ s/\(dq/\"/g;
17713498266Sopenharmony_ci            push @desc, $d;
17813498266Sopenharmony_ci        }
17913498266Sopenharmony_ci    }
18013498266Sopenharmony_ci    close(F);
18113498266Sopenharmony_ci
18213498266Sopenharmony_ci    print "See-also:\n";
18313498266Sopenharmony_ci    for my $s (sort @seealso) {
18413498266Sopenharmony_ci        print "  - $s\n" if($s);
18513498266Sopenharmony_ci    }
18613498266Sopenharmony_ci    print "---\n";
18713498266Sopenharmony_ci    print @desc;
18813498266Sopenharmony_ci
18913498266Sopenharmony_ci    return !$header;
19013498266Sopenharmony_ci}
19113498266Sopenharmony_ci
19213498266Sopenharmony_ciexit single($ARGV[0]);
19313498266Sopenharmony_ci
194