xref: /aosp_15_r20/external/curl/scripts/nroff2cd (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker#!/usr/bin/env perl
2*6236dae4SAndroid Build Coastguard Worker#***************************************************************************
3*6236dae4SAndroid Build Coastguard Worker#                                  _   _ ____  _
4*6236dae4SAndroid Build Coastguard Worker#  Project                     ___| | | |  _ \| |
5*6236dae4SAndroid Build Coastguard Worker#                             / __| | | | |_) | |
6*6236dae4SAndroid Build Coastguard Worker#                            | (__| |_| |  _ <| |___
7*6236dae4SAndroid Build Coastguard Worker#                             \___|\___/|_| \_\_____|
8*6236dae4SAndroid Build Coastguard Worker#
9*6236dae4SAndroid Build Coastguard Worker# Copyright (C) Daniel Stenberg, <[email protected]>, et al.
10*6236dae4SAndroid Build Coastguard Worker#
11*6236dae4SAndroid Build Coastguard Worker# This software is licensed as described in the file COPYING, which
12*6236dae4SAndroid Build Coastguard Worker# you should have received as part of this distribution. The terms
13*6236dae4SAndroid Build Coastguard Worker# are also available at https://curl.se/docs/copyright.html.
14*6236dae4SAndroid Build Coastguard Worker#
15*6236dae4SAndroid Build Coastguard Worker# You may opt to use, copy, modify, merge, publish, distribute and/or sell
16*6236dae4SAndroid Build Coastguard Worker# copies of the Software, and permit persons to whom the Software is
17*6236dae4SAndroid Build Coastguard Worker# furnished to do so, under the terms of the COPYING file.
18*6236dae4SAndroid Build Coastguard Worker#
19*6236dae4SAndroid Build Coastguard Worker# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20*6236dae4SAndroid Build Coastguard Worker# KIND, either express or implied.
21*6236dae4SAndroid Build Coastguard Worker#
22*6236dae4SAndroid Build Coastguard Worker# SPDX-License-Identifier: curl
23*6236dae4SAndroid Build Coastguard Worker#
24*6236dae4SAndroid Build Coastguard Worker###########################################################################
25*6236dae4SAndroid Build Coastguard Worker
26*6236dae4SAndroid Build Coastguard Worker=begin comment
27*6236dae4SAndroid Build Coastguard Worker
28*6236dae4SAndroid Build Coastguard WorkerThis script converts an nroff file to curldown
29*6236dae4SAndroid Build Coastguard Worker
30*6236dae4SAndroid Build Coastguard WorkerExample: cd2nroff [options] <file.md> > <file.3>
31*6236dae4SAndroid Build Coastguard Worker
32*6236dae4SAndroid Build Coastguard WorkerNote: when converting .nf sections, this tool does not know if the
33*6236dae4SAndroid Build Coastguard Workersection is code or just regular quotes. It then assumes and uses ~~~c
34*6236dae4SAndroid Build Coastguard Workerfor code.
35*6236dae4SAndroid Build Coastguard Worker
36*6236dae4SAndroid Build Coastguard Worker=end comment
37*6236dae4SAndroid Build Coastguard Worker=cut
38*6236dae4SAndroid Build Coastguard Worker
39*6236dae4SAndroid Build Coastguard Workermy $nroff2cd = "0.1"; # to keep check
40*6236dae4SAndroid Build Coastguard Worker
41*6236dae4SAndroid Build Coastguard Workersub single {
42*6236dae4SAndroid Build Coastguard Worker    my ($f)=@_;
43*6236dae4SAndroid Build Coastguard Worker    open(F, "<:crlf", "$f") ||
44*6236dae4SAndroid Build Coastguard Worker        return 1;
45*6236dae4SAndroid Build Coastguard Worker    my $line;
46*6236dae4SAndroid Build Coastguard Worker    my $title;
47*6236dae4SAndroid Build Coastguard Worker    my $section;
48*6236dae4SAndroid Build Coastguard Worker    my $source;
49*6236dae4SAndroid Build Coastguard Worker    my @seealso;
50*6236dae4SAndroid Build Coastguard Worker    my @desc;
51*6236dae4SAndroid Build Coastguard Worker    my $header; # non-zero when TH is passed
52*6236dae4SAndroid Build Coastguard Worker    my $quote = 0; # quote state
53*6236dae4SAndroid Build Coastguard Worker    while(<F>) {
54*6236dae4SAndroid Build Coastguard Worker        $line++;
55*6236dae4SAndroid Build Coastguard Worker        my $d = $_;
56*6236dae4SAndroid Build Coastguard Worker        if($_ =~ /^.\\\"/) {
57*6236dae4SAndroid Build Coastguard Worker            # a comment we can ignore
58*6236dae4SAndroid Build Coastguard Worker            next;
59*6236dae4SAndroid Build Coastguard Worker        }
60*6236dae4SAndroid Build Coastguard Worker        if(!$header) {
61*6236dae4SAndroid Build Coastguard Worker            if($d =~ /.so (.*)/) {
62*6236dae4SAndroid Build Coastguard Worker                # this is basically an include, so do that
63*6236dae4SAndroid Build Coastguard Worker                my $f = $1;
64*6236dae4SAndroid Build Coastguard Worker                # remove leading directory
65*6236dae4SAndroid Build Coastguard Worker                $f =~ s/(.*?\/)//;
66*6236dae4SAndroid Build Coastguard Worker                close(F);
67*6236dae4SAndroid Build Coastguard Worker                open(F, "<:crlf", "$f") || return 1;
68*6236dae4SAndroid Build Coastguard Worker            }
69*6236dae4SAndroid Build Coastguard Worker            if($d =~ /^\.TH ([^ ]*) (\d) \"(.*?)\" ([^ \n]*)/) {
70*6236dae4SAndroid Build Coastguard Worker                # header, this needs to be the first thing after leading comments
71*6236dae4SAndroid Build Coastguard Worker                $title = $1;
72*6236dae4SAndroid Build Coastguard Worker                $section = $2;
73*6236dae4SAndroid Build Coastguard Worker                # date is $3
74*6236dae4SAndroid Build Coastguard Worker                $source = $4;
75*6236dae4SAndroid Build Coastguard Worker                # if there are enclosing quotes around source, remove them
76*6236dae4SAndroid Build Coastguard Worker                $source =~ s/[\"\'](.*)[\"\']\z/$1/;
77*6236dae4SAndroid Build Coastguard Worker                $header = 1;
78*6236dae4SAndroid Build Coastguard Worker
79*6236dae4SAndroid Build Coastguard Worker            print <<HEAD
80*6236dae4SAndroid Build Coastguard Worker---
81*6236dae4SAndroid Build Coastguard Workerc: Copyright (C) Daniel Stenberg, <[email protected]>, et al.
82*6236dae4SAndroid Build Coastguard WorkerSPDX-License-Identifier: curl
83*6236dae4SAndroid Build Coastguard WorkerTitle: $title
84*6236dae4SAndroid Build Coastguard WorkerSection: $section
85*6236dae4SAndroid Build Coastguard WorkerSource: $source
86*6236dae4SAndroid Build Coastguard WorkerHEAD
87*6236dae4SAndroid Build Coastguard Worker                ;
88*6236dae4SAndroid Build Coastguard Worker            }
89*6236dae4SAndroid Build Coastguard Worker            next;
90*6236dae4SAndroid Build Coastguard Worker        }
91*6236dae4SAndroid Build Coastguard Worker
92*6236dae4SAndroid Build Coastguard Worker        if($quote) {
93*6236dae4SAndroid Build Coastguard Worker            if($d =~ /^\.SH/) {
94*6236dae4SAndroid Build Coastguard Worker                #end of quote without an .fi
95*6236dae4SAndroid Build Coastguard Worker                $quote = 0;
96*6236dae4SAndroid Build Coastguard Worker                push @desc, "~~~\n";
97*6236dae4SAndroid Build Coastguard Worker            }
98*6236dae4SAndroid Build Coastguard Worker            elsif($d =~ /^\.fi/) {
99*6236dae4SAndroid Build Coastguard Worker                #end of quote
100*6236dae4SAndroid Build Coastguard Worker                $quote = 0;
101*6236dae4SAndroid Build Coastguard Worker                push @desc, "~~~\n";
102*6236dae4SAndroid Build Coastguard Worker                next;
103*6236dae4SAndroid Build Coastguard Worker            }
104*6236dae4SAndroid Build Coastguard Worker            else {
105*6236dae4SAndroid Build Coastguard Worker                # double-backslashes converted to single ones
106*6236dae4SAndroid Build Coastguard Worker                $d =~ s/\\\\/\\/g;
107*6236dae4SAndroid Build Coastguard Worker                push @desc, $d;
108*6236dae4SAndroid Build Coastguard Worker                next;
109*6236dae4SAndroid Build Coastguard Worker            }
110*6236dae4SAndroid Build Coastguard Worker        }
111*6236dae4SAndroid Build Coastguard Worker        if($d =~ /^\.SH (.*)/) {
112*6236dae4SAndroid Build Coastguard Worker            my $word = $1;
113*6236dae4SAndroid Build Coastguard Worker            # if there are enclosing quotes, remove them first
114*6236dae4SAndroid Build Coastguard Worker            $word =~ s/[\"\'](.*)[\"\']\z/$1/;
115*6236dae4SAndroid Build Coastguard Worker            if($word eq "SEE ALSO") {
116*6236dae4SAndroid Build Coastguard Worker                # we just slurp up this section
117*6236dae4SAndroid Build Coastguard Worker                next;
118*6236dae4SAndroid Build Coastguard Worker            }
119*6236dae4SAndroid Build Coastguard Worker            push @desc, "\n# $word\n\n";
120*6236dae4SAndroid Build Coastguard Worker        }
121*6236dae4SAndroid Build Coastguard Worker        elsif($d =~ /^\.(RS|RE)/) {
122*6236dae4SAndroid Build Coastguard Worker            # ignore these
123*6236dae4SAndroid Build Coastguard Worker        }
124*6236dae4SAndroid Build Coastguard Worker        elsif($d =~ /^\.IP (.*)/) {
125*6236dae4SAndroid Build Coastguard Worker            my $word = $1;
126*6236dae4SAndroid Build Coastguard Worker            # if there are enclosing quotes, remove them first
127*6236dae4SAndroid Build Coastguard Worker            $word =~ s/[\"\'](.*)[\"\']\z/$1/;
128*6236dae4SAndroid Build Coastguard Worker            push @desc, "\n## $word\n\n";
129*6236dae4SAndroid Build Coastguard Worker        }
130*6236dae4SAndroid Build Coastguard Worker        elsif($d =~ /^\.IP/) {
131*6236dae4SAndroid Build Coastguard Worker            # .IP with no text we just skip
132*6236dae4SAndroid Build Coastguard Worker        }
133*6236dae4SAndroid Build Coastguard Worker        elsif($d =~ /^\.BR (.*)/) {
134*6236dae4SAndroid Build Coastguard Worker            # only used for SEE ALSO
135*6236dae4SAndroid Build Coastguard Worker            my $word = $1;
136*6236dae4SAndroid Build Coastguard Worker            # remove trailing comma
137*6236dae4SAndroid Build Coastguard Worker            $word =~ s/,\z//;
138*6236dae4SAndroid Build Coastguard Worker
139*6236dae4SAndroid Build Coastguard Worker            for my $s (split(/,/, $word)) {
140*6236dae4SAndroid Build Coastguard Worker                # remove all double quotes
141*6236dae4SAndroid Build Coastguard Worker                $s =~ s/\"//g;
142*6236dae4SAndroid Build Coastguard Worker                # tream leading whitespace
143*6236dae4SAndroid Build Coastguard Worker                $s =~ s/^ +//g;
144*6236dae4SAndroid Build Coastguard Worker                push @seealso, $s;
145*6236dae4SAndroid Build Coastguard Worker            }
146*6236dae4SAndroid Build Coastguard Worker        }
147*6236dae4SAndroid Build Coastguard Worker        elsif($d =~ /^\.I (.*)/) {
148*6236dae4SAndroid Build Coastguard Worker            push @desc, "*$1*\n";
149*6236dae4SAndroid Build Coastguard Worker        }
150*6236dae4SAndroid Build Coastguard Worker        elsif($d =~ /^\.B (.*)/) {
151*6236dae4SAndroid Build Coastguard Worker            push @desc, "**$1**\n";
152*6236dae4SAndroid Build Coastguard Worker        }
153*6236dae4SAndroid Build Coastguard Worker        elsif($d =~ /^\.nf/) {
154*6236dae4SAndroid Build Coastguard Worker            push @desc, "~~~c\n";
155*6236dae4SAndroid Build Coastguard Worker            $quote = 1;
156*6236dae4SAndroid Build Coastguard Worker        }
157*6236dae4SAndroid Build Coastguard Worker        else {
158*6236dae4SAndroid Build Coastguard Worker            # embolden
159*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\\fB(.*?)\\fP/**$1**/g;
160*6236dae4SAndroid Build Coastguard Worker            # links to "curl.*()" are left bare since cd2nroff handles them
161*6236dae4SAndroid Build Coastguard Worker            # specially
162*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\\fI(curl.*?\(3\))\\fP/$1/ig;
163*6236dae4SAndroid Build Coastguard Worker            # emphasize
164*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\\fI(.*?)\\fP/*$1*/g;
165*6236dae4SAndroid Build Coastguard Worker            # emphasize on a split line
166*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\\fI/*/g;
167*6236dae4SAndroid Build Coastguard Worker            # bold on a split line
168*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\\fB/**/g;
169*6236dae4SAndroid Build Coastguard Worker            # remove backslash amp
170*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\\&//g;
171*6236dae4SAndroid Build Coastguard Worker            # remove backslashes
172*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\\//g;
173*6236dae4SAndroid Build Coastguard Worker            # fix single quotes
174*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\(aq/'/g;
175*6236dae4SAndroid Build Coastguard Worker            # fix double quotes
176*6236dae4SAndroid Build Coastguard Worker            $d =~ s/\(dq/\"/g;
177*6236dae4SAndroid Build Coastguard Worker            push @desc, $d;
178*6236dae4SAndroid Build Coastguard Worker        }
179*6236dae4SAndroid Build Coastguard Worker    }
180*6236dae4SAndroid Build Coastguard Worker    close(F);
181*6236dae4SAndroid Build Coastguard Worker
182*6236dae4SAndroid Build Coastguard Worker    print "See-also:\n";
183*6236dae4SAndroid Build Coastguard Worker    for my $s (sort @seealso) {
184*6236dae4SAndroid Build Coastguard Worker        print "  - $s\n" if($s);
185*6236dae4SAndroid Build Coastguard Worker    }
186*6236dae4SAndroid Build Coastguard Worker    print "---\n";
187*6236dae4SAndroid Build Coastguard Worker    print @desc;
188*6236dae4SAndroid Build Coastguard Worker
189*6236dae4SAndroid Build Coastguard Worker    return !$header;
190*6236dae4SAndroid Build Coastguard Worker}
191*6236dae4SAndroid Build Coastguard Worker
192*6236dae4SAndroid Build Coastguard Workerexit single($ARGV[0]);
193