=================================================================== RCS file: /cvs/pod2mdoc/pod2mdoc.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -p -r1.8 -r1.9 --- pod2mdoc/pod2mdoc.c 2014/03/23 23:57:38 1.8 +++ pod2mdoc/pod2mdoc.c 2014/03/24 01:07:30 1.9 @@ -1,4 +1,4 @@ -/* $Id: pod2mdoc.c,v 1.8 2014/03/23 23:57:38 kristaps Exp $ */ +/* $Id: pod2mdoc.c,v 1.9 2014/03/24 01:07:30 kristaps Exp $ */ /* * Copyright (c) 2014 Kristaps Dzonsons * @@ -158,6 +158,77 @@ formatescape(const char *buf, size_t *start, size_t en } /* + * Run some heuristics to intuit a link format. + * I recognise L as a Perl manpage, printing it in section 3p; + * or a general UNIX foo(5) manpage. + * If I recognise one, I set "start" to be the end of the sequence so + * that the caller can safely just continue processing. + * Otherwise, I don't touch "start". + */ +static int +trylink(const char *buf, size_t *start, size_t end, size_t dsz) +{ + size_t sv, nstart, nend, i, j; + int hasdouble; + + /* + * Scan to the start of the terminus. + * This function is more or less replicated in the formatcode() + * for null or index formatting codes. + */ + hasdouble = 0; + for (sv = nstart = *start; nstart < end; nstart++) { + /* Do we have a double-colon? */ + if (':' == buf[nstart] && + nstart > sv && + ':' == buf[nstart - 1]) + hasdouble = 1; + if ('>' != buf[nstart]) + continue; + else if (dsz == 1) + break; + assert(nstart > 0); + if (' ' != buf[nstart - 1]) + continue; + i = nstart; + for (j = 0; i < end && j < dsz; j++) + if ('>' != buf[i++]) + break; + if (dsz == j) + break; + } + + /* We don't care about stubs. */ + if (nstart == end || nstart == *start) + return(0); + + /* Set nend to the end of content. */ + nend = nstart; + if (dsz > 1) + nend--; + + /* + * Provide for some common invocations of the link primitive. + * First, allow us to link to other Perl manuals. + */ + if (hasdouble) + printf("Xr %.*s 3p", + (int)(nend - sv), &buf[sv]); + else if (nend - sv > 3 && isalnum(buf[sv]) && + ')' == buf[nend - 1] && + isdigit((int)buf[nend - 2]) && + '(' == buf[nend - 3]) + printf("Xr %.*s %c", + (int)(nend - 3 - sv), + &buf[sv], buf[nend - 2]); + else + return(0); + + *start = nstart; + return(1); +} + +/* * We're at the character in front of a format code, which is structured * like X<...> and can contain nested format codes. * This consumes the whole format code, and any nested format codes, til @@ -284,13 +355,13 @@ formatcode(const char *buf, size_t *start, printf("Qo Li "); break; case (FMT_LINK): - printf("Lk "); + if ( ! trylink(buf, start, end, dsz)) + printf("No "); break; case (FMT_FILE): printf("Pa "); break; case (FMT_NBSP): - /* TODO. */ printf("No "); break; default: