~fancycade/szc

bd35b82118214e52308ef9d8c7892c3220059cb9 — Fancy Cade 2 years ago
Initial commit
6 files changed, 399 insertions(+), 0 deletions(-)

A .build.yml
A .editorconfig
A .gitignore
A README.md
A meson.build
A src/main.c
A  => .build.yml +11 -0
@@ 1,11 @@
image: alpine/edge
packages:
  - meson
  - samurai
tasks:
  - build: |
      cd szc
      meson build
      samu -C build
sources:
  - https://git.sr.ht/~fancycade/szc

A  => .editorconfig +9 -0
@@ 1,9 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
trim_trailing_whitespace = true
indent_style = tab
indent_size = 8

A  => .gitignore +1 -0
@@ 1,1 @@
build/

A  => README.md +47 -0
@@ 1,47 @@
# szc

# Install
    cd szc
    meson build
    ninja -C build

# Usage
    build/szc

There is an index.md in the zettelkasten directory.

index.md

The index links to hubs, hubs link to zettels.

open szc
szc new
-> *hubname*

szc ls
-> List hubs

list hubs

type in hubname

Select hub 

ls hubs

new *zettelname*

open *zettelname*

link *zettelname*

ls hubs

select hub

ls zettels

select zettel

add link to ls


A  => meson.build +44 -0
@@ 1,44 @@
project(
	'szc',
	'c',
	version: '0.1.0',
	license: 'GPL',
	meson_version: '>=0.51.0',
	default_options: [
		'c_std=c11',
		'warning_level=2',
		'werror=true',
	],
)

cc = meson.get_compiler('c')

add_project_arguments(cc.get_supported_arguments([
	'-D_POSIX_C_SOURCE=200809L',
	'-Wundef',
	'-Wlogical-op',
	'-Wmissing-include-dirs',
	'-Wold-style-definition',
	'-Wpointer-arith',
	'-Winit-self',
	'-Wstrict-prototypes',
	'-Wimplicit-fallthrough=2',
	'-Wendif-labels',
	'-Wstrict-aliasing=2',
	'-Woverflow',
	'-Wmissing-prototypes',
	'-Wno-missing-braces',
	'-Wno-missing-field-initializers',
	'-Wno-unused-parameter',
]), language: 'c')

uuid = dependency('uuid')

executable(
	'szc',
	files(
		'src/main.c',
	),
	install: true,
	dependencies: [uuid]
)

A  => src/main.c +287 -0
@@ 1,287 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <uuid/uuid.h>
#include <sys/stat.h>
#include <sys/types.h>

void read_zettel(char* filename);
void read_hub(char* hubpath);
void new_zettel(char* hubpath, char* title);
void new_hub(char* hubpath);
void list_hubs(char* zdir);
void user_interface(void);
int get_path(char* path, char* zettel, char* hub);
int scan_zettel(char* path, char* zettel);


void
new_zettel(char* hubpath, char* title)
{
        char zname[100];
        char uuid[37];
        uuid_t binuuid;
        uuid_generate_random(binuuid);
        uuid_unparse_upper(binuuid, uuid);
        strncpy(zname, uuid, 9);
        zname[8] = '\0';
        strcat(zname, ".md");

        char filename[500];
        sprintf(filename, "%s/%s", hubpath, zname);

        FILE* fp = fopen(filename, "w");
        if (fp == NULL) {
                fclose(fp);
                return;
        }

        char tl[100];
        sprintf(tl, "title: %s\n", title),
        fputs(tl, fp);
        fputs("---\n", fp);

        fclose(fp);

        char command[600];
        sprintf(command, "$EDITOR %s", filename);

        system(command);
}

void
new_hub(char* hubpath)
{
        int result = mkdir(hubpath, 0777);
        if (result != 0)
                printf("Failed to make hub\n");
}

void
read_zettel(char* filename)
{
        FILE* fp = fopen(filename, "r");
        if (fp == NULL) {
                printf("File not found\n");
                goto end;
        }


        char buffer[100];
        size_t n = 0;
        while (1) {
                fgets(buffer, 100, fp);
                if (strcmp(buffer, "---\n") == 0)
                        break;

                printf("%s - %s", filename, buffer);

                if (n > 5) // Back up plan
                        break;

                n = n + 1;
        }

end:
        fclose(fp);
}

void
read_hub(char* hubpath)
{
        struct dirent* de;

        DIR* dr = opendir(hubpath);
        if (dr == NULL)
                goto end;

        while ((de = readdir(dr)) != NULL) {
                if (strcmp(de->d_name, ".") != 0 &&
                    strcmp(de->d_name, "..") != 0) {
                        char abs[100];
                        strcpy(abs, hubpath);
                        strcat(abs, "/");
                        strcat(abs, de->d_name);
                        read_zettel(abs);
                }
        }

end:
        closedir(dr);
}

void
list_hubs(char* zdir)
{
        struct dirent* de;

        DIR* dr = opendir(zdir);
        if (dr == NULL)
                goto end;

        while((de = readdir(dr)) != NULL) {
                if (strcmp(de->d_name, ".") != 0 &&
                    strcmp(de->d_name, "..") != 0) {
                        printf("%s\n", de->d_name);
                }
        }
end:
        closedir(dr);
}

int
scan_zettel(char* path, char* zettel)
{
        int signal = 0;
        FILE* fp = fopen(path, "r");
        if (fp == NULL)
                goto end;

        char buffer[100];
        size_t n = 0;
        while (1) {
                fgets(buffer, 100, fp);
                if (strcmp(buffer, "---\n") == 0)
                        break;

                strtok(buffer, " "); // Skip first
                char* title = strtok(NULL, " ");
                title[strcspn(title, "\n")] = '\0'; // Trim newline
                if (strcmp(title, zettel)) {
                        signal = 1;
                        break;
                }

                if (n > 5) // Back up plan
                        break;
                n = n + 1;
        }

end:
        fclose(fp);
        return signal;
}

int
get_path(char* path, char* zettel, char* hub)
{
        struct dirent* de;

        int signal = 0;
        DIR* dr = opendir(hub);
        while((de = readdir(dr)) != NULL) {
                if (strcmp(de->d_name, ".") != 0 &&
                    strcmp(de->d_name, "..") != 0) {
                        char abs[300];
                        sprintf(abs, "%s/%s", hub, de->d_name);
                        int result = scan_zettel(abs, zettel);
                        if (result != 0) {
                                strcpy(path, abs);
                                break;
                        }
                }
        }

        closedir(dr);
        return signal;
}

void
user_interface(void)
{
        char* zdir = "zettelkasten/";

        printf("Hi there! Welcome to Simple Zettelkasten in C\n");
        printf("Do you want to create a new zettel or search for a zettel?\n");

        char choice[10];
        fgets(choice, 10, stdin);
        choice[strcspn(choice, "\n")] = '\0';

        if (strcmp(choice, "query") == 0) {

                printf("Hi there! Select a hub:\n");
                list_hubs(zdir);

                char hub[50];
                fgets(hub, 50, stdin);
                hub[strcspn(hub, "\n")] = '\0';

                char hubpath[300];
                strcpy(hubpath, zdir);
                strcat(hubpath, hub);
                printf("Selected %s\n", hub);

                printf("Select a zettel:\n");
                read_hub(hubpath);

                char zettel[100];
                fgets(zettel, 100, stdin);

                char path[50];
                if (get_path(path, zettel, hubpath) != 0) {
                        printf("Unable to find zettel\n");
                        return;
                }

                char command[100];
                sprintf(command, "$EDITOR %s", path);

                system(command);

        } else if (strcmp(choice, "new") == 0) {
                printf("Do you want to create a new hub or zettel?\n");
                char choice2[10];
                fgets(choice2, 10, stdin);
                choice2[strcspn(choice2, "\n")] = '\0';

                if (strcmp(choice2, "hub") == 0) {
                        printf("Enter new hub name:\n");
                        char hubname[50];
                        fgets(hubname, 50, stdin);
                        hubname[strcspn(hubname, "\n")] = '\0';

                        char hubpath[150];
                        strcpy(hubpath, zdir);
                        strcat(hubpath, hubname);

                        new_hub(hubpath);
                } else if (strcmp(choice2, "zettel") == 0) {
                        printf("Listing hubs:\n");
                        list_hubs(zdir);
                        printf("------\n");
                        printf("Select hub:\n");

                        char hubname[50];
                        fgets(hubname, 50, stdin);
                        hubname[strcspn(hubname, "\n")] = '\0';

                        char hubpath[200];
                        strcpy(hubpath, zdir);
                        strcat(hubpath, hubname);

                        printf("Enter the title of your new zettel:\n");

                        char zettel[50];
                        fgets(zettel, 50, stdin);
                        zettel[strcspn(zettel, "\n")] = '\0';

                        new_zettel(hubpath, zettel);

                } else {
                        printf("Invalid command: %s. Try hub or zettel\n", choice2);
                }
        } else {
                printf("Invalid command: %s. Try query or new\n", choice);
        }


}

int
main(int argc, char* argv[])
{
        user_interface();
        return 0;
}