webgen.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include "html.h"
  7. #include "utils.h"
  8. #define LENGTH(x) (sizeof (x) / sizeof (*x))
  9. char *line = NULL;
  10. unsigned linenum = 0;
  11. size_t linelen;
  12. char *params[9] = { 0 };
  13. int nparams;
  14. int inparagraph = 0;
  15. struct {
  16. char *name;
  17. int(*fun)(void);
  18. } tokens[] = { //TODO: make the recognition not dependent on length+order
  19. { ".img", spitimg },
  20. { ".ref", spithref },
  21. { ".br", spitlinebreak },
  22. { ".ce", codeend },
  23. { ".cs", codestart },
  24. { ".cw", spitmonospace },
  25. { ".hr", spithorizontalrule },
  26. { ".pp", newparagraph },
  27. { ".sh", subheading },
  28. { ".b", spitbold },
  29. { ".i", spititalic },
  30. //{ "", newparagraph },
  31. };
  32. char *
  33. nextword(char *p)
  34. {
  35. // find the end of current word
  36. for (;; p++) {
  37. if (*p == '\0') {
  38. return NULL;
  39. } else if (isspace(*p)) {
  40. //TODO: is this correct?
  41. *p = '\0';
  42. p++;
  43. break;
  44. }
  45. }
  46. // find the first letter of next word
  47. for (;; p++) {
  48. if (*p == '\0') {
  49. return NULL;
  50. } else if (!isspace(*p)) {
  51. break;
  52. }
  53. }
  54. return p;
  55. }
  56. int
  57. paramize(void)
  58. {
  59. char *p = line;
  60. char *w = line;
  61. nparams = 0;
  62. while ((w = nextword(p)) != NULL) {
  63. params[nparams++] = w;
  64. //puts(w);
  65. p = w;
  66. }
  67. return 0;
  68. }
  69. int
  70. spit(void)
  71. {
  72. // TODO: should we always spit the original?
  73. return fputs(line, stdout);
  74. }
  75. int
  76. tokenp(void)
  77. {
  78. int i;
  79. // implicit new paragraph via an empty line is a special case
  80. if (line[0] == '\n') {
  81. newparagraph();
  82. return 0;
  83. }
  84. for (i = 0; i < LENGTH(tokens); i++) {
  85. const char * t = tokens[i].name;
  86. size_t len = strlen(t);
  87. if (!strncmp(line, t, len) && isspace(line[len])) {
  88. paramize();
  89. tokens[i].fun();
  90. return 1;
  91. }
  92. }
  93. spit();
  94. return 0;
  95. }
  96. int
  97. main(int argc, char *argv[])
  98. {
  99. FILE *stream = stdin;
  100. size_t len = 0;
  101. ssize_t nread;
  102. spitheader();
  103. while ((nread = getline(&line, &len, stream)) != -1) {
  104. linenum++;
  105. tokenp();
  106. }
  107. free(line);
  108. if (inparagraph) {
  109. puts("</p>");
  110. }
  111. spitfooter();
  112. if (nerrors > 0) {
  113. fprintf(stderr, "Generation finished with %d error(s).\n", nerrors);
  114. return 1;
  115. }
  116. return 0;
  117. }