Compare commits
3 Commits
1287949669
...
8678f326cd
Author | SHA1 | Date | |
---|---|---|---|
8678f326cd | |||
843329331d | |||
16c3dcac15 |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "src/hoedown"]
|
||||||
|
path = src/hoedown
|
||||||
|
url = git@github.com:hoedown/hoedown.git
|
@ -21,9 +21,21 @@ add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/resources.c"
|
|||||||
COMMENT "Generating resources"
|
COMMENT "Generating resources"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/src/hoedown/libhoedown.a"
|
||||||
|
COMMAND make libhoedown.a
|
||||||
|
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/src/hoedown"
|
||||||
|
COMMENT "Compiling libhoedown"
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_LIBRARY(HOEDOWN STATIC IMPORTED)
|
||||||
|
SET_TARGET_PROPERTIES(HOEDOWN PROPERTIES
|
||||||
|
IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/src/hoedown/libhoedown.a"
|
||||||
|
)
|
||||||
|
|
||||||
aux_source_directory(./src SRC_LIST)
|
aux_source_directory(./src SRC_LIST)
|
||||||
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
add_executable(${PROJECT_NAME} ${SRC_LIST})
|
||||||
target_sources(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/resources.c")
|
target_sources(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/resources.c")
|
||||||
target_link_libraries(${PROJECT_NAME} ${GTK3_LIBRARIES} ${WEBKIT_LIBRARIES})
|
target_sources(${PROJECT_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/src/hoedown/libhoedown.a")
|
||||||
|
target_link_libraries(${PROJECT_NAME} ${GTK3_LIBRARIES} ${WEBKIT_LIBRARIES} HOEDOWN)
|
||||||
|
|
||||||
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||||
|
@ -13,7 +13,7 @@ Renders everything as is. You will see the source code except for the header abo
|
|||||||
The following constructs are supported: *italics*, **bold**, Headings 1 to 4.
|
The following constructs are supported: *italics*, **bold**, Headings 1 to 4.
|
||||||
|
|
||||||
## Full HTML with Images
|
## Full HTML with Images
|
||||||
As the external md command is invoked and a web browser used to render the content, all markdown syntax supported by the md command is supported.
|
Markdown is rendered using [Hoedown](https://github.com/hoedown/hoedown/) and displayed using an integrated web browser. This all Markdown syntax (including images) are supported.
|
||||||
|
|
||||||
# Encrypted Entries Using GPG
|
# Encrypted Entries Using GPG
|
||||||
MDiary supports gpg encrypted entries. To use this feature, place a gpg encrypted entry as *<name>.md.gpg* in the workspace. MDiary will automatically show a decrypt button in the header bar which will invoke gpg to decrypt all encrypted entries in the workspace for this session.
|
MDiary supports gpg encrypted entries. To use this feature, place a gpg encrypted entry as *<name>.md.gpg* in the workspace. MDiary will automatically show a decrypt button in the header bar which will invoke gpg to decrypt all encrypted entries in the workspace for this session.
|
||||||
|
1
src/hoedown
Submodule
1
src/hoedown
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 980b9c549b4348d50b683ecee6abee470b98acda
|
@ -771,16 +771,18 @@ void mainWindow_calendarSelected(GtkWidget *widget, gpointer user_data)
|
|||||||
|
|
||||||
static void mainWindow_set_text(struct mainWindow *mainWindow, gchar *text, gchar *file_url)
|
static void mainWindow_set_text(struct mainWindow *mainWindow, gchar *text, gchar *file_url)
|
||||||
{
|
{
|
||||||
gchar *tempfile_path = "/tmp/mdiary.tmp.md";
|
|
||||||
gchar *cmd = NULL;
|
gchar *cmd = NULL;
|
||||||
gchar *cmd_stdout = NULL;
|
gchar *cmd_stdout = NULL;
|
||||||
gchar *cmd_stderr = NULL;
|
gchar *cmd_stderr = NULL;
|
||||||
gint exit_status = 0;
|
|
||||||
gchar *base_url = NULL;
|
|
||||||
GFileOutputStream *stream = NULL;
|
GFileOutputStream *stream = NULL;
|
||||||
GFile *file = NULL;
|
GFile *file = NULL;
|
||||||
GtkTextIter iter;
|
GtkTextIter iter;
|
||||||
GtkTextIter iter_end;
|
GtkTextIter iter_end;
|
||||||
|
hoedown_buffer *ob;
|
||||||
|
hoedown_renderer *renderer = NULL;
|
||||||
|
void (*renderer_free)(hoedown_renderer *) = NULL;
|
||||||
|
hoedown_document *document;
|
||||||
|
gchar *base_url = NULL;
|
||||||
|
|
||||||
if (mainWindow->renderer == RENDERER_TEXT) {
|
if (mainWindow->renderer == RENDERER_TEXT) {
|
||||||
gtk_text_buffer_set_text(mainWindow->textBuffer, text, strlen(text));
|
gtk_text_buffer_set_text(mainWindow->textBuffer, text, strlen(text));
|
||||||
@ -802,24 +804,21 @@ static void mainWindow_set_text(struct mainWindow *mainWindow, gchar *text, gcha
|
|||||||
} else {
|
} else {
|
||||||
if (text[0] != '\0') {
|
if (text[0] != '\0') {
|
||||||
base_url = g_strdup_printf("file://%s", file_url);
|
base_url = g_strdup_printf("file://%s", file_url);
|
||||||
file = g_file_new_for_path(tempfile_path);
|
g_info("Rendering markdown as full HTML...");
|
||||||
stream = g_file_replace(
|
|
||||||
file, NULL, FALSE,
|
|
||||||
G_FILE_CREATE_NONE,
|
|
||||||
NULL, NULL);
|
|
||||||
g_output_stream_write(G_OUTPUT_STREAM(stream), text, strlen(text), NULL, NULL);
|
|
||||||
g_output_stream_flush(G_OUTPUT_STREAM(stream), NULL, NULL);
|
|
||||||
|
|
||||||
cmd = g_strdup_printf("markdown %s", tempfile_path);
|
renderer = hoedown_html_renderer_new(0, 0);
|
||||||
if (g_spawn_command_line_sync(cmd, &cmd_stdout, &cmd_stderr, &exit_status, NULL) &&
|
renderer_free = hoedown_html_renderer_free;
|
||||||
exit_status == 0) {
|
|
||||||
webkit_web_view_load_html(WEBKIT_WEB_VIEW(mainWindow->webkitView),
|
ob = hoedown_buffer_new(64);
|
||||||
cmd_stdout, base_url);
|
document = hoedown_document_new(renderer, 0, 16);
|
||||||
} else {
|
hoedown_document_render(document, ob, (const uint8_t *) text, strlen(text));
|
||||||
g_warning("Could not render markdown for file. Showing plain text instead.\n");
|
|
||||||
webkit_web_view_load_html(WEBKIT_WEB_VIEW(mainWindow->webkitView),
|
webkit_web_view_load_html(WEBKIT_WEB_VIEW(mainWindow->webkitView),
|
||||||
text, base_url);
|
hoedown_buffer_cstr(ob), base_url);
|
||||||
}
|
|
||||||
|
hoedown_buffer_free(ob);
|
||||||
|
hoedown_document_free(document);
|
||||||
|
renderer_free(renderer);
|
||||||
g_free(base_url);
|
g_free(base_url);
|
||||||
} else {
|
} else {
|
||||||
webkit_web_view_load_html(WEBKIT_WEB_VIEW(mainWindow->webkitView),
|
webkit_web_view_load_html(WEBKIT_WEB_VIEW(mainWindow->webkitView),
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
#include "mdiary.h"
|
#include "mdiary.h"
|
||||||
#include "md_pango.h"
|
#include "md_pango.h"
|
||||||
|
|
||||||
|
#include "hoedown/src/document.h"
|
||||||
|
#include "hoedown/src/html.h"
|
||||||
|
|
||||||
#define FILE_LIST_MAX_LEN 5
|
#define FILE_LIST_MAX_LEN 5
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
32
src/mdiary.c
32
src/mdiary.c
@ -246,7 +246,7 @@ static gchar *mdiary_get_line_from_string(gchar **str_ptr)
|
|||||||
* @param autoCompletion
|
* @param autoCompletion
|
||||||
*/
|
*/
|
||||||
static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
|
static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
|
||||||
gchar *filename, gchar *content,
|
gchar *filename, gchar *content, GList *autotags,
|
||||||
GtkListStore *entryListStore, GtkListStore *autoCompletion)
|
GtkListStore *entryListStore, GtkListStore *autoCompletion)
|
||||||
{
|
{
|
||||||
GFile *file = NULL;
|
GFile *file = NULL;
|
||||||
@ -263,6 +263,8 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
GString *text = NULL;
|
GString *text = NULL;
|
||||||
guint header_state = 0;
|
guint header_state = 0;
|
||||||
|
|
||||||
|
GList *l;
|
||||||
|
|
||||||
g_message("Add file: %s\n", filename);
|
g_message("Add file: %s\n", filename);
|
||||||
mdiary_scanner->entries_failed++; /* Will be decremented again when entry was successfully added. */
|
mdiary_scanner->entries_failed++; /* Will be decremented again when entry was successfully added. */
|
||||||
|
|
||||||
@ -323,7 +325,7 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
}
|
}
|
||||||
if (!tagList) {
|
if (!tagList) {
|
||||||
g_warning("PARSER: Could not detect tags in file!\n");
|
g_warning("PARSER: Could not detect tags in file!\n");
|
||||||
tagList = g_list_append(tagList, "untagged");
|
tagList = g_list_append(tagList, g_strdup("untagged"));
|
||||||
}
|
}
|
||||||
if (!text) {
|
if (!text) {
|
||||||
g_warning("PARSER: Could not find any text in file!\n");
|
g_warning("PARSER: Could not find any text in file!\n");
|
||||||
@ -338,6 +340,11 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
title = g_strdup("Untitled");
|
title = g_strdup("Untitled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (l = autotags; l != NULL; l = l->next)
|
||||||
|
{
|
||||||
|
tagList = g_list_append(tagList, g_strdup(l->data));
|
||||||
|
}
|
||||||
|
|
||||||
mdiary_scanner->entries_failed--;
|
mdiary_scanner->entries_failed--;
|
||||||
mdiary_scanner->entries_added++;
|
mdiary_scanner->entries_added++;
|
||||||
mdiary_add_entry_to_store(entryListStore,
|
mdiary_add_entry_to_store(entryListStore,
|
||||||
@ -359,6 +366,8 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
g_input_stream_close(G_INPUT_STREAM(stream), NULL, NULL);
|
g_input_stream_close(G_INPUT_STREAM(stream), NULL, NULL);
|
||||||
g_object_unref(file);
|
g_object_unref(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_list_free_full(tagList, *g_free);
|
||||||
g_string_free(text, 0);
|
g_string_free(text, 0);
|
||||||
g_free(summary);
|
g_free(summary);
|
||||||
g_free(title);
|
g_free(title);
|
||||||
@ -366,7 +375,7 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void mdiary_add_gpg_to_store(struct mdiary_scanner *mdiary_scanner,
|
static void mdiary_add_gpg_to_store(struct mdiary_scanner *mdiary_scanner,
|
||||||
gchar *filename,
|
gchar *filename, GList **add_tags,
|
||||||
GtkListStore *entryListStore, GtkListStore *autoCompletion)
|
GtkListStore *entryListStore, GtkListStore *autoCompletion)
|
||||||
{
|
{
|
||||||
gchar *cmd = NULL;
|
gchar *cmd = NULL;
|
||||||
@ -378,7 +387,7 @@ static void mdiary_add_gpg_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
|
|
||||||
if (g_spawn_command_line_sync(cmd, &cmd_stdout, &cmd_stderr, &exit_status, NULL) && exit_status == 0) {
|
if (g_spawn_command_line_sync(cmd, &cmd_stdout, &cmd_stderr, &exit_status, NULL) && exit_status == 0) {
|
||||||
g_message("GPG: Decryption OK!\n");
|
g_message("GPG: Decryption OK!\n");
|
||||||
mdiary_add_file_to_store(mdiary_scanner, filename, cmd_stdout, entryListStore, autoCompletion);
|
mdiary_add_file_to_store(mdiary_scanner, filename, cmd_stdout, *add_tags, entryListStore, autoCompletion);
|
||||||
} else {
|
} else {
|
||||||
mdiary_scanner->entries_failed++;
|
mdiary_scanner->entries_failed++;
|
||||||
mdiary_scanner->error_code |= MDS_ERROR_GPG;
|
mdiary_scanner->error_code |= MDS_ERROR_GPG;
|
||||||
@ -396,6 +405,7 @@ static void mdiary_add_gpg_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
|
|
||||||
static void mdiary_recurse_and_collect(struct mdiary_scanner *mdiary_scanner,
|
static void mdiary_recurse_and_collect(struct mdiary_scanner *mdiary_scanner,
|
||||||
gchar *base_dir,
|
gchar *base_dir,
|
||||||
|
GList **autotags,
|
||||||
GtkListStore *entryListStore,
|
GtkListStore *entryListStore,
|
||||||
GtkListStore *autoCompletion,
|
GtkListStore *autoCompletion,
|
||||||
guint max_level)
|
guint max_level)
|
||||||
@ -417,27 +427,28 @@ static void mdiary_recurse_and_collect(struct mdiary_scanner *mdiary_scanner,
|
|||||||
if (g_regex_match(regex, fullPath, 0, &match_info) &&
|
if (g_regex_match(regex, fullPath, 0, &match_info) &&
|
||||||
g_match_info_matches(match_info))
|
g_match_info_matches(match_info))
|
||||||
mdiary_add_file_to_store(mdiary_scanner,
|
mdiary_add_file_to_store(mdiary_scanner,
|
||||||
fullPath, NULL,
|
fullPath, NULL, *autotags,
|
||||||
entryListStore, autoCompletion);
|
entryListStore, autoCompletion);
|
||||||
g_regex_unref(regex);
|
g_regex_unref(regex);
|
||||||
|
|
||||||
|
|
||||||
regex = g_regex_new("\\.md.gpg$", G_REGEX_CASELESS, 0, NULL);
|
regex = g_regex_new("\\.md.gpg$", G_REGEX_CASELESS, 0, NULL);
|
||||||
if (g_regex_match(regex, fullPath, 0, &match_info) &&
|
if (g_regex_match(regex, fullPath, 0, &match_info) &&
|
||||||
g_match_info_matches(match_info)) {
|
g_match_info_matches(match_info)) {
|
||||||
mdiary_scanner->entries_encrypted++;
|
mdiary_scanner->entries_encrypted++;
|
||||||
if (mdiary_scanner->gpg_enabled)
|
if (mdiary_scanner->gpg_enabled)
|
||||||
mdiary_add_gpg_to_store(mdiary_scanner,
|
mdiary_add_gpg_to_store(mdiary_scanner,
|
||||||
fullPath,
|
fullPath, autotags,
|
||||||
entryListStore, autoCompletion);
|
entryListStore, autoCompletion);
|
||||||
}
|
}
|
||||||
g_regex_unref(regex);
|
g_regex_unref(regex);
|
||||||
|
|
||||||
} else if (g_file_test(fullPath, G_FILE_TEST_IS_DIR) && max_level) {
|
} else if (g_file_test(fullPath, G_FILE_TEST_IS_DIR) && max_level) {
|
||||||
|
*autotags = g_list_append(*autotags, dirname);
|
||||||
mdiary_recurse_and_collect(mdiary_scanner,
|
mdiary_recurse_and_collect(mdiary_scanner,
|
||||||
fullPath,
|
fullPath, autotags,
|
||||||
entryListStore, autoCompletion,
|
entryListStore, autoCompletion,
|
||||||
max_level--);
|
max_level--);
|
||||||
|
*autotags = g_list_remove(*autotags, g_list_last(*autotags)->data);
|
||||||
}
|
}
|
||||||
g_free(fullPath);
|
g_free(fullPath);
|
||||||
}
|
}
|
||||||
@ -478,8 +489,11 @@ gint mdiary_scan_to_store(struct mdiary_scanner *mdiary_scanner,
|
|||||||
gchar *base_dir,
|
gchar *base_dir,
|
||||||
GtkListStore *entryListStore, GtkListStore *autoCompletion)
|
GtkListStore *entryListStore, GtkListStore *autoCompletion)
|
||||||
{
|
{
|
||||||
|
GList *autotags = NULL;
|
||||||
|
|
||||||
mdiary_recurse_and_collect(mdiary_scanner, base_dir, entryListStore, autoCompletion, 5);
|
mdiary_recurse_and_collect(mdiary_scanner, base_dir, &autotags, entryListStore, autoCompletion, 5);
|
||||||
|
|
||||||
|
g_list_free(autotags);
|
||||||
|
|
||||||
return mdiary_scanner->entries_added;
|
return mdiary_scanner->entries_added;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user