Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,14 @@ thanksnum.gen: $(DOCROOT)/THANKS
thanks.gen: $(DOCROOT)/THANKS
grep '^[^ ]' $< | sort | sed -e 's/ /\&nbsp;/g' -e 's/-/\&\#8209/g' -e '$$!s/$$/\&nbsp;\&middot;/' > $@

faq.html: _faq.shtml $(MAINPARTS) faq.gen
faq.html: _faq.shtml $(MAINPARTS) faq.gen faq-content.gen
$(ACTION)

faq.gen: $(DOCROOT)/FAQ faqparse.pl
./faqparse.pl < $< > $@
faq.gen: $(DOCROOT)/FAQ.md tcparse.pl
./tcparse.pl $< >$@

faq-content.gen: $(DOCROOT)/FAQ.md
$(MARKDOWN) < $< > $@

alt-svc.html: _alt-svc.html $(MAINPARTS) alt-svc.gen
$(ACTION)
Expand All @@ -385,11 +388,14 @@ http-cookies.gen: $(DOCROOT)/HTTP-COOKIES.md
irc.html: _irc.html $(MAINPARTS)
$(ACTION)

knownbugs.html: _knownbugs.html $(MAINPARTS) knownbugs.gen
knownbugs.html: _knownbugs.html $(MAINPARTS) knownbugs.gen knownbugs-content.gen
$(ACTION)

knownbugs.gen: $(DOCROOT)/KNOWN_BUGS faqparse.pl
./faqparse.pl < $< > $@
knownbugs.gen: $(DOCROOT)/KNOWN_BUGS.md tcparse.pl
./tcparse.pl $< >$@

knownbugs-content.gen: $(DOCROOT)/KNOWN_BUGS.md
$(MARKDOWN) < $< > $@

knownrisks.html: _knownrisks.html $(MAINPARTS) knownrisks.gen
$(ACTION)
Expand Down Expand Up @@ -421,11 +427,14 @@ tutorial.html: _tutorial.html $(MAINPARTS) manual.gen
manual.gen: $(DOCROOT)/MANUAL.md
$(MARKDOWN) < $< >$@

todo.html: _todo.html $(MAINPARTS) todo.gen
todo.html: _todo.html $(MAINPARTS) todo.gen todo-content.gen
$(ACTION)

todo.gen: $(DOCROOT)/TODO faqparse.pl
./faqparse.pl < $< > $@
todo.gen: $(DOCROOT)/TODO.md tcparse.pl
./tcparse.pl $< >$@

todo-content.gen: $(DOCROOT)/TODO.md
$(MARKDOWN) < $< > $@

governance.html: _governance.html $(MAINPARTS) governance.gen
$(ACTION)
Expand Down
2 changes: 2 additions & 0 deletions docs/_faq.shtml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ TITLE(FAQ -- Frequently Asked Questions)

#include "faq.gen"

#include "faq-content.gen"

#include "_footer.html"

</body>
Expand Down
2 changes: 2 additions & 0 deletions docs/_knownbugs.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#include "knownbugs.gen"

#include "knownbugs-content.gen"

#include "_footer.html"

</body>
Expand Down
15 changes: 12 additions & 3 deletions docs/_todo.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
<html>
<head> <title>curl - TODO</title>
#include "css.t"

<style>
input[type=checkbox] {
display: none;
}
ul.task-list {
list-style-type: none;
}
</style>
</head>

#define CURL_DOCS
Expand All @@ -12,9 +21,7 @@
#include "_menu.html"
#include "setup.t"

WHERE3(Docs, "/docs/", Project, "/docs/projdocs.html", TODO)

TITLE(TODO -- nice to have features)
WHERE3(Docs, "/docs/", Project, "/docs/projdocs.html", Nice to have features)
<div class="relatedbox">
<b>Related:</b>
<br><a href="/dev/deprecate.html">Deprecate</a>
Expand All @@ -24,6 +31,8 @@

#include "todo.gen"

#include "todo-content.gen"

#include "_footer.html"

</body>
Expand Down
229 changes: 229 additions & 0 deletions docs/tcparse.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
#!/usr/bin/env perl

# Parse markdown FAQ to generate hierarchical table of contents with numbered entries

use strict;
use warnings;

sub make_section_anchor {
my ($title) = @_;
# remove "special" letters
$title =~ s/[^A-Za-z0-9_ ]//g;
# make dashes for spaces
$title =~ s/ /-/g;
return $title;
}

sub make_anchor {
my $title = shift;
my $anchor = substr($title, 0, 32);
# filter off "odd" chars
$anchor =~ s/[^a-z0-9A-Z]/_/g;
# filter off trailing underscores
$anchor =~ s/_+\z//;
# filter off initial underscores
$anchor =~ s/^_+//;
# filter off multiple underscores
$anchor =~ s/_+/_/g;
return $anchor;
}

my $input = $ARGV[0] or die "Usage: $0 <input-file>\n";

open my $in, '<', $input or die "Cannot open input file '$input': $!\n";

# First pass: collect all sections and questions
my @sections;
my $current_section;
my $current_question;

while (my $line = <$in>) {
chomp $line;

# Match ## heading (section)
if ($line =~ /^##\s+(.+)$/) {
my $title = $1;
my $anchor = make_section_anchor($title);

$current_section = {
title => $title,
anchor => $anchor,
questions => []
};
push @sections, $current_section;
$current_question = undef;
}
# Match ### heading (question)
elsif ($line =~ /^###\s+(.+)$/ && $current_section) {
my $title = $1;
my $anchor = make_anchor($title);

# HTML escape the title
my $escaped_title = $title;
$escaped_title =~ s/&/&amp;/g;
$escaped_title =~ s/</&lt;/g;
$escaped_title =~ s/>/&gt;/g;
# Escape C comment delimiters for fcpp
$escaped_title =~ s/\*\//&#42;&#47;/g; # */
$escaped_title =~ s/\/\*/&#47;&#42;/g; # /*

$current_question = {
title => $escaped_title,
anchor => $anchor,
subquestions => []
};
push @{$current_section->{questions}}, $current_question;
}
# Match #### heading (sub-question)
elsif ($line =~ /^####\s+(.+)$/ && $current_question) {
my $title = $1;
my $anchor = make_anchor($title);

# HTML escape the title
my $escaped_title = $title;
$escaped_title =~ s/&/&amp;/g;
$escaped_title =~ s/</&lt;/g;
$escaped_title =~ s/>/&gt;/g;
# Escape C comment delimiters for fcpp
$escaped_title =~ s/\*\//&#42;&#47;/g; # */
$escaped_title =~ s/\/\*/&#47;&#42;/g; # /*

push @{$current_question->{subquestions}}, {
title => $escaped_title,
anchor => $anchor
};
}
}

close $in;

# Create a lookup hash for anchors by title
my %anchor_by_title;
foreach my $section (@sections) {
$anchor_by_title{$section->{title}} = $section->{anchor};
foreach my $question (@{$section->{questions}}) {
# Store with original unescaped title for matching
my $orig_title = $question->{title};
$orig_title =~ s/&amp;/&/g;
$orig_title =~ s/&lt;/</g;
$orig_title =~ s/&gt;/>/g;
$orig_title =~ s/&#42;&#47;/\*\//g;
$orig_title =~ s/&#47;&#42;/\/\*/g;
$anchor_by_title{$orig_title} = $question->{anchor};

foreach my $subq (@{$question->{subquestions}}) {
my $orig_subq_title = $subq->{title};
$orig_subq_title =~ s/&amp;/&/g;
$orig_subq_title =~ s/&lt;/</g;
$orig_subq_title =~ s/&gt;/>/g;
$orig_subq_title =~ s/&#42;&#47;/\*\//g;
$orig_subq_title =~ s/&#47;&#42;/\/\*/g;
$anchor_by_title{$orig_subq_title} = $subq->{anchor};
}
}
}

# Second pass: generate HTML output with linked section headings and grouped questions
my $section_num = 0;

foreach my $section (@sections) {
$section_num++;

# Output section heading as a link
print "<h2><a href=\"#$section->{anchor}\">$section->{title}</a></h2>\n";

# Start paragraph for questions
if (@{$section->{questions}} > 0) {
print "<p>\n";

my $question_num = 0;
foreach my $question (@{$section->{questions}}) {
$question_num++;

# Output question link
print "<a href=\"#$question->{anchor}\">$question->{title}</a><br>\n";

# Output sub-questions if any
foreach my $subq (@{$question->{subquestions}}) {
print "<a href=\"#$subq->{anchor}\">$subq->{title}</a><br>\n";
}
}

print "</p>\n";
}
}

# Third pass: output the content with modified id attributes
print "\n<!-- CONTENT WITH MODIFIED IDS -->\n\n";

open $in, '<', $input or die "Cannot reopen input file '$input': $!\n";

my @paragraph_lines = ();
my $in_paragraph = 0;

sub flush_paragraph {
if (@paragraph_lines) {
# Join the lines and wrap in <p> tags
my $content = join("\n", @paragraph_lines);
print "<p>$content</p>\n";
@paragraph_lines = ();
}
$in_paragraph = 0;
}

while (my $line = <$in>) {
chomp $line;

# Skip # heading (level 1, e.g., #FAQ)
if ($line =~ /^#\s+(.+)$/) {
flush_paragraph();
next;
}
# Match ## heading (section)
elsif ($line =~ /^##\s+(.+)$/) {
flush_paragraph();
my $title = $1;
my $anchor = $anchor_by_title{$title};
print "<h2 id=\"$anchor\">$title</h2>\n";
}
# Match ### heading (question)
elsif ($line =~ /^###\s+(.+)$/) {
flush_paragraph();
my $title = $1;
my $anchor = $anchor_by_title{$title};
print "<h3 id=\"$anchor\">$title</h3>\n";
}
# Match #### heading (sub-question)
elsif ($line =~ /^####\s+(.+)$/) {
flush_paragraph();
my $title = $1;
my $anchor = $anchor_by_title{$title};
print "<h4 id=\"$anchor\">$title</h4>\n";
}
# Blank line ends current paragraph
elsif ($line =~ /^\s*$/) {
flush_paragraph();
print "\n";
}
else {
# Convert markdown angle bracket links to HTML anchors
# Convert <https://github.com/curl/curl/issues/12345> to <a href="...">curl/curl#12345</a>
$line =~ s/<(https?:\/\/github\.com\/curl\/curl\/issues\/(\d+))>/<a href="$1">curl\/curl#$2<\/a>/g;
# Convert <https://github.com/curl/curl/pull/12345> to <a href="...">curl/curl#12345</a>
$line =~ s/<(https?:\/\/github\.com\/curl\/curl\/pull\/(\d+))>/<a href="$1">curl\/curl#$2<\/a>/g;
# Convert other GitHub links generically
$line =~ s/<(https?:\/\/github\.com\/([^\/]+)\/([^\/]+)\/issues\/(\d+))>/<a href="$1">$2\/$3#$4<\/a>/g;
$line =~ s/<(https?:\/\/github\.com\/([^\/]+)\/([^\/]+)\/pull\/(\d+))>/<a href="$1">$2\/$3#$4<\/a>/g;
# Convert other angle bracket URLs to simple links
$line =~ s/<(https?:\/\/[^>]+)>/<a href="$1">$1<\/a>/g;

# Add line to current paragraph
push @paragraph_lines, $line;
$in_paragraph = 1;
}
}

# Flush any remaining paragraph
flush_paragraph();

close $in;
Loading