"pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "horrorshow"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "idna"
version = "0.1.4"
"comrak 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"gio 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "horrorshow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sourceview 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
"checksum gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0847c507e52c1feaede13ef56fb4847742438602655449d5f1f782e8633f146f"
"checksum gtk-source-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b893d266bbc13de37ecd4ab7125761ce4cb924b1cf4603e73f14d13ca7d3a9c"
"checksum gtk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "905fcfbaaad1b44ec0b4bba9e4d527d728284c62bc2ba41fccedace2b096766f"
+"checksum horrorshow 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d587765115bf4e613f0c88e3fcad077dc9b1a339de89912f6a75f21049938bce"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8"
"checksum itertools 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3f2be4da1690a039e9ae5fd575f706a63ad5a2120f161b1d653c9da3930dd21"
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
- <child>
- <object class="GtkToolbar" id="toolbar">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkToolButton" id="open_button">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Open</property>
- <property name="is_important">True</property>
- <property name="label" translatable="yes">Open</property>
- <property name="use_underline">True</property>
- <property name="icon_name">document-open</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkToolButton" id="render_button">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Render Markdown</property>
- <property name="is_important">True</property>
- <property name="label" translatable="yes">Render</property>
- <property name="use_underline">True</property>
- <property name="icon_name">view-refresh</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkToggleToolButton" id="live_button">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="tooltip_text" translatable="yes">Live Markdown</property>
- <property name="label" translatable="yes">Live</property>
- <property name="use_underline">True</property>
- <property name="icon_name">media-playback-start</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkSeparatorToolItem" id="spacer">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="visible_vertical">False</property>
- <property name="draw">False</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="homogeneous">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkToolButton" id="about_button">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="use_underline">True</property>
- <property name="stock_id">gtk-about</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="homogeneous">False</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
<child>
<object class="GtkPaned">
<property name="visible">True</property>
</object>
</child>
<child type="titlebar">
- <placeholder/>
+ <object class="GtkHeaderBar" id="header_bar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="show_close_button">True</property>
+ <child>
+ <object class="GtkToolButton" id="open_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Open</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Open</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">document-open</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="render_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Render</property>
+ <property name="is_important">True</property>
+ <property name="label" translatable="yes">Render</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">view-refresh</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToggleToolButton" id="live_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Live</property>
+ <property name="label" translatable="yes">Live</property>
+ <property name="use_underline">True</property>
+ <property name="icon_name">media-playback-start</property>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolButton" id="about_button">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">About</property>
+ <property name="use_underline">True</property>
+ <property name="stock_id">gtk-about</property>
+ </object>
+ <packing>
+ <property name="pack_type">end</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
</child>
</object>
<object class="GtkAboutDialog" id="about_dialog">
extern crate gtk;
extern crate sourceview;
extern crate comrak;
+#[macro_use]
+extern crate horrorshow;
-mod markdown;
+mod preview;
use std::env::args;
use std::fs::File;
use gio::prelude::*;
use gtk::prelude::*;
use gtk::Builder;
-
-use markdown::{string_to_html, buffer_to_html};
+use gtk::TextBuffer;
const NAME: &str = env!("CARGO_PKG_NAME");
const VERSION: &str = env!("CARGO_PKG_VERSION");
let _ = reader.read_to_string(&mut contents);
text_view.get_buffer().unwrap().set_text(&contents);
- markdown_view.get_buffer().unwrap().set_text(&string_to_html(&contents));
+ markdown_view.get_buffer().unwrap().set_text(&preview::render(&contents));
}
file_chooser.hide();
text_view.connect_key_release_event(clone!(text_view, markdown_view, live_button => move |_, _| {
if live_button.get_active() {
- let buffer = text_view.get_buffer().unwrap();
- markdown_view.get_buffer().unwrap().set_text(&buffer_to_html(&buffer));
+ let markdown = buffer_to_string(text_view.get_buffer());
+ markdown_view.get_buffer().unwrap().set_text(&preview::render(&markdown));
}
Inhibit(true)
}));
render_button.connect_clicked(clone!(text_view, markdown_view => move |_| {
- let buffer = text_view.get_buffer().unwrap();
- markdown_view.get_buffer().unwrap().set_text(&buffer_to_html(&buffer));
+ let markdown = buffer_to_string(text_view.get_buffer());
+ markdown_view.get_buffer().unwrap().set_text(&preview::render(&markdown));
}));
about_button.connect_clicked(clone!(about_dialog => move |_| {
window.show_all();
}
+fn buffer_to_string(buffer: Option<TextBuffer>) -> String {
+ let buffer = buffer.unwrap();
+ let (start, end) = buffer.get_bounds();
+ let text = buffer.get_text(&start, &end, false);
+
+ text.unwrap()
+}
+
fn main() {
let application = gtk::Application::new("com.github.markdown-rs", gio::ApplicationFlags::empty())
.expect("Initialization failed...");
--- /dev/null
+
+// https://github.com/Stebalien/horrorshow-rs
+use horrorshow::Raw;
+use horrorshow::helper::doctype;
+
+// https://github.com/kivikakk/comrak
+use comrak::{markdown_to_html, ComrakOptions};
+
+pub fn string_to_html(markdown: &str) -> String {
+ let options = ComrakOptions {
+ hardbreaks: true,
+ ext_table: true,
+ ext_strikethrough: true,
+ ..ComrakOptions::default()
+ };
+
+ markdown_to_html(markdown, &options)
+}
+
+pub fn render(markdown: &str) -> String {
+ format!(
+ "{}",
+ html!(
+ : doctype::HTML;
+ html {
+ head {
+ link(rel="stylesheet", href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css") {}
+ script(src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js") {}
+ script(src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/languages/rust.min.js") {}
+ script {
+ : Raw("hljs.initHighlightingOnLoad()")
+ }
+ style {
+ : "body { width: 80%; margin: 0 auto }";
+ : "img { max-width: 80% }"
+ }
+ }
+ body {
+ : Raw(&string_to_html(markdown));
+ }
+ }
+ )
+ )
+}