diff options
| author | Joseph Hunkeler <jhunkeler@users.noreply.github.com> | 2024-08-28 13:52:12 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-28 13:52:12 -0400 | 
| commit | b625cf2045a73b9477abe3cc25f38bf34c8c483b (patch) | |
| tree | abc1f6dfaef579b2248f81d176c65aa789f18b9e | |
| parent | f22a121c6667e3139f8695ff1dbcc0b33039f330 (diff) | |
| download | stasis-b625cf2045a73b9477abe3cc25f38bf34c8c483b.tar.gz | |
Pandoc improvements (#37)
* Tweak pandoc command and add a style sheet
* Only search for platform sub-string when valid
* Add get_pandoc_version
* Add version checking and set options accordingly
* Add support for  globals.sysconfdir
* Add missing brace
* Remove options that are created dynamically
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/stasis_indexer.c | 134 | ||||
| -rw-r--r-- | stasis_pandoc.css | 232 | 
3 files changed, 355 insertions, 12 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index f358b22..abb700c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,5 +35,6 @@ endif()  set(SYSCONFDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_SYSCONFDIR}")  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/config.h @ONLY) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/stasis_pandoc.css DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/stasis)  install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/stasis.ini DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/stasis)  install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mission DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/stasis) diff --git a/src/stasis_indexer.c b/src/stasis_indexer.c index 4f57a86..25f0fa7 100644 --- a/src/stasis_indexer.c +++ b/src/stasis_indexer.c @@ -119,12 +119,7 @@ int indexer_load_metadata(struct Delivery *ctx, const char *filename) {          } else if (!strcmp(name, "codename")) {              ctx->meta.codename = strdup(value);          } else if (!strcmp(name, "platform")) { -            ctx->system.platform = calloc(DELIVERY_PLATFORM_MAX, sizeof(*ctx->system.platform)); -            char **platform = split(value, " ", 0); -            ctx->system.platform[DELIVERY_PLATFORM] = platform[DELIVERY_PLATFORM]; -            ctx->system.platform[DELIVERY_PLATFORM_CONDA_SUBDIR] = platform[DELIVERY_PLATFORM_CONDA_SUBDIR]; -            ctx->system.platform[DELIVERY_PLATFORM_CONDA_INSTALLER] = platform[DELIVERY_PLATFORM_CONDA_INSTALLER]; -            ctx->system.platform[DELIVERY_PLATFORM_RELEASE] = platform[DELIVERY_PLATFORM_RELEASE]; +            ctx->system.platform = split(value, " ", 0);          } else if (!strcmp(name, "arch")) {              ctx->system.arch = strdup(value);          } else if (!strcmp(name, "time")) { @@ -229,6 +224,56 @@ struct Delivery **get_latest_deliveries(struct Delivery ctx[], size_t nelem) {      return result;  } +int get_pandoc_version(size_t *result) { +    *result = 0; +    int state = 0; +    char *version_str = shell_output("pandoc --version", &state); +    if (state || !version_str) { +        // an error occurred +        return -1; +    } + +    // Verify that we're looking at pandoc +    if (strlen(version_str) > 7 && !strncmp(version_str, "pandoc ", 7)) { +        // we have pandoc +        char *v_begin = &version_str[7]; +        if (!v_begin) { +            SYSERROR("unexpected pandoc output: %s", version_str); +            return -1; +        } +        char *v_end = strchr(version_str, '\n'); +        if (v_end) { +            *v_end = 0; +        } + +        char **parts = split(v_begin, ".", 0); +        if (!parts) { +            SYSERROR("unable to split pandoc version string, '%s': %s", version_str, strerror(errno)); +            return -1; +        } + +        size_t parts_total; +        for (parts_total = 0; parts[parts_total] != NULL; parts_total++); + +        // generate the version as an integer +        // note: pandoc version scheme never exceeds four elements (or bytes in this case) +        for (size_t i = 0; i < 4; i++) { +            unsigned char tmp = 0; +            if (i < parts_total) { +                // only process version elements we have. the rest will be zeros. +                tmp = strtoul(parts[i], NULL, 10); +            } +            // pack version element into result +            *result = (*result << 8) | tmp; +        } +    } else { +        // invalid version string +        return 1; +    } + +    return 0; +} +  int indexer_make_website(struct Delivery *ctx) {      char cmd[PATH_MAX];      const char *pattern = "*.md"; @@ -238,6 +283,43 @@ int indexer_make_website(struct Delivery *ctx) {          return 0;      } +    char *css_filename = calloc(PATH_MAX, sizeof(*css_filename)); +    if (!css_filename) { +        SYSERROR("unable to allocate string for CSS file path: %s", strerror(errno)); +        return -1; +    } + +    sprintf(css_filename, "%s/%s", globals.sysconfdir, "stasis_pandoc.css"); +    int have_css = access(css_filename, F_OK | R_OK) == 0; + +    char pandoc_versioned_args[255] = {0}; +    size_t pandoc_version = 0; + +    if (!get_pandoc_version(&pandoc_version)) { +        // < 2.19 +        if (pandoc_version < 0x02130000) { +            strcat(pandoc_versioned_args, "--self-contained "); +        } else { +            // >= 2.19 +            strcat(pandoc_versioned_args, "--embed-resources "); +        } + +        // >= 1.15.0.4 +        if (pandoc_version >= 0x010f0004) { +            strcat(pandoc_versioned_args, "--standalone "); +        } + +        // >= 1.10.0.1 +        if (pandoc_version >= 0x010a0001) { +            strcat(cmd, "-f markdown+autolink_bare_uris "); +        } + +        // >= 3.1.10 +        if (pandoc_version >= 0x03010a00) { +            strcat(cmd, "-f markdown+alerts "); +        } +    } +      struct StrList *dirs = strlist_init();      strlist_append(&dirs, ctx->storage.delivery_dir);      strlist_append(&dirs, ctx->storage.results_dir); @@ -269,7 +351,13 @@ int indexer_make_website(struct Delivery *ctx) {              // Converts a markdown file to html              strcpy(cmd, "pandoc "); -            strcat(cmd, "--standalone "); +            strcat(cmd, pandoc_versioned_args); +            if (have_css) { +                strcat(cmd, "--css "); +                strcat(cmd, css_filename); +            } +            strcat(cmd, " "); +            strcat(cmd, "--metadata title=\"STASIS\" ");              strcat(cmd, "-o ");              strcat(cmd, fullpath_dest);              strcat(cmd, " "); @@ -423,8 +511,11 @@ int indexer_readmes(struct Delivery ctx[], size_t nelem) {                  char *arch = strlist_item(archs, a);                  int have_combo = 0;                  for (size_t i = 0; i < nelem; i++) { -                    if (strstr(latest[i]->system.platform[DELIVERY_PLATFORM_RELEASE], platform) && strstr(latest[i]->system.arch, arch)) { -                        have_combo = 1; +                    if (latest[i] && latest[i]->system.platform) { +                        if (strstr(latest[i]->system.platform[DELIVERY_PLATFORM_RELEASE], platform) && +                            strstr(latest[i]->system.arch, arch)) { +                            have_combo = 1; +                        }                      }                  }                  if (!have_combo) { @@ -500,9 +591,12 @@ int indexer_junitxml_report(struct Delivery ctx[], size_t nelem) {                  char *arch = strlist_item(archs, a);                  int have_combo = 0;                  for (size_t i = 0; i < nelem; i++) { -                    if (strstr(latest[i]->system.platform[DELIVERY_PLATFORM_RELEASE], platform) && strstr(latest[i]->system.arch, arch)) { -                        have_combo = 1; -                        break; +                    if (latest[i] && latest[i]->system.platform) { +                        if (strstr(latest[i]->system.platform[DELIVERY_PLATFORM_RELEASE], platform) && +                            strstr(latest[i]->system.arch, arch)) { +                            have_combo = 1; +                            break; +                        }                      }                  }                  if (!have_combo) { @@ -664,10 +758,26 @@ int main(int argc, char *argv[]) {              if (isempty(rootdirs[i]) || !strcmp(rootdirs[i], "/") || !strcmp(rootdirs[i], "\\")) {                  SYSERROR("Unsafe directory: %s", rootdirs[i]);                  exit(1); +            } else if (access(rootdirs[i], F_OK)) { +                SYSERROR("%s: %s", rootdirs[i], strerror(errno)); +                exit(1);              }          }      } +    char stasis_sysconfdir_tmp[PATH_MAX]; +    if (getenv("STASIS_SYSCONFDIR")) { +        strncpy(stasis_sysconfdir_tmp, getenv("STASIS_SYSCONFDIR"), sizeof(stasis_sysconfdir_tmp) - 1); +    } else { +        strncpy(stasis_sysconfdir_tmp, STASIS_SYSCONFDIR, sizeof(stasis_sysconfdir_tmp) - 1); +    } + +    globals.sysconfdir = realpath(stasis_sysconfdir_tmp, NULL); +    if (!globals.sysconfdir) { +        msg(STASIS_MSG_ERROR | STASIS_MSG_L1, "Unable to resolve path to configuration directory: %s\n", stasis_sysconfdir_tmp); +        exit(1); +    } +      char *workdir;      char workdir_template[PATH_MAX] = {0};      char *system_tmp = getenv("TMPDIR"); diff --git a/stasis_pandoc.css b/stasis_pandoc.css new file mode 100644 index 0000000..456c3e9 --- /dev/null +++ b/stasis_pandoc.css @@ -0,0 +1,232 @@ +/* Modified pandoc defaults */ + +html { +	color: #1a1a1a; +	background-color: #fdfdfd; +} + +body { +	margin: 0 auto; +	max-width: 50%; +	padding-left: 50px; +	padding-right: 50px; +	padding-top: 50px; +	padding-bottom: 50px; +	hyphens: auto; +	overflow-wrap: break-word; +	text-rendering: optimizeLegibility; +	font-kerning: normal; +} + +@media (max-width: 600px) { +	body { +		font-size: 0.9em; +		padding: 12px; +	} + +	h1 { +		font-size: 1.8em; +	} +} + +@media print { +	html { +		background-color: white; +	} + +	body { +		background-color: transparent; +		color: black; +		font-size: 12pt; +	} + +	p, +	h2, +	h3 { +		orphans: 3; +		widows: 3; +	} + +	h2, +	h3, +	h4 { +		page-break-after: avoid; +	} +} + +p { +	margin: 1em 0; +} + +/* Use browser defaults +a { +color: #1a1a1a; +} +a:visited { +color: #1a1a1a; +} +*/ +img { +	max-width: 100%; +} + +svg { +	height: auto; +	max-width: 100%; +} + +h1, +h2, +h3, +h4, +h5, +h6 { +	margin-top: 1.4em; +} + +h5, +h6 { +	font-size: 1em; +	font-style: italic; +} + +h6 { +	font-weight: normal; +} + +ol, +ul { +	padding-left: 1.7em; +	margin-top: 1em; +} + +li>ol, +li>ul { +	margin-top: 0; +} + +blockquote { +	margin: 1em 0 1em 1.7em; +	padding-left: 1em; +	border-left: 2px solid #e6e6e6; +	color: #606060; +} + +code { +	font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace; +	font-size: 90%; +	margin: 0; +	hyphens: manual; +} + +pre { +	margin: 1em 0; +	overflow: auto; +} + +pre code { +	padding: 0; +	overflow: visible; +	overflow-wrap: normal; +} + +.sourceCode { +	background-color: transparent; +	overflow: visible; +} + +hr { +	background-color: #1a1a1a; +	border: none; +	height: 1px; +	margin: 1em 0; +} + +table { +	margin: 1em 0; +	border-collapse: collapse; +	width: 100%; +	overflow-x: auto; +	display: block; +	font-variant-numeric: lining-nums tabular-nums; +} + +table caption { +	margin-bottom: 0.75em; +} + +tbody { +	margin-top: 0.5em; +	border-top: 1px solid #1a1a1a; +	border-bottom: 1px solid #1a1a1a; +} + +th { +	border-top: 1px solid #1a1a1a; +	padding: 0.25em 0.5em 0.25em 0.5em; +} + +td { +	padding: 0.125em 0.5em 0.25em 0.5em; +} + +header { +	margin-bottom: 4em; +	text-align: center; +} + +#TOC li { +	list-style: none; +} + +#TOC ul { +	padding-left: 1.3em; +} + +#TOC>ul { +	padding-left: 0; +} + +#TOC a:not(:hover) { +	text-decoration: none; +} + +code { +	white-space: pre-wrap; +} + +span.smallcaps { +	font-variant: small-caps; +} + +div.columns { +	display: flex; +	gap: min(4vw, 1.5em); +} + +div.column { +	flex: auto; +	overflow-x: auto; +} + +div.hanging-indent { +	margin-left: 1.5em; +	text-indent: -1.5em; +} + +ul.task-list[class] { +	list-style: none; +} + +ul.task-list li input[type="checkbox"] { +	font-size: inherit; +	width: 0.8em; +	margin: 0 0.8em 0.2em -1.6em; +	vertical-align: middle; +} + +.display.math { +	display: block; +	text-align: center; +	margin: 0.5rem auto; +}
\ No newline at end of file | 
