First step to kramdown => HTML + LaTeX Book with macros
This commit is contained in:
parent
314bad7936
commit
0c0d20c998
11 changed files with 280 additions and 19 deletions
103
Rakefile
103
Rakefile
|
@ -59,6 +59,109 @@ task :to_html do
|
|||
x.run
|
||||
end
|
||||
|
||||
task :khtml do
|
||||
require 'rubygems'
|
||||
require 'kramdown'
|
||||
require 'filters/markdown_macros'
|
||||
require 'filters/mkd_post_latex_macros_to_html'
|
||||
|
||||
class KrambookCompile
|
||||
require 'config_html.rb'
|
||||
|
||||
attr_accessor :filelist
|
||||
|
||||
# take a string from kramdown
|
||||
# returns LaTeX after filter
|
||||
def compile_text(tmp)
|
||||
@prefilters.each do |f|
|
||||
tmp=f.run( tmp )
|
||||
end
|
||||
|
||||
# compile to latex
|
||||
tmp=Kramdown::Document.new(tmp, :latex_headers => %w(chapter section subsection paragraph subparagraph subsubparagraph)).to_html
|
||||
|
||||
# post filters
|
||||
@postfilters.each{ |f| tmp=f.run(tmp) }
|
||||
return tmp
|
||||
end
|
||||
|
||||
def process_template
|
||||
puts "PROCESS: "+@template_file
|
||||
txt=File.read(@template_file)
|
||||
|
||||
# puts "READ: " + txt
|
||||
txt.sub!( /<!-- INCLUDES -->/ ) do
|
||||
puts "HERE"
|
||||
@filelist.map do |source,dest|
|
||||
%{<div class="block left">
|
||||
<h3>
|
||||
<a href="#{dest.sub(/^tmp\//,'')}">
|
||||
#{File::basename(dest,'.html')}
|
||||
<span class="nicer">»</span>
|
||||
</a>
|
||||
</h3>
|
||||
</div>}
|
||||
end.join("\n") + '</ul>'
|
||||
end
|
||||
# puts "AFTER INCLUDES: " + txt
|
||||
txt.gsub!(%r{<!-- Author -->},@author)
|
||||
# puts "AFTER AUTHOR: " + txt
|
||||
txt.gsub!(%r{<!-- Title -->},@title)
|
||||
txt.gsub!(%r{<!-- Subtitle -->},@subtitle)
|
||||
# puts "AFTER TITLE: " + txt
|
||||
txt.sub!( %r{<!-- HTML HEADER -->},@html_headers)
|
||||
# puts "AFTER HTML HEADER: " + txt
|
||||
fic=File.new("tmp/#{@pdfname}.html","w")
|
||||
fic.write(txt)
|
||||
fic.close
|
||||
end
|
||||
|
||||
def initialize
|
||||
|
||||
eval File.new('config_html.rb','r').read
|
||||
|
||||
@prefilters=[]
|
||||
@prefilters<<=MarkdownMacros.new
|
||||
|
||||
@postfilters=[]
|
||||
@postfilters<<=MarkdownPostLatexMacrosToHTML.new
|
||||
|
||||
@filelist=Dir.glob("content/**/*.md").sort.map do |fic|
|
||||
[ fic, fic.sub(/^content\//,"tmp/").sub(/.md$/,".html") ]
|
||||
end
|
||||
end
|
||||
|
||||
def run
|
||||
@filelist.each do |doublon|
|
||||
source=doublon[0]
|
||||
dest=doublon[1]
|
||||
puts source
|
||||
|
||||
# read and compile in LaTeX the .md file
|
||||
text=compile_text( File.new(source,"r").read )
|
||||
|
||||
# create directory if necessary
|
||||
if not FileTest::directory?(File.dirname(dest))
|
||||
FileUtils.mkdir_p(File.dirname(dest))
|
||||
end
|
||||
|
||||
# write the .tex file
|
||||
fic = File.new(dest,"w")
|
||||
fic.write(text)
|
||||
fic.close
|
||||
|
||||
end
|
||||
|
||||
# write the .tex file containing all includes
|
||||
process_template
|
||||
|
||||
system("cp -rf include tmp/")
|
||||
# system("open tmp/#{@pdfname}.html")
|
||||
end
|
||||
end
|
||||
KrambookCompile.new.run
|
||||
end
|
||||
|
||||
task :compile do
|
||||
require 'rubygems'
|
||||
require 'kramdown'
|
||||
|
|
19
config_html.rb
Normal file
19
config_html.rb
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Use this file to configure some general variables
|
||||
|
||||
@title=%{Krambook}
|
||||
@subtitle=%{<span class="small">Write Books like an
|
||||
<code>UB3R 1337</code> <em>(Hacker)</em></span>}
|
||||
|
||||
@author="Yann Esposito"
|
||||
|
||||
# file name
|
||||
@pdfname="krambook"
|
||||
|
||||
# LaTeX headers (before \begin{document})
|
||||
@html_headers=''
|
||||
|
||||
# change the template file in case latex_headers is not enough
|
||||
# Remember to not remove lines begining by %%#
|
||||
# look at include/template.tex for example
|
||||
@template_file="include/template.html"
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
%%% markdown %%% `markdown` %%%
|
||||
%%% kramdown %%% [`kramdown`](http://kramdown.rubyforge.org) %%%
|
||||
LLL xelatex LLL \XeLaTeX LLL
|
||||
LLL xelatex_ LLL \XeLaTeX{} LLL
|
||||
LLL latex LLL \LaTeX LLL
|
||||
LLL latex_ LLL \LaTeX{} LLL
|
||||
LLL tex LLL \TeX LLL
|
||||
LLL tex_ LLL \TeX{} LLL
|
||||
LLL xelatex LLL \XeLaTeX LLL XeLaTeX HTML
|
||||
LLL xelatex_ LLL \XeLaTeX{} LLL XeLaTeX HTML
|
||||
LLL latex LLL \LaTeX LLL LaTeX HTML
|
||||
LLL latex_ LLL \LaTeX{} LLL LaTeX HTML
|
||||
LLL tex LLL \TeX LLL TeX HTML
|
||||
LLL tex_ LLL \TeX{} LLL TeX HTML
|
||||
|
||||
# Write Books like a Hacker
|
||||
|
||||
|
@ -56,8 +56,8 @@ To prove my point, simply compare a %latex_ and a %markdown file.
|
|||
|
||||
Both file will be generated as:
|
||||
|
||||
LLL beginbox LLL \medskip\fbox{\colorbox{boxcolor}{\begin{minipage}{.80\linewidth}% LLL
|
||||
LLL endbox LLL \end{minipage}}}\medskip LLL
|
||||
LLL beginbox LLL \medskip\fbox{\colorbox{boxcolor}{\begin{minipage}{.80\linewidth}% LLL <div class="box"> HTML
|
||||
LLL endbox LLL \end{minipage}}}\medskip LLL </div> HTML
|
||||
|
||||
%beginbox
|
||||
|
||||
|
@ -154,9 +154,9 @@ Remark:
|
|||
These transformations will occur on the markdown file before it is transformed in LaTeX.
|
||||
|
||||
You can also declare macro that will be processed after the file was transformed in LaTeX.
|
||||
|
||||
LLL latex LLL \LaTeX LLL
|
||||
LLL latex_ LLL \LaTeX{} LLL
|
||||
|
||||
LLL latex LLL \LaTeX LLL LaTeX HTML
|
||||
LLL latex_ LLL \LaTeX{} LLL LaTeX HTML
|
||||
|
||||
In markdown, you simply write \%macroname or \%code
|
||||
and it will be transformed correctly in your pdf.
|
||||
|
|
|
@ -7,8 +7,8 @@ macro %%%
|
|||
%%% complex %%% ruby: (1..5).map do |x|
|
||||
x*x
|
||||
end.join(" : ") %%%
|
||||
LLL latex LLL \LaTeX LLL
|
||||
LLL tldr LLL {\em Too long don't read: } LLL
|
||||
LLL latex LLL \LaTeX LLL LaTeX HTML
|
||||
LLL tldr LLL {\em Too long don't read: } LLL <em>Too long don't read: </em> HTML
|
||||
|
||||
It is a simple demonstration of how macros are working.
|
||||
They were declared inside the markdown like this:
|
||||
|
@ -21,8 +21,8 @@ They were declared inside the markdown like this:
|
|||
%%% complex %%% ruby: (1..5).map do |x|
|
||||
x*x
|
||||
end.join(" : ") %%%
|
||||
LLL latex LLL \LaTeX LLL
|
||||
LLL tldr LLL {\em Too long don't read: } LLL
|
||||
LLL latex LLL \LaTeX LLL LaTeX HTML
|
||||
LLL tldr LLL {\em Too long don't read: } LLL <em>Too long don't read: </em> HTML
|
||||
~~~
|
||||
|
||||
Now if I write:
|
||||
|
|
|
@ -33,10 +33,10 @@ class MarkdownPostLatexMacros
|
|||
end
|
||||
|
||||
def run (content)
|
||||
content.gsub(/^LLL (\w(\w|\d|\\_)*) LLL ((.|\n)*?) LLL/m) do |m|
|
||||
content.gsub(/^LLL (\w(\w|\d|\\_)*) LLL ((.|\n)*?) LLL( (.|\n)*? HTML)?/m) do |m|
|
||||
name=$1
|
||||
value=$3
|
||||
# puts %{ ltx macro %#{name}\t=> #{value}}
|
||||
# puts %{ ADD LATEX MACRO: %#{name}\t=> #{value}}
|
||||
name.gsub!(/\\_/,'_')
|
||||
value=value.gsub(/\\textbackslash\{\}/,'\\').
|
||||
gsub(/\\textbar\{\}/,'|').
|
||||
|
|
57
filters/mkd_post_latex_macros_to_html.rb
Normal file
57
filters/mkd_post_latex_macros_to_html.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Add macros to Markdown
|
||||
#
|
||||
# Here is a %test.
|
||||
#
|
||||
# you could add a macro like this
|
||||
#
|
||||
# filter.macro={
|
||||
# :latex => %{\LaTeX}
|
||||
# }
|
||||
#
|
||||
# or within the markdown file by
|
||||
#
|
||||
# %%% macro_name %%% macro_value %%%
|
||||
#
|
||||
|
||||
class MarkdownPostLatexMacrosToHTML
|
||||
attr_accessor :macro
|
||||
def initialize()
|
||||
super
|
||||
@macro={}
|
||||
end
|
||||
|
||||
def macro_value_for(ident)
|
||||
return '%' if ident.nil? or ident==""
|
||||
ident=ident.intern
|
||||
return %{%#{ident}} if @macro[ident].nil?
|
||||
|
||||
if @macro[ident] =~ /ruby: ((.|n)*)/m
|
||||
return eval $1
|
||||
else
|
||||
return @macro[ident]
|
||||
end
|
||||
end
|
||||
|
||||
def run (content)
|
||||
content.gsub(/(^<p>\s*)?LLL (\w(\w|\d|\\_)*) LLL ((.|\n)*?) LLL( ((.|\n)*?) HTML)?((\s|\n)*<\/p>)?/m) do |m|
|
||||
name=$2
|
||||
value=$7
|
||||
puts "SAVE HTML MACRO: #{name} => #{value}"
|
||||
@macro[name.intern]=value
|
||||
""
|
||||
end.gsub(/(\\?)%(\w[a-zA-Z0-9_]*)/) do |m|
|
||||
# puts " ltx macro MATCH: #{$3}"
|
||||
protected=$1
|
||||
name=$2
|
||||
if name != ""
|
||||
if protected == ""
|
||||
macro_value_for(name)
|
||||
else
|
||||
%{<code>%#{name}</code>}
|
||||
end
|
||||
else
|
||||
m
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -36,10 +36,14 @@
|
|||
<script>
|
||||
var page=1;
|
||||
google.setOnLoadCallback( function() {
|
||||
|
||||
$('#first').click( function() { changeTo(1); });
|
||||
$('#previous').click( function() { changeTo(page-1); });
|
||||
$('#previous').addClass('disable');
|
||||
$('#next').click( function() { changeTo(page+1); });
|
||||
|
||||
$('#previous').addClass('disable');
|
||||
$('#first').addClass('disable');
|
||||
|
||||
$('#nbpages').text("Page 1 / "+nb_pages);
|
||||
});
|
||||
</script>
|
||||
|
|
1
include/main.css
Normal file
1
include/main.css
Normal file
File diff suppressed because one or more lines are too long
26
include/template.html
Normal file
26
include/template.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="fr" xml:lang="fr">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<link rel="stylesheet" type="text/css" href="include/main.css" />
|
||||
|
||||
<!-- HTML HEADER -->
|
||||
<title><!-- Title --> by <!-- Author --></title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">
|
||||
<h1 style="font-size: 5em; font-weight: normal;"> <!-- Title --> </h1>
|
||||
<div id="titre">
|
||||
<h2> <!-- Subtitle --> </h2>
|
||||
<h3><em>by</em> <!-- Author --> </h3>
|
||||
</div>
|
||||
<div id="afterhead" style="padding-top: 2em; font-size: 1.3em;">
|
||||
<!-- INCLUDES -->
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -23,10 +23,18 @@
|
|||
\newcommand{\styleprintchapternum}{\textcolor{hrulecolor}{\Huge\thechapter\hspace{.5em}}}
|
||||
\renewcommand*{\printchaptertitle}[1]{\medskip\begin{center}\styleprintchapternum \hfill\begin{minipage}{.9\linewidth}\begin {center}\Huge##1\end{center}\end{minipage}\end{center}\medskip}
|
||||
}
|
||||
% --
|
||||
|
||||
\chapterstyle{combined}
|
||||
% -- END CHAPTER STYLE --
|
||||
|
||||
% -- Hyperref setup --
|
||||
\definecolor{linkcolor}{rgb}{0.4,0.0,0.0}
|
||||
\hypersetup{
|
||||
colorlinks=true, %
|
||||
urlcolor=linkcolor, %
|
||||
pdfcreator=author, %
|
||||
}
|
||||
% --
|
||||
|
||||
\author{}
|
||||
|
||||
|
|
43
include/ystyle.css
Normal file
43
include/ystyle.css
Normal file
|
@ -0,0 +1,43 @@
|
|||
/* Author: Yann Esposito
|
||||
* Website: yannesposito.com
|
||||
* Krambook url: http://github.com/yogsototh/krambook.git
|
||||
* */
|
||||
|
||||
#leftcolumn {float: left; width: 7em}
|
||||
#rightcolumn {float: right; width: 7em}
|
||||
.button {
|
||||
text-shadow: 0 1px 0 #eee;
|
||||
border: 1px solid #666;
|
||||
width: 7em;
|
||||
height: 3em;
|
||||
background: #ccc;
|
||||
color: #333;
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
line-height: 3em; }
|
||||
|
||||
.disable {
|
||||
cursor: default;
|
||||
opacity: .3 }
|
||||
|
||||
#nbpages{
|
||||
border: 1px solid #666;
|
||||
width: 7em;
|
||||
height: 3em;
|
||||
line-height: 3em;
|
||||
background: #eee;
|
||||
text-align: center; }
|
||||
|
||||
#content {margin-left: auto; margin-right: auto; text-align: center}
|
||||
#frame {
|
||||
text-align: center; margin-left: auto; margin-right: auto;
|
||||
width: 492pt; height: 672pt; border: 1px solid #ccc}
|
||||
#who { position: fixed; bottom: 2px; right: 2px; text-align: right; font-size: .7em; }
|
||||
a { color: #888; text-decoration: none; border: none; }
|
||||
a:hover { color: #dc3; }
|
Loading…
Reference in a new issue