better handling of relative path
All checks were successful
pyrite-dev/taiga/pipeline/head This commit looks good

This commit is contained in:
Nishi 2026-03-10 05:04:34 +09:00
commit 69a9134f11
Signed by: nishi
GPG key ID: 27EF69B208EB9343
3 changed files with 127 additions and 25 deletions

View file

@ -6,7 +6,6 @@ static int mode = 0;
static char* title = NULL;
static int in_title = 0;
static int in_section = 0;
static int in_pre = 0;
static char** mapping;
static int mapping_len;
@ -90,12 +89,11 @@ static int enter_block(MD_BLOCKTYPE type, void* detail, void* user) {
indent++;
} else if(type == MD_BLOCK_CODE) {
print_indent();
fprintf(out, "<pre>");
fprintf(out, "<pre>\n");
indent++;
print_indent();
fprintf(out, "<code>");
fprintf(out, "<code>\n");
indent++;
in_pre = 1;
} else if(type == MD_BLOCK_TABLE) {
print_indent();
fprintf(out, "<table>\n");
@ -178,7 +176,6 @@ static int leave_block(MD_BLOCKTYPE type, void* detail, void* user) {
indent--;
print_indent();
fprintf(out, "</pre>\n");
in_pre = 0;
} else if(type == MD_BLOCK_TABLE) {
indent--;
print_indent();
@ -216,9 +213,13 @@ static int enter_span(MD_SPANTYPE type, void* detail, void* user) {
fprintf(out, "<strong>\n");
indent++;
} else if(type == MD_SPAN_A) {
MD_SPAN_A_DETAIL* det = detail;
char* href = encode(det->href.text, det->href.size);
MD_SPAN_A_DETAIL* det = detail;
char* href = encode(det->href.text, det->href.size);
char* href_wd = href;
int i;
char* str;
while((str = strstr(href_wd, "./")) == href_wd) href_wd = str + 2;
for(i = 0; i < mapping_len; i++) {
char* key = u_strdup(mapping[i]);
@ -229,7 +230,7 @@ static int enter_span(MD_SPANTYPE type, void* detail, void* user) {
value++;
}
if(value != NULL && strcmp(key, href) == 0) {
if(value != NULL && strcmp(key, href_wd) == 0) {
free(href);
href = encode(value, -1);
}
@ -311,7 +312,7 @@ static int leave_span(MD_SPANTYPE type, void* detail, void* user) {
}
static int text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* user) {
if(in_title && (type == MD_TEXT_NORMAL || type == MD_TEXT_ENTITY)) {
if(in_title && (type == MD_TEXT_NORMAL || type == MD_TEXT_ENTITY || type == MD_TEXT_CODE)) {
if(title == NULL) {
title = malloc(size + 1);
@ -411,7 +412,6 @@ int action_markdown(int argc, char** argv) {
in_title = 0;
in_section = 0;
in_pre = 0;
mode = 0;
if(md_parse(buffer, size, &parser, NULL)) {
free(buffer);
@ -432,7 +432,6 @@ int action_markdown(int argc, char** argv) {
in_title = 0;
in_section = 0;
in_pre = 0;
mode = 1;
if(md_parse(buffer, size, &parser, NULL)) {
free(buffer);

View file

@ -1,8 +1,70 @@
#include <taiga.h>
static int scan(const char* inp, const char* path) {
static const char* inp;
static const char* oup;
typedef struct stringkv {
char* key;
char* value;
} stringkv_t;
static stringkv_t* paths = NULL;
#define IS_INDEX(x) (strcmp((x), "README.md") == 0)
static void populate(const char* path) {
char* in = u_strvacat(inp, "/", path, NULL);
IO_DIR* dir;
if((dir = io_opendir(in)) != NULL) {
struct io_dirent* d;
while((d = io_readdir(dir)) != NULL) {
char* p;
struct io_stat s;
if(strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) continue;
p = u_strvacat(in, d->d_name, NULL);
if(io_stat(p, &s) == 0) {
char* str;
int is_md = 0;
str = strrchr(d->d_name, '.');
if(str != NULL && strcmp(str, ".md") == 0) is_md = 1;
if(IO_S_ISDIR(s.st_mode)) {
char* p2 = u_strvacat(path, d->d_name, "/", NULL);
populate(p2);
free(p2);
} else if(is_md) {
char* p2 = u_strvacat(path, d->d_name, NULL);
char* pathv;
if(IS_INDEX(d->d_name)) {
pathv = u_strdup(path);
} else {
char* n = u_strdup(d->d_name);
char* str;
if((str = strchr(n, '.')) != NULL) str[0] = 0;
pathv = u_strvacat(path, n, "/", NULL);
free(n);
}
shput(paths, p2, pathv);
free(p2);
}
}
free(p);
}
}
}
static int scan(const char* top, const char* path) {
char* in = u_strvacat(inp, "/", path, NULL);
char* out = u_strvacat("site/content/", path, NULL);
char* out = u_strvacat(oup, path, NULL);
IO_DIR* dir;
io_mkdir(out, 0755);
@ -24,12 +86,14 @@ static int scan(const char* inp, const char* path) {
if(str != NULL && strcmp(str, ".md") == 0) is_md = 1;
if(IO_S_ISDIR(s.st_mode)) {
char* p2 = u_strvacat(d->d_name, "/", NULL);
char* p2 = u_strvacat(path, d->d_name, "/", NULL);
char* o = u_strvacat(out, d->d_name, NULL);
char* t = u_strvacat(top, "../", NULL);
io_mkdir(o, 0755);
free(o);
if(!scan(inp, p2)) {
if(!scan(t, p2)) {
free(t);
free(p2);
free(p);
io_closedir(dir);
@ -38,33 +102,57 @@ static int scan(const char* inp, const char* path) {
return 0;
}
free(t);
free(p2);
} else if(is_md) {
char** argv = NULL;
char* o = NULL;
int i;
printf("%s:\n", p);
arrput(argv, p);
if(strcmp(d->d_name, "README.md") == 0) {
if(IS_INDEX(d->d_name)) {
o = u_strvacat(out, "index.xml", NULL);
} else {
char* n = u_strdup(d->d_name);
char* str;
char* d;
char* pathd;
if((str = strchr(n, '.')) != NULL) str[0] = 0;
d = u_strvacat(out, n, NULL);
o = u_strvacat(d, "/index.xml", NULL);
io_mkdir(d, 0755);
free(d);
pathd = u_strvacat(out, n, NULL);
o = u_strvacat(pathd, "/index.xml", NULL);
io_mkdir(pathd, 0755);
free(pathd);
free(n);
}
if(o != NULL) arrput(argv, o);
arrput(argv, o);
for(i = 0; i < shlen(paths); i++) {
char* t;
char* v;
if(IS_INDEX(d->d_name)) {
t = u_strdup(top);
} else {
t = u_strvacat(top, "../", NULL);
}
if(strstr(paths[i].value, path) == paths[i].value) {
v = u_strvacat(paths[i].key + strlen(path), "=", paths[i].value + strlen(path), NULL);
arrput(argv, v);
}
v = u_strvacat(top, paths[i].key, "=", t, paths[i].value, NULL);
arrput(argv, v);
free(t);
}
if(action_markdown(arrlen(argv), argv)) {
for(i = 2; i < arrlen(argv); i++) free(argv[i]);
free(o);
arrfree(argv);
free(p);
@ -74,6 +162,7 @@ static int scan(const char* inp, const char* path) {
return 0;
}
free(o);
for(i = 2; i < arrlen(argv); i++) free(argv[i]);
arrfree(argv);
}
}
@ -90,15 +179,29 @@ static int scan(const char* inp, const char* path) {
}
int action_markdown_dir(int argc, char** argv) {
int i;
if(argc != 1) {
fprintf(stderr, "Usage: markdown-dir input\n");
fprintf(stderr, "Usage: markdown-dir input [output]\n");
return 1;
}
if(!scan(argv[0], "")) {
inp = argv[0];
oup = (argc >= 2) ? argv[1] : "site/content/";
paths = NULL;
sh_new_strdup(paths);
populate("");
if(!scan("", "")) {
for(i = 0; i < shlen(paths); i++) free(paths[i].value);
shfree(paths);
return 1;
}
for(i = 0; i < shlen(paths); i++) free(paths[i].value);
shfree(paths);
return 0;
}

View file

@ -23,7 +23,7 @@ static int scan(const char* top, int mode, const char* path) {
p = u_strvacat(in, d->d_name, NULL);
if(io_stat(p, &s) == 0) {
if(IO_S_ISDIR(s.st_mode)) {
char* p2 = u_strvacat(d->d_name, "/", NULL);
char* p2 = u_strvacat(path, d->d_name, "/", NULL);
char* t = u_strvacat(top, "../", NULL);
char* o = u_strvacat(out, d->d_name, NULL);