Giter VIP home page Giter VIP logo

lazyblorg's Introduction

## -*- coding: utf-8;mode: org; -*- ## Time-stamp: <2015-10-31 10:13:10 vk> ## This file is best viewed with GNU Emacs Org-mode: http://orgmode.org/

«A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.» (Antoine de Saint-Exupéry)

lazyblorg – blogging with Org-mode for very lazy people

This is a web log (blog) environment for GNU Emacs with Org-mode which generates static HTML5 web pages. It is much more superior to any other Org-mode-to-blog-solution I have seen so far!

If you don’t believe me right away, there is a list of similar/alternative projects on http://orgmode.org/worg/org-blog-wiki.html which seem really tedious to me.

See my original post to the Org-mode ML for how this idea of lazyblorg started in 2011.

This awesome piece of software is a sheer beauty with regard to:

  • simplicity of creating a new blog entry
    • I mean it: there is no step which can be skipped!
  • integration into my personal workflows
    • here, you have to either adapt my totally awesome workflows or you have to find alternative ways of doing following things:
      • linking/including image files or attachments in general (I use this Memacs module)
        • advantage of my method: I simply add an image file by typing tsfile:2014-03-03-this-is-my-file-name.jpg in double-brackets and I really don’t care in which folder the file is currently located on my system
      • copying resulting HTML files to webspace (I do it using unison/rsync)
      • probably more to come

Target group

Lazy users of Org-mode who want to do blogging very easily and totally cool.

Or simply wannabes. I’m perfectly fine with this as long as they use lazyblorg.

Skills necessary

  • modifying configuration settings, e.g., in script files
  • optional: creating scheduled tasks (crond, …) if you are a really lazy one (and if you trust lazyblorg to do its job in the background)

System requirements

Development platform is Debian GNU/Linux. So with any GNU/Linux you should be fine as well.

It might work on OS X but I never tried it so far.

I definitely does not work with Microsoft Windows. Although a programmer can add a couple of os.path.thisorthat() here and there and it should be good to go. Please consider sending a pull-request if you are fixing this issue. Thanks!

Version

Currently, I consider lazyblorg in beta-status with version 0.6 or so.

Why lazyblorg?

Minimum effort for blogging.

And: your blog entries can be written anywhere in your Org-mode files. They will be found by lazyblorg. :-)

Further advantages are listed below.

Example workflow for creating a blog entry

  1. write a blog entry anywhere in your Org-mode files
    • With lazyblorg, you can, e.g., write a blog article about an event as a sub-heading of the event itself!
  2. tag your entry with :blog:
  3. add an unique ID in the PROPERTIES drawer
  4. set the state of your entry to DONE
    • make sure that a :LOGBOOK: drawer entry will be created that contains the time-stamp

That’s it. lazyblorg does the rest. It feels like magic, doesn’t it? :-)

Advantages

These things make a blogger a happy one:

No other Org-mode blogging system I know of is able to process blog entries which are scattered across all your Org-mode documents.

No other Org-mode blogging system I know of is able to generate a blog entry with that minimum effort to the author.

You do not need to maintain a specific Org-mode file that contains you blog posts only. *Create* blog posts anywhere in between your notes, todos, contacts, …

And there are some technological advantages you might consider as well:

  • You don’t need to write or correct HTML code by yourself.
  • produces static, state-of-the-art HTML5
    • it’s super-fast on delivery to browsers
    • very low computing requirements on your web server: minimum of server load
  • No in-between format or tool.
    • Direct conversion from Org-mode to HTML/CSS.
    • dependencies have the tendency to cause problems when the dependent tools change over time
    • lazyblorg should be running fine for a long time after it is set up properly
  • Decide by yourself how and where you are hosting your blog files and log files.
  • you will find more advantages when running and using lazyblorg - I am very confident about that ;-)

Disadvantages

Yes, there are some disadvantages. I am totally honest with you since we are becoming close friends right now:

  • lazyblorg re-generates the complete set of output pages on every run
    • this will probably changed in a future release (to me: no high priority)
    • most of the time this is not an issue at all
      • if pages are generated on a different system as the web server runs on, performance is a minor issue
      • if you don’t have thousands of pages, this will not take long
  • lazyblorg is implemented in Python:
    • Its Org-mode parser supports only a sub-set of Org-mode syntax and features.
      • Whenever I think that an additional Org-mode syntax element is needed for my blog, I start thinking of implementing it
  • lazyblorg is using state-of-the art HTML5 and CSS3
    • No old HTML4.01 transitional stuff or similar
    • Results might not be compatible with browsers such as Internet Explorer or mobile devices.
      • tell your Internet Explorer friends that they should do themselves a favor and switch to a real browser
  • You have to accept the one-time setup effort which requires knowledge of:
    • using command-line tools
    • modifying configuration files
    • summary: getting this beautiful thing to work in your environment

Features

lazyblorg will support a basic set of syntax of Org-mode. It will also support RSS/ATOM feed(s), tags, (external) image files, tables, static pages (outside of day-oriented blog entry hierarchy), updates, and more.

«Technology develops from the primitive via the complex to the simple.»

(Antoine de Saint-Exupéry; note: lazyblorg is currently “primitive” but with a great outlook up to the status of being simple)

See FAQs for “What Org-mode elements are supported by lazyblorg?”

FAQs

Why lazyblorg and not <another project>?

Please do read the sections “Why lazyblorg” and “Advantages” above.

Does lazyblorg cost anything?

No.

Although, please do respect the license which is attached to this project.

As with every open source project, you will find that there are some costs: your time. However, you will gain additional knowledge from coping with it. :-)

Am I able to use lazyblorg for myself?

Yes.

Get it from github and read the installation notes in this file.

What Org-mode elements are supported by lazyblorg?

The parser only implements a sub-set of Org-mode syntax. See section “notes” in dev/lazyblorg.org for a plan of supported elements.

An Org-mode test-file (for unit testing) containing all implemented Org-mode syntax elements can be found at: testdata/currently_supported_orgmode_syntax.org

This test-file produces an example HTML entry that can be found at: testdata/currently_supported_orgmode_syntax.html

Where can I find support for lazyblorg?

In short: please do help yourself. :-)

Long: I developed lazyblorg for my own purposes and therefore it is optimized for my own requirements only. If you find lazyblorg cool and you want to use it on your own, I am totally OK with that. However, I can not offer much time in supporting other requirements than my own. If you did not catch this by yourself: I am lazy.

Is lazyblorg in active development? What are the future plans?

This section was updated on 2014-03-14:

Currently: yes (heavy) :-)

My general plan:

  • Add features to lazyblorg as long as I feel the urge to.
  • Be open to enhancements done by others on github.
  • If lazyblorg reaches a state, where I do not need anything additional, let’s keep it that way: development stopped because it reached sufficient perfection :-)

See also dev/lazyblorg.org for the issue tracking with all kind of information about the development (open issues, plans, documentation, …).

Already accomplished:

  • develop lazyblorg to be able to replace my current web page and its blog.
  • ATOM/RSS

Next:

  • tag-pages
  • Auto-tags
  • overview pages (monthly, yearly)
  • internal refactoring (object containing all constants, …)
  • lists
  • include image files

Is there any documentation about the internals of lazyblorg?

Yes, please do read dev/lazyblorg.org (especially section “notes”).

Lazyblorg uses what technology?

  • input files: Org-mode files of version 8.x
    • my personal Org-mode is from the Org-mode git repository; so I tend to stay up-to-date to get newest features and fixes
  • processing: Python 2.x
    • some dependencies on libraries, nothing fancy
    • I started with Python 2.x and never got the tension to test Python 3.x so far
  • output files: static HTML5, CSS3

Why didn’t you use HTML export/org-publish/Elisp/…?

Please do read my statement on GitHub.

Isn’t this quite slow?

As with 2014-09-21, the parser and htmlizer is performing pretty well in my opinion. When I re-generate my whole blog, I currently get this summary output:

Parsed 27 Org-mode files with 323327 lines (in 5.99 seconds)
Generated 61 articles: 8 persistent, 52 temporal, 0 tag, 1 entry page (in 0.30 seconds)

Can I use the Org-mode parser (in Python) for other purposes as well?

Yes, please do read dev/lazyblorg.org and lib/orgparser.py.

Although, you have to modify it a bit since I filter out headings that meet the criteria of being a blog article. You also have to know that I did not write a clean parser (separate lexical and syntactic analysis) for Org-mode. I used the naive line-by-line method in order to get the sub-set Org-mode syntax done quickly. There certainly is a downside of this method in terms of capability and probably also maintainability.

Please also note that this parser only implements a sub-set of Org-mode syntax (see section “notes” in dev/lazyblorg.org).

I do have a question but it is not listed here. Where to ask?

Just drop me a line: lazyblorg <at-sign> Karl <minus-sign> Voit <dot> at

Installing and Starting with lazyblorg

Currently, lazyblorg is in beta status. It’s not finished yet. However, I am using it for my own blog and therefore it gets more and more ready to use as I add new features.

What’s working so far:

  • parsing a very basic sub-set of Org-mode
  • parsing the HTML templates
  • generating HTML5 pages with a sub-set of the sub-set of the Org-mode syntax elements

Non-working things are either mentioned in dev/lazyblorg.org or marked with “FIXXME” in the source code files.

External dependencies

The number of external dependencies is kept at a minimum.

This is a list of the most important dependencies:

  • Werkzeug
    • for sanitizing path components
    • I installed it on Debian GNU/Linux with apt-get install python-werkzeug
  • pickle
    • object serialization
    • most likely: should be part of your Python distribution
  • pypandoc
    • some Org-mode syntax elements are being converted using Pandoc and its Python binding pypandoc
    • you can get it via sudo apt-get install pandoc and sudo pip install pypandoc
    • Note: Debian GNU/Linux 8 (Jessie) comes with a Pandoc version which is has bugs. Please install a more recent version which also required some minor changes. I upgraded to pandoc-1.15.1-1-amd64.deb from: http://pandoc.org/installing.html
  • Sass (optional) if you want to generate your CSS from the scss-file

All other libraries should be part of a standard Python distribution.

How to Start

  1. Get the source
  2. do a technological test-drive
    • start: lazyblorg/example_invocation.sh
    • this should work with GNU/Linux (and most probably OS X)
    • if not, there is something wrong with the set-up; maybe missing external libraries, wrong paths, …
  3. study, understand, and adopt the content of example_invocation.sh
    • with this, you are able to modify command line parameters to meet your requirements
    • if unsure, ask for help using lazyblorg.py --help
  4. get yourself an overview on what defines a lazyblorg blog post and write your own blog posts
    1. A (direct) tag has to be blog
      • Sorry, no tag inheritance. Every blog entry has to be explicitely tagged.
    2. You have to add an unique :ID: property
    3. The entry has to be marked with DONE
    4. A :LOGBOOK: entry has to be found with the time-stamp of setting the entry to DONE
      • in my set-up, this is created automatically
    5. Do not use Org-mode elements that lazyblorg does not understand
      • you should not get a disaster if you are using new elements. The result might disappoint you, that’s all.
  5. OPTIONAL: write your own CSS file
  6. OPTIONAL: adopt the blog template
  7. publish your pages on a web space of your choice
    • publishing can be done in various ways. This is how I do it using lazyblorg/make_and_publish_public_voit.sh which is an adopted version of lazyblorg/example_invocation.sh:
      1. executing testall.sh
        • this is for checking whether or not recent code changes did something harmful to my (unfortunately very limited) set of unit tests
      2. executing lazyblorg with my more or less fixed set of command line parameters
      3. executing rsync -av testdata/2del/blog/* $HOME/public_html/
        • it synchronizes the newly generated blog data to the local copy of my web space data
        • this separation makes sense to me because with this, I am able to do test drives without overwriting my (local copy of my) blog
      4. executing unison
        • in order to transfer my local copy of my web space data to my public web space
    • This method has the advantage that generating (executing lazyblorg) and publishing (executing unison) are separate steps. This way, I can locally re-generate the blog (for testing purposes) as often I want to. However, as long as I do not sync it to my web space, I keep the meta-data (which is in the local web space copy) of the published version (and not the meta-data of the previous test-run).
  8. have fun with a pretty neat method to generate your blog pages

Because we are already close friends now, I tell you a hidden feature of lazyblorg nobody knows yet: whenever you see a π-symbol in the upper right corner of a blog entry on my blog: this is a link to the original Org-mode source of that page. This way, you can compare Org-mode-source and HTML-result right away. Isn’t that cool? :-)

Five categories of page type

There are five different types of pages in lazyblorg. Most of the time, you are going to produce temporal pages. However, it is important to understand the other ones as well.

In order to process a blog-heading to its HTML5 representation, its Org-mode file has to be included in the --orgfiles command line argument of lazyblorg.py. Do not forget to include the archive files as well.

  1. temporal
  2. persistent
  3. tags
  4. entry page
  5. templates

temporal

These pages are associated with a certain (first) publishing date. The date of the most recent update is derived from the most recent time-stamp when you are marking the heading as DONE

URLs end up like http://example.com/2014/03/30/this-is-the-ID/ where “this-is-the-ID” is derived from the ID-property. The date is taken from the oldest time-stamp when the heading was marked as DONE. If the ID starts with an ISO date, this date gets truncated: “2014-03-30-this-is-the-ID” gets “this-is-the-ID”

  • reason: you can use general terms like “sports” without worrying that another heading has “sports” as ID as well (“2014-03-30-sports” is pretty unique in contrast to “sports”).
  • hey, isn’t this nice or what?
  • criteria (as already mentioned above)
    1. ID set
    2. tag: blog
    3. status is DONE

persistent

Pages that will be constantly updated to stay up-to-date are realized as persistent pages.

This type is very handy for, e.g., about-pages, colophon, constantly updated tutorials/howtos, and so forth.

URLs are like http://example.com/this-is-the-ID/:

  • if it starts with an ISO date: same truncation as with the temporal IDs
  • criteria
    1. ID set
    2. tag: blog
    3. tag: lb_persistent
    4. status is DONE

tags

NOT IMPLEMENTED YET!

Tag pages are a specialty of lazyblorg. Unlike other systems, lazyblorg embraces tags as very important classification meta-data. When I am using a tag, I associate a specific context with it. This specific context is highly subjective unless I explain it to you. Tag pages are my explanation, what I do mean by using a certain tag. In the future, tags of temporal pages are automatically linked to (existing) tag pages describing each tag.

Hence: tag pages are like persistent pages which describe a certain tag.

URLs are like http://example.com/tags/this-is-the-ID/

  • if it starts with an ISO date: same truncation as with the temporal IDs
  • criteria
    1. ID set
    2. tag: blog
    3. tag: lb_tags
    4. status is DONE

entry page

The main or entry page is handled in a special way. It is a persistent page whose content is generated using HTML snippets from the templates and enriched with links to the most recent updated pages. So far, there is not much Org-mode on the entry page. It is more or less a dash-board and a jumping page.

The URL is like http://example.com/

templates

There must be exactly one heading which meets the criteria of a templates heading (see below). Within this heading, separate HTML blocks define the HTML snippets that are used by lazyblorg to generate the HTML pages. Please take a look at lazyblorg/templates/blog-format.org]] to get an impression how this works.

You might want to start with my blog-format template and adopt it to your needs.

  • criteria
    1. ID set
    2. tag: blog
    3. tag: lb_templates
    4. status is DONE
    5. contains all necessary HTML blocks with pre-defined names

BONUS: Preview Blog Article

It is tedious to re-generate the whole blog and even upload it to your web-space just to check the HTML version of the article you are currently writing.

Yeah, this also sucks at my side.

Good news everybody: There is a simple method to preview the article under the cursor. The script preview_blogentry.sh contains an ELISP function that extracts the current blog article (all lazyblorg criteria has to be fulfilled: ID, blog tag, status DONE), stores it into a temporary file, and invokes lazyblorg via preview_blogentry.sh with this temporary file and the Org-mode file containing the format definitions.

If this worked out, your browser shows you all generated blog articles.

Please do adopt the mentioned scripts to you specific requirements - the ones from the repository are for my personal set-up which is unlikely to fit yours (directory paths mostly).

Bang! Another damn cool feature of lazyblorg. This is going better and better. :-)

BONUS: Jump From URL to Blog Article

Imagine, you’re looking at a blog article of your nice lazyblorg-generated blog. Now you want to go to the corresponding Org-mode source to fix a typo.

The issue here is, that you have to either know, where your heading is located or you have to go to the HTML page source, extract the ID, and jump to this ID.

I’ve got a better method: put the URL of your blog article into your clipboard (via C-l C-c), press a magic shortcut in Emacs, and BAAAM! you’re right on spot.

How’s that magic happening?

Just use the following Emacs lisp code snippet, adapt the domain string, and assign a keyboard shortcut:

(defun my-jump-to-lazyblorg-heading-according-to-URL-in-clipboard ()
  "Retrieves an URL from the clipboard, gets its Org-mode source,
   extracts the ID of the article and jumps to its Org-mode heading"
  (interactive)
  (let (
        ;; Getting URL from the clipboard. Since it may contain
        ;; some text properties we are using substring-no-properties
        ;; function
        (url (substring-no-properties (current-kill 0)))
        ;; This is a check string: if the URL in the clipboard
        ;; doesn't start with this, an error message is shown
        (domain "http://karl-voit.at")
  )
    ;; Check if URL string is from my domain (all other strings do
    ;; not make any sense here)
    (if (string-prefix-p (upcase domain) (upcase url))
    ;; Retrieving content by URL into new buffer asynchronously
    (url-retrieve url 
                      ;; call this lambda function when URL content is retrieved
          (lambda (status)
             ;; Extrating and preparing the ID
             (let* (
                                ;; Limit the ID search to the top 1000 characters of the buffer
                (pageheader (buffer-substring 1 1000))
                ;; Start index of the id
                                (start (string-match "<meta name=\"orgmode-id\" content=\"" pageheader))
                                ;; End index of the id
                                (end (string-match "\" />" pageheader start))
                                ;; Amount of characters to skip for the openning tag
                                (chars-to-skip (length "<meta name=\"orgmode-id\" content=\""))
                                ;; Extract ID
                                (lazyblorg-id (if (and start end (< start end))
                                                  ;; ... extract it and return.
                                                  (substring pageheader (+ start chars-to-skip) end)
                                                nil))
                                )
               (message (concat "Looking for id:" lazyblorg-id " ..."))
               (org-open-link-from-string (concat "id:" lazyblorg-id))
               )
             )
          )
  (message (concat "Sorry: the URL \"" (substring url 0 (length domain)) "...\" doesn't start with \"" domain "\". Aborting."))
  )
    )
  )

Contribute!

I am looking for your ideas:

If you want to contribute to this cool project, please fork and contribute!

Issues, bugs, user-stories, … are maintained in dev/lazyblorg.org

I am using Python PEP8 and some ideas from Test Driven Development (TDD).

Local Variables

lazyblorg's People

Contributors

novoid avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.