Code Map
1 sorg.c
sorg.org:15
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parg.h"
1.1 global_variables
sorg.org:1413
static int use_secno = 0;
sorg.org:1433
static char *indxfile = NULL;
static int mktoc = 0;
1.2 enums
sorg.org:373
enum {
1.2.1 types
sorg.org:613
MODE_TEXT,
sorg.org:671
MODE_BEGIN_CODE,
sorg.org:738
MODE_CODE,
sorg.org:1046
MODE_ULIST,
sorg.org:375
MODE_NONE
};
1.3 sorg_data
sorg.org:72
typedef struct {
1.3.1 sorg_data_contents
sorg.org:92
int mode;
sorg.org:108
int pmode;
sorg.org:126
size_t pos;
size_t off;
size_t blksize;
sorg.org:142
#define SORG_MAXSEC 10
int secpos[SORG_MAXSEC];
sorg.org:159
int depth;
int pdepth;
sorg.org:74
} sorg_d;
1.4 function_declarations
sorg.org:196
static int parse(sorg_d *sorg, FILE *out, char *buf, size_t size);
sorg.org:386
static int is_header(sorg_d *sorg, char *buf, size_t size);
sorg.org:422
static void print_header(sorg_d *sorg, char *buf, size_t size, FILE *out);
sorg.org:541
static int is_title(sorg_d *sorg, const char *buf, size_t size);
sorg.org:563
static void print_title(sorg_d *sorg, const char *buf, size_t size, FILE *out);
sorg.org:619
void print_text(sorg_d *sorg, char *buf, FILE *out);
sorg.org:645
static int is_name(sorg_d *sorg, char *buf, size_t size);
sorg.org:685
static void print_name(sorg_d *sorg, char *buf, size_t size, FILE *out);
sorg.org:745
static int is_begin(sorg_d *sorg, char *buf, size_t size);
sorg.org:772
static int is_end(sorg_d *sorg, char *buf, size_t size);
sorg.org:801
static int is_block_ref(sorg_d *sorg, char *buf, size_t size);
sorg.org:834
static size_t print_block_ref(sorg_d *sorg, char *buf, size_t size, FILE *out);
sorg.org:891
static int is_encapsulated(sorg_d *sorg,
const char *delim,
int dsize,
char *buf,
size_t size);
sorg.org:919
static size_t print_encapsulated(sorg_d *sorg,
const char *delim,
int dsize,
char *buf,
size_t size,
const char *tag,
FILE *out);
sorg.org:969
static int chk_encapsulated(sorg_d *sorg,
const char *delim,
int dsize,
char *buf,
size_t size,
const char *tag,
FILE *out);
sorg.org:1063
static int is_ulistitem(sorg_d *sorg, char *buf, size_t size);
sorg.org:1085
static void print_ulist_begin(sorg_d *sorg, FILE *out);
sorg.org:1101
static void print_ulist_end(sorg_d *sorg, FILE *out);
sorg.org:1116
static void print_ulist_item(sorg_d *sorg, char *buf, size_t size, FILE *out);
sorg.org:1194
static int is_link(sorg_d *sorg, char *buf, size_t size);
sorg.org:1219
static size_t print_link(sorg_d *sorg, char *buf, size_t size, FILE *out);
sorg.org:1277
static int is_comment(sorg_d *sorg, char *line, size_t size);
sorg.org:1315
static void update_section_depth(sorg_d *sorg, int depth);
sorg.org:1347
static void print_section(sorg_d *sorg, FILE *out);
sorg.org:1519
static void spaces_to_underscores(const char *str, size_t size, FILE *out);
1.5 functions
sorg.org:81
void sorg_init(sorg_d *sorg) {
int i;
1.5.1 initialize_stuff
sorg.org:100
sorg->mode = MODE_NONE;
sorg.org:115
sorg->pmode = MODE_NONE;
sorg.org:133
sorg->pos = 0;
sorg->off = 0;
sorg->blksize = 0;
sorg.org:150
for(i = 0; i < SORG_MAXSEC; i++) sorg->secpos[i] = 0;
sorg.org:171
sorg->depth = -1;
sorg->pdepth = -1;
sorg.org:84
}
sorg.org:391
static int is_header(sorg_d *sorg, char *buf, size_t size)
{
size_t s;
if(size == 0) return 0;
if(buf[0] != '*') return 0;
for(s = 1; s < size; s++) {
if(buf[s] == '*') {
continue;
} else if(buf[s] == ' ') {
return 1;
} else {
return 0;
}
}
return 0;
}
sorg.org:427
static void print_header(sorg_d *sorg, char *buf, size_t size, FILE *out)
{
size_t s;
size_t off;
int mode;
int level;
off = 0;
mode = 0;
level = 1;
for(s = 0; s < size; s++) {
if(mode == 2) break;
switch(mode) {
case 0: /* asterisks */
if(buf[off] != '*') {
mode = 1;
off++;
break;
}
level++;
off++;
break;
case 1: /* spaces */
if(buf[off] != ' ') {
mode = 2;
break;
}
}
}
if(buf[size - 1] == '\n') size--; /* chomp */
1.5.2 update_section_depth
sorg.org:477
update_section_depth(sorg, level - 2);
sorg.org:459
if(mktoc) {
1.5.3 print_toc_header
sorg.org:520
if(sorg->depth > sorg->pdepth) {
fprintf(out, "<ul>");
} else if(sorg->depth < sorg->pdepth) {
for(s = 0; s < (sorg->pdepth - sorg->depth); s++)
fprintf(out, "</ul>");
}
fprintf(out, "<li><a href=\"%s#", indxfile);
spaces_to_underscores(buf + off, size - off, out);
fprintf(out, "\">");
if(use_secno) print_section(sorg, out);
fwrite(buf + off, 1, size - off, out);
fprintf(out, "</a></li>\n");
sorg.org:461
} else {
1.5.4 print_normal_header
sorg.org:482
fprintf(out, "<a id=\"");
spaces_to_underscores(buf + off, size - off, out);
fprintf(out, "\">\n");
if(level < 6) {
fprintf(out, "<h%d>", level);
if(use_secno) print_section(sorg, out);
fwrite(buf + off, 1, size - off, out);
fprintf(out, "</h%d>\n", level);
} else {
fprintf(out, "<u><i>");
if(use_secno) print_section(sorg, out);
fwrite(buf + off, 1, size - off, out);
fprintf(out, "</i></u>\n");
}
fprintf(out, "</a>\n");
sorg.org:463
}
}
sorg.org:546
static int is_title(sorg_d *sorg, const char *buf, size_t size)
{
const char *title = "#+TITLE:";
size_t title_size = 8;
size_t s;
if(size < title_size) return 0;
for(s = 0; s < title_size; s++) {
if(buf[s] != title[s]) return 0;
}
return 1;
}
sorg.org:568
static void print_title(sorg_d *sorg, const char *buf, size_t size, FILE *out)
{
size_t s;
int mode;
const char *title;
size_t tsize;
mode = 1;
tsize = 0;
title = NULL;
for(s = 8; s < size; s++) {
if(mode == 0) break;
switch(mode) {
case 1: /* spaces */
if(buf[s] == ' ') {
continue;
}
mode = 2;
tsize = 1;
title = &buf[s];
break;
case 2:
if(buf[s] == '\n') {
mode = 0;
break;
}
tsize++;
break;
}
}
if(title != NULL) {
fprintf(out, "<h1>");
fwrite(title, 1, tsize, out);
fprintf(out, "</h1>\n");
}
}
sorg.org:626
void print_text(sorg_d *sorg, char *buf, FILE *out)
{
if(sorg->blksize > 0) {
printf("are we here?\n");
fwrite(buf + sorg->off, 1, sorg->blksize - 1, out);
}
}
sorg.org:650
static int is_name(sorg_d *sorg, char *buf, size_t size)
{
const char *name = "#+NAME:";
const int name_size = 7;
size_t s;
if(size < name_size) return 0;
for(s = 0; s < name_size; s++) {
if(buf[s] != name[s]) return 0;
}
return 1;
}
sorg.org:690
static void print_name(sorg_d *sorg, char *buf, size_t size, FILE *out)
{
int mode;
size_t name_size;
size_t n;
size_t off;
buf+=7;
size -= 7;
name_size = 0;
mode = 1;
off = 0;
for(n = 0; n < size; n++) {
if(mode == 0) break;
switch(mode) {
case 1: /* spaces */
if(buf[n] == ' ') {
break;
}
off = n;
mode = 2;
name_size = 1;
break;
case 2: /* count to line break*/
if(buf[n] == '\n' || buf[n] == ' ') {
mode = 0;
break;
}
name_size++;
break;
}
}
fprintf(out, "<a id=\"_");
spaces_to_underscores(buf + off, name_size, out);
fprintf(out, "\">\n");
fprintf(out, "<div><b><i><<");
fwrite(buf + off, 1, name_size, out);
fprintf(out, "</b></i>>>=</div>\n");
fprintf(out, "</a>");
}
sorg.org:750
static int is_begin(sorg_d *sorg, char *buf, size_t size)
{
const char *name = "#+BEGIN_SRC";
const int name_size = 11;
size_t s;
if(size < name_size) return 0;
for(s = 0; s < name_size; s++) {
if(buf[s] != name[s]) return 0;
}
return 1;
}
sorg.org:777
static int is_end(sorg_d *sorg, char *buf, size_t size)
{
const char *name = "#+END_SRC";
const int name_size = 9;
size_t s;
if(size < name_size) return 0;
for(s = 0; s < name_size; s++) {
if(buf[s] != name[s]) return 0;
}
return 1;
}
sorg.org:811
static int is_block_ref(sorg_d *sorg, char *buf, size_t size)
{
size_t n;
if(size < 5) return 0;
if(buf[0] != '<' || buf[1] != '<') return 0;
size -= 1; /* for lookahead */
for(n = 2; n < size; n++) {
if(buf[n] == '>' && buf[n + 1] == '>') return 1;
}
return 0;
}
sorg.org:843
static size_t print_block_ref(sorg_d *sorg, char *buf, size_t size, FILE *out)
{
size_t off;
size_t n;
char *name;
size_t name_size;
size_t tmp;
size -= 1; /* for lookahead */
off = 2;
name_size = 0;
tmp = 0;
name = &buf[2];
for(n = 2; n < size; n++) {
off++;
tmp++;
if(buf[n] == '>' && buf[n + 1] == '>') {
name_size = tmp - 1;
n++;
off++;
break;
}
}
fprintf(out, "<a href=\"#_");
spaces_to_underscores(name, name_size, out);
fprintf(out, "\"><<");
fwrite(name, 1, name_size, out);
fprintf(out, ">></a>");
return off;
}
sorg.org:900
static int is_encapsulated(sorg_d *sorg,
const char *delim,
int dsize,
char *buf,
size_t size)
{
size_t s;
if(buf[0] != delim[0]) return 0;
size = size - 1;
for(s = 1; s < size; s++) if(buf[s] == delim[0]) return 1;
return 0;
}
sorg.org:936
static size_t print_encapsulated(sorg_d *sorg,
const char *delim,
int dsize,
char *buf,
size_t size,
const char *tag,
FILE *out)
{
size_t off;
size_t s;
off = 1;
size = size - 1;
for(s = 1; s < size; s++) {
off++;
if(buf[s] == delim[0]) {
break;
}
}
fprintf(out, "<%s>", tag);
fwrite(buf + dsize, 1, off - 2*dsize, out);
fprintf(out, "</%s>", tag);
return off;
}
sorg.org:980
static int chk_encapsulated(sorg_d *sorg,
const char *delim,
int dsize,
char *buf,
size_t size,
const char *tag,
FILE *out)
{
if(is_encapsulated(sorg,
delim,
dsize,
&buf[sorg->pos],
size - sorg->pos))
{
fwrite(buf + sorg->off, 1, sorg->blksize - 1, out);
sorg->pos += print_encapsulated(sorg,
delim,
dsize,
&buf[sorg->pos],
size - sorg->pos,
tag,
out);
sorg->blksize = 1;
sorg->off = sorg->pos;
return 1;
}
return 0;
}
sorg.org:1068
static int is_ulistitem(sorg_d *sorg, char *buf, size_t size)
{
if(size == 0) return 0;
else if(buf[0] != '-') return 0;
else if(size == 2 && buf[0] == '-') return 1;
else if(buf[0] == '-' && buf[1] == ' ') return 1;
return 0;
}
sorg.org:1090
static void print_ulist_begin(sorg_d *sorg, FILE *out)
{
fprintf(out, "<ul>\n");
}
sorg.org:1106
static void print_ulist_end(sorg_d *sorg, FILE *out)
{
fprintf(out, "</ul>\n");
}
sorg.org:1140
static void print_ulist_item(sorg_d *sorg, char *buf, size_t size, FILE *out)
{
size_t s;
int mode;
size_t off;
size_t len;
size_t s_blksize;
size_t s_off;
size_t s_pos;
mode = 1;
off = 1; /* assume first character is '-' */
len = 0;
for(s = 1; s < size; s++) {
if(mode == 0) break;
switch(mode) {
case 1: /* whitespaces after initial dash */
if(buf[s] != ' ') mode = 2;
else off++;
break;
case 2: /* look for linebreak */
if(buf[s] == '\n') {
mode = 0;
}
len++;
break;
}
}
fprintf(out, "<li><p>");
sorg->pmode = MODE_NONE;
sorg->mode = MODE_TEXT;
s_off = sorg->off;
s_blksize = sorg->blksize;
s_pos = sorg->pos;
parse(sorg, out, buf + off, len + 1);
sorg->off = s_off;
sorg->blksize = s_blksize;
sorg->pos = s_pos;
sorg->mode = MODE_ULIST;
sorg->pmode = MODE_ULIST;
/* fwrite(buf + off, len, 1, out); */
fprintf(out, "</p></li>\n");
}
sorg.org:1199
static int is_link(sorg_d *sorg, char *buf, size_t size)
{
size_t n;
if(size < 5) return 0;
if(buf[0] != '[' || buf[1] != '[') return 0;
size -= 1; /* for lookahead */
for(n = 2; n < size; n++) {
if(buf[n] == ']' && buf[n + 1] == ']') return 1;
}
return 0;
}
sorg.org:1224
static size_t print_link(sorg_d *sorg, char *buf, size_t size, FILE *out)
{
size_t off;
size_t n;
char *link;
size_t link_size;
char *name;
size_t name_size;
size_t tmp;
size -= 1; /* for lookahead */
off = 2;
name_size = 0;
link_size = 0;
tmp = 0;
link = NULL;
name = NULL;
link = &buf[2];
for(n = 2; n < size; n++) {
off++;
tmp++;
if(buf[n] == ']' && buf[n + 1] == '[') {
link_size = tmp - 1;
tmp = 0;
name = &buf[n + 2];
n++;
off++;
} else if(buf[n] == ']' && buf[n + 1] == ']') {
name_size = tmp - 1;
off++;
break;
}
}
if(!strncmp(link, "https://", 8) || !strncmp(link, "http://", 7)) {
fprintf(out, "<a href=\"");
fwrite(link, 1, link_size, out);
} else {
fprintf(out, "<a href=\"#");
spaces_to_underscores(link, link_size, out);
}
fprintf(out, "\">");
fwrite(name, 1, name_size, out);
fprintf(out, "</a>");
return off;
}
sorg.org:1286
static int is_comment(sorg_d *sorg, char *line, size_t size)
{
if(size <= 0) return 0;
if(size == 2 && line[0] == '#') return 1;
if(line[0] == '#' && line[1] == ' ') return 1;
return 0;
}
sorg.org:1320
static void update_section_depth(sorg_d *sorg, int depth)
{
int i;
if(depth < 0 && depth > SORG_MAXSEC) {
fprintf(stderr,
"Warning: section depth of %d exceeds maximum depth of %d\n",
depth + 1, SORG_MAXSEC);
return;
}
if(depth > sorg->depth) {
sorg->secpos[depth] = 1;
} else if(depth < sorg->depth) {
sorg->secpos[depth]++;
for(i = depth + 1; i < SORG_MAXSEC; i++) sorg->secpos[i] = 0;
} else {
sorg->secpos[depth]++;
}
sorg->pdepth = sorg->depth;
sorg->depth = depth;
}
sorg.org:1355
static void print_section(sorg_d *sorg, FILE *out)
{
int i;
if(sorg->depth < 0) return;
fprintf(out, "%d", sorg->secpos[0]);
for(i = 1; i <= sorg->depth; i++) {
fprintf(out, ".%d", sorg->secpos[i]);
}
fputc(' ', out);
}
sorg.org:1524
static void spaces_to_underscores(const char *str, size_t size, FILE *out)
{
size_t blksize;
size_t n;
size_t off;
off = 0;
blksize = 0;
for(n = 0; n < size; n++) {
blksize++;
if(str[n] == ' ') {
fwrite(str + off, 1, blksize - 1, out);
fputc('_', out);
blksize = 0;
off = n + 1;
}
}
fwrite(str + off, 1, blksize, out);
}
1.6 parsing_top
sorg.org:201
static int parse(sorg_d *sorg, FILE *out, char *buf, size_t size)
{
sorg->pos = 0;
sorg->off = 0;
sorg->blksize = 0;
if(mktoc) {
1.6.1 toc_parse_mode
sorg.org:360
if(buf[0] == '\n') {
return 1;
}
if(is_title(sorg, buf, size)) {
print_title(sorg, buf, size, out);
}else if(is_header(sorg, buf, size)) {
print_header(sorg, buf, size, out);
}
sorg.org:208
} else {
1.6.2 normal_parse_mode
sorg.org:218
if(buf[0] == '\n') {
if(sorg->pmode == MODE_TEXT) {
fprintf(out,"</p>\n");
sorg->pmode = MODE_NONE;
}
return 1;
}
while(sorg->pos < size) {
switch(sorg->mode) {
case MODE_NONE:
if(is_comment(sorg, buf, size)) {
sorg->mode = MODE_NONE;
return 1;
} if(is_header(sorg, buf, size)) {
if(sorg->pmode == MODE_TEXT) fprintf(out, "</p>\n");
print_header(sorg, buf, size, out);
sorg->mode = MODE_NONE;
sorg->pmode = sorg->mode;
return 1;
} else if(is_name(sorg, buf, size)) {
if(sorg->pmode == MODE_TEXT) fprintf(out, "</p>\n");
print_name(sorg, buf, size, out);
sorg->mode = MODE_BEGIN_CODE;
sorg->pmode = sorg->mode;
return 1;
} else if(is_title(sorg, buf, size)) {
if(sorg->pmode == MODE_TEXT) fprintf(out, "</p>\n");
print_title(sorg, buf, size, out);
sorg->mode = MODE_NONE;
sorg->pmode = sorg->mode;
return 1;
} else if(is_ulistitem(sorg, buf, size)) {
if(sorg->pmode == MODE_TEXT) fprintf(out, "</p>\n");
print_ulist_begin(sorg, out);
print_ulist_item(sorg, buf, size, out);
sorg->pmode = sorg->mode;
sorg->mode = MODE_ULIST;
return 1;
} else {
sorg->mode = MODE_TEXT;
sorg->off = sorg->pos;
sorg->blksize = 1;
if(sorg->pmode != MODE_TEXT) fprintf(out, "<p>");
}
break;
case MODE_TEXT:
1.6.2.1 parse_formatted
sorg.org:1016
if(chk_encapsulated(sorg, "*", 1, buf, size, "b", out)) break;
sorg.org:1022
if(chk_encapsulated(sorg, "/", 1, buf, size, "i", out)) break;
sorg.org:1028
if(chk_encapsulated(sorg, "=", 1, buf, size, "code", out)) break;
sorg.org:1033
if(chk_encapsulated(sorg, "_", 1, buf, size, "u", out)) break;
sorg.org:266
if(is_link(sorg, &buf[sorg->pos], size - sorg->pos)) {
print_text(sorg, buf, out);
sorg->pos += print_link(sorg,
&buf[sorg->pos],
size - sorg->pos,
out);
sorg->blksize = 1;
sorg->off = sorg->pos;
} else if(is_block_ref(sorg, &buf[sorg->pos], size - sorg->pos)) {
print_text(sorg, buf, out);
sorg->pos += print_block_ref(sorg,
&buf[sorg->pos],
size - sorg->pos,
out);
sorg->blksize = 1;
sorg->off = sorg->pos;
} else {
if(buf[sorg->pos] != '\n') sorg->blksize++;
sorg->pos++;
}
break;
case MODE_BEGIN_CODE:
if(!is_begin(sorg, buf, size)) return 0;
else {
fprintf(out, "\n<p><code>");
sorg->mode = MODE_CODE;
return 1;
}
break;
case MODE_CODE:
if(is_end(sorg, buf, size)) {
sorg->mode = MODE_NONE;
fprintf(out, "\n</code></p>\n");
return 1;
}
sorg->blksize++;
switch(buf[sorg->pos]) {
case '<':
fwrite(buf + sorg->off, 1, sorg->blksize - 1, out);
sorg->off = sorg->pos + 1;
sorg->blksize = 0;
fprintf(out, "<");
break;
case '>':
fwrite(buf + sorg->off, 1, sorg->blksize - 1, out);
sorg->off = sorg->pos + 1;
sorg->blksize = 0;
fprintf(out, ">");
break;
case '\n':
fwrite(buf + sorg->off, 1, sorg->blksize - 1, out);
sorg->off = sorg->pos + 1;
sorg->blksize = 0;
fprintf(out, "<br>\n");
break;
case ' ':
fwrite(buf + sorg->off, 1, sorg->blksize - 1, out);
sorg->off = sorg->pos + 1;
sorg->blksize = 0;
fprintf(out, " ");
break;
}
sorg->pos++;
break;
case MODE_ULIST:
if(is_ulistitem(sorg, buf, size)) {
print_ulist_item(sorg, buf, size, out);
return 1;
} else {
sorg->pmode = sorg->mode;
sorg->mode = MODE_NONE;
print_ulist_end(sorg, out);
parse(sorg, out, buf, size);
return 1;
}
break;
}
}
fwrite(buf + sorg->off, 1, sorg->blksize, out);
sorg->pmode = sorg->mode;
if(sorg->mode != MODE_CODE) {
sorg->mode = MODE_NONE;
}
sorg.org:210
}
return 1;
}
1.7 getline
sorg.org:1447
size_t sorg_getline(char **lineptr, size_t *n, FILE *stream) {
char *bufptr = NULL;
char *p = bufptr;
size_t size;
int c;
if (lineptr == NULL) {
return -1;
}
if (stream == NULL) {
return -1;
}
if (n == NULL) {
return -1;
}
bufptr = *lineptr;
size = *n;
c = fgetc(stream);
if (c == EOF) {
return -1;
}
if (bufptr == NULL) {
bufptr = malloc(128);
if (bufptr == NULL) {
return -1;
}
size = 128;
}
p = bufptr;
while(c != EOF) {
if ((p - bufptr) > (size - 1)) {
size = size + 128;
bufptr = realloc(bufptr, size);
if (bufptr == NULL) {
return -1;
}
}
*p++ = c;
if (c == '\n') {
break;
}
c = fgetc(stream);
}
*lineptr = bufptr;
/* Some text editors do not insert a linebreak on the last line.
* For these cases, shift everything by 1.
*/
if(c == EOF) {
p = p + 1;
size += 1;
}
*p++ = '\0';
*n = size;
return p - bufptr - 1;
}
sorg.org:27
int main(int argc, char *argv[])
{
FILE *in;
FILE *out;
char *line;
size_t read;
size_t n;
sorg_d sorg;
char *filename;
1.8 local_variables
sorg.org:1375
struct parg_state ps;
int c;
sorg.org:38
filename = NULL;
in = stdin;
1.9 parse_command_flags
sorg.org:1381
parg_init(&ps);
while((c = parg_getopt(&ps, argc, argv, "st:")) != -1) {
switch(c) {
case 1:
filename = (char *)ps.optarg;
break;
case 't':
1.9.1 generate_toc
sorg.org:1424
mktoc = 1;
indxfile = (char *)ps.optarg;
sorg.org:1389
break;
case 's':
1.9.2 turn_on_sections
sorg.org:1406
use_secno = 1;
sorg.org:1392
break;
default:
fprintf(stderr, "Unknown option -%c\n", c);
return 1;
}
}
sorg.org:43
if(filename != NULL) {
in = fopen(filename, "r");
}
out = stdout;
line = NULL;
n = 0;
sorg_init(&sorg);
while((read = sorg_getline(&line, &n, in)) != -1) {
parse(&sorg, out, line, read);
}
if(sorg.pmode == MODE_TEXT) fprintf(out, "</p>");
if(mktoc && sorg.depth >= 0) fprintf(out, "</ul>");
if(in != stdin) fclose(in);
if(line != NULL) free(line);
return 0;
}